Merge
This commit is contained in:
commit
3fd8e0b4d2
@ -369,3 +369,4 @@ cae471d3b87783e0a3deea658e1e1c84b2485b6c jdk-9+121
|
|||||||
f80c841ae2545eaf9acd2724bccc305d98cefbe2 jdk-9+124
|
f80c841ae2545eaf9acd2724bccc305d98cefbe2 jdk-9+124
|
||||||
9aa7d40f3a453f51e47f4c1b19eff5740a74a9f8 jdk-9+125
|
9aa7d40f3a453f51e47f4c1b19eff5740a74a9f8 jdk-9+125
|
||||||
3a58466296d36944454756ef01e7513ac5e14a16 jdk-9+126
|
3a58466296d36944454756ef01e7513ac5e14a16 jdk-9+126
|
||||||
|
8fa686245bd2a072ece3392743460030f0854520 jdk-9+127
|
||||||
|
@ -369,3 +369,4 @@ e33a34cc551907617d8129c4faaf1a5a7e61d21c jdk-9+123
|
|||||||
45121d5afb9d5bfadab75378572ad96832e0809e jdk-9+124
|
45121d5afb9d5bfadab75378572ad96832e0809e jdk-9+124
|
||||||
1d48e67d1b91eb9f72e49e69a4021edb85e357fc jdk-9+125
|
1d48e67d1b91eb9f72e49e69a4021edb85e357fc jdk-9+125
|
||||||
c7f5ba08fcd4b8416e62c21229f9a07c95498919 jdk-9+126
|
c7f5ba08fcd4b8416e62c21229f9a07c95498919 jdk-9+126
|
||||||
|
8fab452b6f4710762ba1d8e55fd62db00b1355fe jdk-9+127
|
||||||
|
@ -529,3 +529,4 @@ af6b4ad908e732d23021f12e8322b204433d5cf6 jdk-9+122
|
|||||||
479631362b4930be985245ea063d87d821a472eb jdk-9+124
|
479631362b4930be985245ea063d87d821a472eb jdk-9+124
|
||||||
bb640b49741af3f57f9994129934c46fc173219f jdk-9+125
|
bb640b49741af3f57f9994129934c46fc173219f jdk-9+125
|
||||||
adc8c84b7cf8c540d920182f78a2bc982366432a jdk-9+126
|
adc8c84b7cf8c540d920182f78a2bc982366432a jdk-9+126
|
||||||
|
352357128f602dcf0426b1cbe011a4685a4d9f97 jdk-9+127
|
||||||
|
@ -45,7 +45,8 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
|||||||
$(DTRACE_GENSRC_DIR)/%.h: $(DTRACE_SOURCE_DIR)/%.d
|
$(DTRACE_GENSRC_DIR)/%.h: $(DTRACE_SOURCE_DIR)/%.d
|
||||||
$(call LogInfo, Generating dtrace header file $(@F))
|
$(call LogInfo, Generating dtrace header file $(@F))
|
||||||
$(call MakeDir, $(@D) $(DTRACE_SUPPORT_DIR))
|
$(call MakeDir, $(@D) $(DTRACE_SUPPORT_DIR))
|
||||||
$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d)
|
$(call ExecuteWithLog, $(DTRACE_SUPPORT_DIR)/$(@F).d, \
|
||||||
|
( $(CC) -E $(DTRACE_CPP_FLAGS) $< > $(DTRACE_SUPPORT_DIR)/$(@F).d ) )
|
||||||
$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -h -o $@ -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
|
$(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -h -o $@ -s $(DTRACE_SUPPORT_DIR)/$(@F).d)
|
||||||
|
|
||||||
# Process all .d files in DTRACE_SOURCE_DIR. They are:
|
# Process all .d files in DTRACE_SOURCE_DIR. They are:
|
||||||
|
@ -68,7 +68,7 @@ ifeq ($(call check-jvm-feature, dtrace), true)
|
|||||||
$1: $$(BUILD_DTRACE_GEN_OFFSETS)
|
$1: $$(BUILD_DTRACE_GEN_OFFSETS)
|
||||||
$$(call LogInfo, Generating dtrace $2 file $$(@F))
|
$$(call LogInfo, Generating dtrace $2 file $$(@F))
|
||||||
$$(call MakeDir, $$(@D))
|
$$(call MakeDir, $$(@D))
|
||||||
$$(call ExecuteWithLog, $$@, $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@)
|
$$(call ExecuteWithLog, $$@, ( $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $$@ ) )
|
||||||
|
|
||||||
TARGETS += $1
|
TARGETS += $1
|
||||||
endef
|
endef
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
*
|
*
|
||||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* have any questions.
|
* questions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
package com.sun.hotspot.tools.compiler;
|
package com.sun.hotspot.tools.compiler;
|
||||||
|
@ -501,13 +501,26 @@ ClassLoaderData::~ClassLoaderData() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Returns true if this class loader data is for the system class loader.
|
||||||
* Returns true if this class loader data is for the platform class loader.
|
bool ClassLoaderData::is_system_class_loader_data() const {
|
||||||
*/
|
return SystemDictionary::is_system_class_loader(class_loader());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if this class loader data is for the platform class loader.
|
||||||
bool ClassLoaderData::is_platform_class_loader_data() const {
|
bool ClassLoaderData::is_platform_class_loader_data() const {
|
||||||
return SystemDictionary::is_platform_class_loader(class_loader());
|
return SystemDictionary::is_platform_class_loader(class_loader());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if this class loader data is one of the 3 builtin
|
||||||
|
// (boot, application/system or platform) class loaders. Note, the
|
||||||
|
// builtin loaders are not freed by a GC.
|
||||||
|
bool ClassLoaderData::is_builtin_class_loader_data() const {
|
||||||
|
Handle classLoaderHandle = class_loader();
|
||||||
|
return (is_the_null_class_loader_data() ||
|
||||||
|
SystemDictionary::is_system_class_loader(classLoaderHandle) ||
|
||||||
|
SystemDictionary::is_platform_class_loader(classLoaderHandle));
|
||||||
|
}
|
||||||
|
|
||||||
Metaspace* ClassLoaderData::metaspace_non_null() {
|
Metaspace* ClassLoaderData::metaspace_non_null() {
|
||||||
assert(!DumpSharedSpaces, "wrong metaspace!");
|
assert(!DumpSharedSpaces, "wrong metaspace!");
|
||||||
// If the metaspace has not been allocated, create a new one. Might want
|
// If the metaspace has not been allocated, create a new one. Might want
|
||||||
@ -957,12 +970,6 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure,
|
|||||||
data = _head;
|
data = _head;
|
||||||
while (data != NULL) {
|
while (data != NULL) {
|
||||||
if (data->is_alive(is_alive_closure)) {
|
if (data->is_alive(is_alive_closure)) {
|
||||||
if (data->packages_defined()) {
|
|
||||||
data->packages()->purge_all_package_exports();
|
|
||||||
}
|
|
||||||
if (data->modules_defined()) {
|
|
||||||
data->modules()->purge_all_module_reads();
|
|
||||||
}
|
|
||||||
// clean metaspace
|
// clean metaspace
|
||||||
if (walk_all_metadata) {
|
if (walk_all_metadata) {
|
||||||
data->classes_do(InstanceKlass::purge_previous_versions);
|
data->classes_do(InstanceKlass::purge_previous_versions);
|
||||||
@ -990,6 +997,23 @@ bool ClassLoaderDataGraph::do_unloading(BoolObjectClosure* is_alive_closure,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (seen_dead_loader) {
|
if (seen_dead_loader) {
|
||||||
|
// Walk a ModuleEntry's reads and a PackageEntry's exports lists
|
||||||
|
// to determine if there are modules on those lists that are now
|
||||||
|
// dead and should be removed. A module's life cycle is equivalent
|
||||||
|
// to its defining class loader's life cycle. Since a module is
|
||||||
|
// considered dead if its class loader is dead, these walks must
|
||||||
|
// occur after each class loader's aliveness is determined.
|
||||||
|
data = _head;
|
||||||
|
while (data != NULL) {
|
||||||
|
if (data->packages_defined()) {
|
||||||
|
data->packages()->purge_all_package_exports();
|
||||||
|
}
|
||||||
|
if (data->modules_defined()) {
|
||||||
|
data->modules()->purge_all_module_reads();
|
||||||
|
}
|
||||||
|
data = data->next();
|
||||||
|
}
|
||||||
|
|
||||||
post_class_unload_events();
|
post_class_unload_events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,9 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
|||||||
bool is_the_null_class_loader_data() const {
|
bool is_the_null_class_loader_data() const {
|
||||||
return this == _the_null_class_loader_data;
|
return this == _the_null_class_loader_data;
|
||||||
}
|
}
|
||||||
|
bool is_system_class_loader_data() const;
|
||||||
bool is_platform_class_loader_data() const;
|
bool is_platform_class_loader_data() const;
|
||||||
|
bool is_builtin_class_loader_data() const;
|
||||||
|
|
||||||
// The Metaspace is created lazily so may be NULL. This
|
// The Metaspace is created lazily so may be NULL. This
|
||||||
// method will allocate a Metaspace if needed.
|
// method will allocate a Metaspace if needed.
|
||||||
|
@ -248,7 +248,7 @@ inline void SimpleCompactHashtable::iterate(const I& iterator) {
|
|||||||
} else {
|
} else {
|
||||||
u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
|
u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
|
||||||
while (entry < entry_max) {
|
while (entry < entry_max) {
|
||||||
iterator.do_value(_base_address, entry[0]);
|
iterator.do_value(_base_address, entry[1]);
|
||||||
entry += 2;
|
entry += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
|
|
||||||
ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
|
ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
|
||||||
|
|
||||||
|
|
||||||
void ModuleEntry::set_location(Symbol* location) {
|
void ModuleEntry::set_location(Symbol* location) {
|
||||||
if (_location != NULL) {
|
if (_location != NULL) {
|
||||||
// _location symbol's refcounts are managed by ModuleEntry,
|
// _location symbol's refcounts are managed by ModuleEntry,
|
||||||
@ -115,10 +114,35 @@ void ModuleEntry::add_read(ModuleEntry* m) {
|
|||||||
// Lazily create a module's reads list
|
// Lazily create a module's reads list
|
||||||
_reads = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(MODULE_READS_SIZE, true);
|
_reads = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(MODULE_READS_SIZE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine, based on this newly established read edge to module m,
|
||||||
|
// if this module's read list should be walked at a GC safepoint.
|
||||||
|
set_read_walk_required(m->loader_data());
|
||||||
|
|
||||||
|
// Establish readability to module m
|
||||||
_reads->append_if_missing(m);
|
_reads->append_if_missing(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the module's loader, that a read edge is being established to, is
|
||||||
|
// not the same loader as this module's and is not one of the 3 builtin
|
||||||
|
// class loaders, then this module's reads list must be walked at GC
|
||||||
|
// safepoint. Modules have the same life cycle as their defining class
|
||||||
|
// loaders and should be removed if dead.
|
||||||
|
void ModuleEntry::set_read_walk_required(ClassLoaderData* m_loader_data) {
|
||||||
|
assert_locked_or_safepoint(Module_lock);
|
||||||
|
if (!_must_walk_reads &&
|
||||||
|
loader_data() != m_loader_data &&
|
||||||
|
!m_loader_data->is_builtin_class_loader_data()) {
|
||||||
|
_must_walk_reads = true;
|
||||||
|
if (log_is_enabled(Trace, modules)) {
|
||||||
|
ResourceMark rm;
|
||||||
|
log_trace(modules)("ModuleEntry::set_read_walk_required(): module %s reads list must be walked",
|
||||||
|
(name() != NULL) ? name()->as_C_string() : UNNAMED_MODULE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ModuleEntry::has_reads() const {
|
bool ModuleEntry::has_reads() const {
|
||||||
assert_locked_or_safepoint(Module_lock);
|
assert_locked_or_safepoint(Module_lock);
|
||||||
return ((_reads != NULL) && !_reads->is_empty());
|
return ((_reads != NULL) && !_reads->is_empty());
|
||||||
@ -127,14 +151,28 @@ bool ModuleEntry::has_reads() const {
|
|||||||
// Purge dead module entries out of reads list.
|
// Purge dead module entries out of reads list.
|
||||||
void ModuleEntry::purge_reads() {
|
void ModuleEntry::purge_reads() {
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
||||||
if (has_reads()) {
|
|
||||||
|
if (_must_walk_reads && has_reads()) {
|
||||||
|
// This module's _must_walk_reads flag will be reset based
|
||||||
|
// on the remaining live modules on the reads list.
|
||||||
|
_must_walk_reads = false;
|
||||||
|
|
||||||
|
if (log_is_enabled(Trace, modules)) {
|
||||||
|
ResourceMark rm;
|
||||||
|
log_trace(modules)("ModuleEntry::purge_reads(): module %s reads list being walked",
|
||||||
|
(name() != NULL) ? name()->as_C_string() : UNNAMED_MODULE);
|
||||||
|
}
|
||||||
|
|
||||||
// Go backwards because this removes entries that are dead.
|
// Go backwards because this removes entries that are dead.
|
||||||
int len = _reads->length();
|
int len = _reads->length();
|
||||||
for (int idx = len - 1; idx >= 0; idx--) {
|
for (int idx = len - 1; idx >= 0; idx--) {
|
||||||
ModuleEntry* module_idx = _reads->at(idx);
|
ModuleEntry* module_idx = _reads->at(idx);
|
||||||
ClassLoaderData* cld = module_idx->loader();
|
ClassLoaderData* cld_idx = module_idx->loader_data();
|
||||||
if (cld->is_unloading()) {
|
if (cld_idx->is_unloading()) {
|
||||||
_reads->delete_at(idx);
|
_reads->delete_at(idx);
|
||||||
|
} else {
|
||||||
|
// Update the need to walk this module's reads based on live modules
|
||||||
|
set_read_walk_required(cld_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,7 +286,7 @@ ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle
|
|||||||
entry->set_module(loader_data->add_handle(module_handle));
|
entry->set_module(loader_data->add_handle(module_handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->set_loader(loader_data);
|
entry->set_loader_data(loader_data);
|
||||||
entry->set_version(version);
|
entry->set_version(version);
|
||||||
entry->set_location(location);
|
entry->set_location(location);
|
||||||
|
|
||||||
@ -375,11 +413,11 @@ void ModuleEntryTable::print(outputStream* st) {
|
|||||||
|
|
||||||
void ModuleEntry::print(outputStream* st) {
|
void ModuleEntry::print(outputStream* st) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
st->print_cr("entry "PTR_FORMAT" name %s module "PTR_FORMAT" loader %s version %s location %s strict %s next "PTR_FORMAT,
|
st->print_cr("entry " PTR_FORMAT " name %s module " PTR_FORMAT " loader %s version %s location %s strict %s next " PTR_FORMAT,
|
||||||
p2i(this),
|
p2i(this),
|
||||||
name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
|
name() == NULL ? UNNAMED_MODULE : name()->as_C_string(),
|
||||||
p2i(module()),
|
p2i(module()),
|
||||||
loader()->loader_name(),
|
loader_data()->loader_name(),
|
||||||
version() != NULL ? version()->as_C_string() : "NULL",
|
version() != NULL ? version()->as_C_string() : "NULL",
|
||||||
location() != NULL ? location()->as_C_string() : "NULL",
|
location() != NULL ? location()->as_C_string() : "NULL",
|
||||||
BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
|
BOOL_TO_STR(!can_read_all_unnamed()), p2i(next()));
|
||||||
@ -401,5 +439,5 @@ void ModuleEntryTable::verify() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ModuleEntry::verify() {
|
void ModuleEntry::verify() {
|
||||||
guarantee(loader() != NULL, "A module entry must be associated with a loader.");
|
guarantee(loader_data() != NULL, "A module entry must be associated with a loader.");
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ class ModuleClosure;
|
|||||||
// It contains:
|
// It contains:
|
||||||
// - Symbol* containing the module's name.
|
// - Symbol* containing the module's name.
|
||||||
// - pointer to the java.lang.reflect.Module for this module.
|
// - pointer to the java.lang.reflect.Module for this module.
|
||||||
|
// - pointer to the java.security.ProtectionDomain shared by classes defined to this module.
|
||||||
// - ClassLoaderData*, class loader of this module.
|
// - ClassLoaderData*, class loader of this module.
|
||||||
// - a growable array containg other module entries that this module can read.
|
// - a growable array containg other module entries that this module can read.
|
||||||
// - a flag indicating if this module can read all unnamed modules.
|
// - a flag indicating if this module can read all unnamed modules.
|
||||||
@ -54,56 +55,58 @@ private:
|
|||||||
jobject _module; // java.lang.reflect.Module
|
jobject _module; // java.lang.reflect.Module
|
||||||
jobject _pd; // java.security.ProtectionDomain, cached
|
jobject _pd; // java.security.ProtectionDomain, cached
|
||||||
// for shared classes from this module
|
// for shared classes from this module
|
||||||
ClassLoaderData* _loader;
|
ClassLoaderData* _loader_data;
|
||||||
GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
|
GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
|
||||||
Symbol* _version; // module version number
|
Symbol* _version; // module version number
|
||||||
Symbol* _location; // module location
|
Symbol* _location; // module location
|
||||||
bool _can_read_all_unnamed;
|
bool _can_read_all_unnamed;
|
||||||
bool _has_default_read_edges; // JVMTI redefine/retransform support
|
bool _has_default_read_edges; // JVMTI redefine/retransform support
|
||||||
|
bool _must_walk_reads; // walk module's reads list at GC safepoints to purge out dead modules
|
||||||
TRACE_DEFINE_TRACE_ID_FIELD;
|
TRACE_DEFINE_TRACE_ID_FIELD;
|
||||||
enum {MODULE_READS_SIZE = 101}; // Initial size of list of modules that the module can read.
|
enum {MODULE_READS_SIZE = 101}; // Initial size of list of modules that the module can read.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void init() {
|
void init() {
|
||||||
_module = NULL;
|
_module = NULL;
|
||||||
_loader = NULL;
|
_loader_data = NULL;
|
||||||
_pd = NULL;
|
_pd = NULL;
|
||||||
_reads = NULL;
|
_reads = NULL;
|
||||||
_version = NULL;
|
_version = NULL;
|
||||||
_location = NULL;
|
_location = NULL;
|
||||||
_can_read_all_unnamed = false;
|
_can_read_all_unnamed = false;
|
||||||
_has_default_read_edges = false;
|
_has_default_read_edges = false;
|
||||||
|
_must_walk_reads = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol* name() const { return literal(); }
|
Symbol* name() const { return literal(); }
|
||||||
void set_name(Symbol* n) { set_literal(n); }
|
void set_name(Symbol* n) { set_literal(n); }
|
||||||
|
|
||||||
jobject module() const { return _module; }
|
jobject module() const { return _module; }
|
||||||
void set_module(jobject j) { _module = j; }
|
void set_module(jobject j) { _module = j; }
|
||||||
|
|
||||||
// The shared ProtectionDomain reference is set once the VM loads a shared class
|
// The shared ProtectionDomain reference is set once the VM loads a shared class
|
||||||
// originated from the current Module. The referenced ProtectionDomain object is
|
// originated from the current Module. The referenced ProtectionDomain object is
|
||||||
// created by the ClassLoader when loading a class (shared or non-shared) from the
|
// created by the ClassLoader when loading a class (shared or non-shared) from the
|
||||||
// Module for the first time. This ProtectionDomain object is used for all
|
// Module for the first time. This ProtectionDomain object is used for all
|
||||||
// classes from the Module loaded by the same ClassLoader.
|
// classes from the Module loaded by the same ClassLoader.
|
||||||
Handle shared_protection_domain();
|
Handle shared_protection_domain();
|
||||||
void set_shared_protection_domain(ClassLoaderData *loader_data,
|
void set_shared_protection_domain(ClassLoaderData *loader_data, Handle pd);
|
||||||
Handle pd);
|
|
||||||
|
|
||||||
ClassLoaderData* loader() const { return _loader; }
|
ClassLoaderData* loader_data() const { return _loader_data; }
|
||||||
void set_loader(ClassLoaderData* l) { _loader = l; }
|
void set_loader_data(ClassLoaderData* l) { _loader_data = l; }
|
||||||
|
|
||||||
Symbol* version() const { return _version; }
|
Symbol* version() const { return _version; }
|
||||||
void set_version(Symbol* version);
|
void set_version(Symbol* version);
|
||||||
|
|
||||||
Symbol* location() const { return _location; }
|
Symbol* location() const { return _location; }
|
||||||
void set_location(Symbol* location);
|
void set_location(Symbol* location);
|
||||||
|
|
||||||
bool can_read(ModuleEntry* m) const;
|
bool can_read(ModuleEntry* m) const;
|
||||||
bool has_reads() const;
|
bool has_reads() const;
|
||||||
void add_read(ModuleEntry* m);
|
void add_read(ModuleEntry* m);
|
||||||
|
void set_read_walk_required(ClassLoaderData* m_loader_data);
|
||||||
|
|
||||||
bool is_named() const { return (literal() != NULL); }
|
bool is_named() const { return (name() != NULL); }
|
||||||
|
|
||||||
bool can_read_all_unnamed() const {
|
bool can_read_all_unnamed() const {
|
||||||
assert(is_named() || _can_read_all_unnamed == true,
|
assert(is_named() || _can_read_all_unnamed == true,
|
||||||
@ -178,7 +181,7 @@ private:
|
|||||||
ModuleEntry* _unnamed_module;
|
ModuleEntry* _unnamed_module;
|
||||||
|
|
||||||
ModuleEntry* new_entry(unsigned int hash, Handle module_handle, Symbol* name, Symbol* version,
|
ModuleEntry* new_entry(unsigned int hash, Handle module_handle, Symbol* name, Symbol* version,
|
||||||
Symbol* location, ClassLoaderData* class_loader);
|
Symbol* location, ClassLoaderData* loader_data);
|
||||||
void add_entry(int index, ModuleEntry* new_entry);
|
void add_entry(int index, ModuleEntry* new_entry);
|
||||||
|
|
||||||
int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
|
int entry_size() const { return BasicHashtable<mtModule>::entry_size(); }
|
||||||
|
@ -113,7 +113,7 @@ static PackageEntry* get_package_entry(ModuleEntry* module_entry, jstring packag
|
|||||||
const char *package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
|
const char *package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
|
||||||
if (package_name == NULL) return NULL;
|
if (package_name == NULL) return NULL;
|
||||||
TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK_NULL);
|
TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK_NULL);
|
||||||
PackageEntryTable* package_entry_table = module_entry->loader()->packages();
|
PackageEntryTable* package_entry_table = module_entry->loader_data()->packages();
|
||||||
assert(package_entry_table != NULL, "Unexpected null package entry table");
|
assert(package_entry_table != NULL, "Unexpected null package entry table");
|
||||||
return package_entry_table->lookup_only(pkg_symbol);
|
return package_entry_table->lookup_only(pkg_symbol);
|
||||||
}
|
}
|
||||||
@ -868,7 +868,7 @@ void Modules::add_module_package(jobject module, jstring package, TRAPS) {
|
|||||||
package_name, module_entry->name()->as_C_string());
|
package_name, module_entry->name()->as_C_string());
|
||||||
|
|
||||||
TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
|
TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
|
||||||
PackageEntryTable* package_table = module_entry->loader()->packages();
|
PackageEntryTable* package_table = module_entry->loader_data()->packages();
|
||||||
assert(package_table != NULL, "Missing package_table");
|
assert(package_table != NULL, "Missing package_table");
|
||||||
|
|
||||||
bool pkg_exists = false;
|
bool pkg_exists = false;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "classfile/moduleEntry.hpp"
|
#include "classfile/moduleEntry.hpp"
|
||||||
#include "classfile/packageEntry.hpp"
|
#include "classfile/packageEntry.hpp"
|
||||||
|
#include "logging/log.hpp"
|
||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
#include "oops/symbol.hpp"
|
#include "oops/symbol.hpp"
|
||||||
#include "runtime/handles.inline.hpp"
|
#include "runtime/handles.inline.hpp"
|
||||||
@ -53,12 +54,40 @@ void PackageEntry::add_qexport(ModuleEntry* m) {
|
|||||||
if (!has_qual_exports_list()) {
|
if (!has_qual_exports_list()) {
|
||||||
// Lazily create a package's qualified exports list.
|
// Lazily create a package's qualified exports list.
|
||||||
// Initial size is small, do not anticipate export lists to be large.
|
// Initial size is small, do not anticipate export lists to be large.
|
||||||
_qualified_exports =
|
_qualified_exports = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true);
|
||||||
new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine, based on this newly established export to module m,
|
||||||
|
// if this package's export list should be walked at a GC safepoint.
|
||||||
|
set_export_walk_required(m->loader_data());
|
||||||
|
|
||||||
|
// Establish exportability to module m
|
||||||
_qualified_exports->append_if_missing(m);
|
_qualified_exports->append_if_missing(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the module's loader, that an export is being established to, is
|
||||||
|
// not the same loader as this module's and is not one of the 3 builtin
|
||||||
|
// class loaders, then this package's export list must be walked at GC
|
||||||
|
// safepoint. Modules have the same life cycle as their defining class
|
||||||
|
// loaders and should be removed if dead.
|
||||||
|
void PackageEntry::set_export_walk_required(ClassLoaderData* m_loader_data) {
|
||||||
|
assert_locked_or_safepoint(Module_lock);
|
||||||
|
ModuleEntry* this_pkg_mod = module();
|
||||||
|
if (!_must_walk_exports &&
|
||||||
|
(this_pkg_mod == NULL || this_pkg_mod->loader_data() != m_loader_data) &&
|
||||||
|
!m_loader_data->is_builtin_class_loader_data()) {
|
||||||
|
_must_walk_exports = true;
|
||||||
|
if (log_is_enabled(Trace, modules)) {
|
||||||
|
ResourceMark rm;
|
||||||
|
assert(name() != NULL, "PackageEntry without a valid name");
|
||||||
|
log_trace(modules)("PackageEntry::set_export_walk_required(): package %s defined in module %s, exports list must be walked",
|
||||||
|
name()->as_C_string(),
|
||||||
|
(this_pkg_mod == NULL || this_pkg_mod->name() == NULL) ?
|
||||||
|
UNNAMED_MODULE : this_pkg_mod->name()->as_C_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set the package's exported states based on the value of the ModuleEntry.
|
// Set the package's exported states based on the value of the ModuleEntry.
|
||||||
void PackageEntry::set_exported(ModuleEntry* m) {
|
void PackageEntry::set_exported(ModuleEntry* m) {
|
||||||
MutexLocker m1(Module_lock);
|
MutexLocker m1(Module_lock);
|
||||||
@ -96,14 +125,34 @@ void PackageEntry::set_is_exported_allUnnamed() {
|
|||||||
// Remove dead module entries within the package's exported list.
|
// Remove dead module entries within the package's exported list.
|
||||||
void PackageEntry::purge_qualified_exports() {
|
void PackageEntry::purge_qualified_exports() {
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
||||||
if (_qualified_exports != NULL) {
|
if (_must_walk_exports &&
|
||||||
|
_qualified_exports != NULL &&
|
||||||
|
!_qualified_exports->is_empty()) {
|
||||||
|
ModuleEntry* pkg_module = module();
|
||||||
|
|
||||||
|
// This package's _must_walk_exports flag will be reset based
|
||||||
|
// on the remaining live modules on the exports list.
|
||||||
|
_must_walk_exports = false;
|
||||||
|
|
||||||
|
if (log_is_enabled(Trace, modules)) {
|
||||||
|
ResourceMark rm;
|
||||||
|
assert(name() != NULL, "PackageEntry without a valid name");
|
||||||
|
ModuleEntry* pkg_mod = module();
|
||||||
|
log_trace(modules)("PackageEntry::purge_qualified_exports(): package %s defined in module %s, exports list being walked",
|
||||||
|
name()->as_C_string(),
|
||||||
|
(pkg_mod == NULL || pkg_mod->name() == NULL) ? UNNAMED_MODULE : pkg_mod->name()->as_C_string());
|
||||||
|
}
|
||||||
|
|
||||||
// Go backwards because this removes entries that are dead.
|
// Go backwards because this removes entries that are dead.
|
||||||
int len = _qualified_exports->length();
|
int len = _qualified_exports->length();
|
||||||
for (int idx = len - 1; idx >= 0; idx--) {
|
for (int idx = len - 1; idx >= 0; idx--) {
|
||||||
ModuleEntry* module_idx = _qualified_exports->at(idx);
|
ModuleEntry* module_idx = _qualified_exports->at(idx);
|
||||||
ClassLoaderData* cld = module_idx->loader();
|
ClassLoaderData* cld_idx = module_idx->loader_data();
|
||||||
if (cld->is_unloading()) {
|
if (cld_idx->is_unloading()) {
|
||||||
_qualified_exports->delete_at(idx);
|
_qualified_exports->delete_at(idx);
|
||||||
|
} else {
|
||||||
|
// Update the need to walk this package's exports based on live modules
|
||||||
|
set_export_walk_required(cld_idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,8 +346,8 @@ void PackageEntryTable::print(outputStream* st) {
|
|||||||
|
|
||||||
void PackageEntry::print(outputStream* st) {
|
void PackageEntry::print(outputStream* st) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
st->print_cr("package entry "PTR_FORMAT" name %s module %s classpath_index "
|
st->print_cr("package entry " PTR_FORMAT " name %s module %s classpath_index "
|
||||||
INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next "PTR_FORMAT,
|
INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next " PTR_FORMAT,
|
||||||
p2i(this), name()->as_C_string(),
|
p2i(this), name()->as_C_string(),
|
||||||
(module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
|
(module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
|
||||||
_classpath_index, _is_exported_unqualified, _is_exported_allUnnamed, p2i(next()));
|
_classpath_index, _is_exported_unqualified, _is_exported_allUnnamed, p2i(next()));
|
||||||
|
@ -69,6 +69,7 @@ private:
|
|||||||
s2 _classpath_index;
|
s2 _classpath_index;
|
||||||
bool _is_exported_unqualified;
|
bool _is_exported_unqualified;
|
||||||
bool _is_exported_allUnnamed;
|
bool _is_exported_allUnnamed;
|
||||||
|
bool _must_walk_exports;
|
||||||
GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
|
GrowableArray<ModuleEntry*>* _exported_pending_delete; // transitioned from qualified to unqualified, delete at safepoint
|
||||||
GrowableArray<ModuleEntry*>* _qualified_exports;
|
GrowableArray<ModuleEntry*>* _qualified_exports;
|
||||||
TRACE_DEFINE_TRACE_ID_FIELD;
|
TRACE_DEFINE_TRACE_ID_FIELD;
|
||||||
@ -82,6 +83,7 @@ public:
|
|||||||
_classpath_index = -1;
|
_classpath_index = -1;
|
||||||
_is_exported_unqualified = false;
|
_is_exported_unqualified = false;
|
||||||
_is_exported_allUnnamed = false;
|
_is_exported_allUnnamed = false;
|
||||||
|
_must_walk_exports = false;
|
||||||
_exported_pending_delete = NULL;
|
_exported_pending_delete = NULL;
|
||||||
_qualified_exports = NULL;
|
_qualified_exports = NULL;
|
||||||
}
|
}
|
||||||
@ -147,6 +149,7 @@ public:
|
|||||||
|
|
||||||
// add the module to the package's qualified exports
|
// add the module to the package's qualified exports
|
||||||
void add_qexport(ModuleEntry* m);
|
void add_qexport(ModuleEntry* m);
|
||||||
|
void set_export_walk_required(ClassLoaderData* m_loader_data);
|
||||||
|
|
||||||
PackageEntry* next() const {
|
PackageEntry* next() const {
|
||||||
return (PackageEntry*)HashtableEntry<Symbol*, mtModule>::next();
|
return (PackageEntry*)HashtableEntry<Symbol*, mtModule>::next();
|
||||||
|
@ -175,9 +175,18 @@ bool SystemDictionary::is_parallelDefine(Handle class_loader) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Returns true if the passed class loader is the builtin application class loader
|
||||||
* Returns true if the passed class loader is the platform class loader.
|
// or a custom system class loader. A customer system class loader can be
|
||||||
*/
|
// specified via -Djava.system.class.loader.
|
||||||
|
bool SystemDictionary::is_system_class_loader(Handle class_loader) {
|
||||||
|
if (class_loader.is_null()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (class_loader->klass() == SystemDictionary::jdk_internal_loader_ClassLoaders_AppClassLoader_klass() ||
|
||||||
|
class_loader() == _java_system_loader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if the passed class loader is the platform class loader.
|
||||||
bool SystemDictionary::is_platform_class_loader(Handle class_loader) {
|
bool SystemDictionary::is_platform_class_loader(Handle class_loader) {
|
||||||
if (class_loader.is_null()) {
|
if (class_loader.is_null()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -660,6 +660,7 @@ public:
|
|||||||
static instanceKlassHandle load_shared_class(Symbol* class_name,
|
static instanceKlassHandle load_shared_class(Symbol* class_name,
|
||||||
Handle class_loader,
|
Handle class_loader,
|
||||||
TRAPS);
|
TRAPS);
|
||||||
|
static bool is_system_class_loader(Handle class_loader);
|
||||||
static bool is_platform_class_loader(Handle class_loader);
|
static bool is_platform_class_loader(Handle class_loader);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -48,10 +48,10 @@ void PreservedMarks::restore_and_increment(volatile size_t* const total_size_add
|
|||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
void PreservedMarks::assert_empty() {
|
void PreservedMarks::assert_empty() {
|
||||||
assert(_stack.is_empty(), "stack expected to be empty, size = "SIZE_FORMAT,
|
assert(_stack.is_empty(), "stack expected to be empty, size = " SIZE_FORMAT,
|
||||||
_stack.size());
|
_stack.size());
|
||||||
assert(_stack.cache_size() == 0,
|
assert(_stack.cache_size() == 0,
|
||||||
"stack expected to have no cached segments, cache size = "SIZE_FORMAT,
|
"stack expected to have no cached segments, cache size = " SIZE_FORMAT,
|
||||||
_stack.cache_size());
|
_stack.cache_size());
|
||||||
}
|
}
|
||||||
#endif // ndef PRODUCT
|
#endif // ndef PRODUCT
|
||||||
|
@ -419,21 +419,20 @@ void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_err
|
|||||||
InstanceKlass* klass = method->method_holder();
|
InstanceKlass* klass = method->method_holder();
|
||||||
u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
|
u2 bc_index = Bytes::get_Java_u2(bcp + prefix_length + 1);
|
||||||
constantPoolHandle cp(method->constants());
|
constantPoolHandle cp(method->constants());
|
||||||
Symbol* field_name = cp->name_ref_at(bc_index);
|
|
||||||
Symbol* field_sig = cp->signature_ref_at(bc_index);
|
|
||||||
Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
|
Symbol* ref_class_name = cp->klass_name_at(cp->klass_ref_index_at(bc_index));
|
||||||
|
|
||||||
if (klass->name() == ref_class_name) {
|
if (klass->name() == ref_class_name) {
|
||||||
|
Symbol* field_name = cp->name_ref_at(bc_index);
|
||||||
|
Symbol* field_sig = cp->signature_ref_at(bc_index);
|
||||||
|
|
||||||
fieldDescriptor fd;
|
fieldDescriptor fd;
|
||||||
klass->find_field(field_name, field_sig, &fd);
|
klass->find_field(field_name, field_sig, &fd);
|
||||||
if (fd.access_flags().is_final()) {
|
if (fd.access_flags().is_final()) {
|
||||||
if (fd.access_flags().is_static()) {
|
if (fd.access_flags().is_static()) {
|
||||||
assert(c == Bytecodes::_putstatic, "must be putstatic");
|
|
||||||
if (!method->is_static_initializer()) {
|
if (!method->is_static_initializer()) {
|
||||||
fd.set_has_initialized_final_update(true);
|
fd.set_has_initialized_final_update(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(c == Bytecodes::_putfield, "must be putfield");
|
|
||||||
if (!method->is_object_initializer()) {
|
if (!method->is_object_initializer()) {
|
||||||
fd.set_has_initialized_final_update(true);
|
fd.set_has_initialized_final_update(true);
|
||||||
}
|
}
|
||||||
|
@ -584,27 +584,26 @@ static bool verify_special_jvm_flags() {
|
|||||||
// Parses a size specification string.
|
// Parses a size specification string.
|
||||||
bool Arguments::atojulong(const char *s, julong* result) {
|
bool Arguments::atojulong(const char *s, julong* result) {
|
||||||
julong n = 0;
|
julong n = 0;
|
||||||
int args_read = 0;
|
|
||||||
bool is_hex = false;
|
// First char must be a digit. Don't allow negative numbers or leading spaces.
|
||||||
// Skip leading 0[xX] for hexadecimal
|
if (!isdigit(*s)) {
|
||||||
if (*s =='0' && (*(s+1) == 'x' || *(s+1) == 'X')) {
|
|
||||||
s += 2;
|
|
||||||
is_hex = true;
|
|
||||||
args_read = sscanf(s, JULONG_FORMAT_X, &n);
|
|
||||||
} else {
|
|
||||||
args_read = sscanf(s, JULONG_FORMAT, &n);
|
|
||||||
}
|
|
||||||
if (args_read != 1) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (*s != '\0' && (isdigit(*s) || (is_hex && isxdigit(*s)))) {
|
|
||||||
s++;
|
bool is_hex = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
|
||||||
}
|
char* remainder;
|
||||||
// 4705540: illegal if more characters are found after the first non-digit
|
errno = 0;
|
||||||
if (strlen(s) > 1) {
|
n = strtoull(s, &remainder, (is_hex ? 16 : 10));
|
||||||
|
if (errno != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
switch (*s) {
|
|
||||||
|
// Fail if no number was read at all or if the remainder contains more than a single non-digit character.
|
||||||
|
if (remainder == s || strlen(remainder) > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*remainder) {
|
||||||
case 'T': case 't':
|
case 'T': case 't':
|
||||||
*result = n * G * K;
|
*result = n * G * K;
|
||||||
// Check for overflow.
|
// Check for overflow.
|
||||||
|
@ -205,16 +205,39 @@ void VMError::print_stack_trace(outputStream* st, JavaThread* jt,
|
|||||||
static void print_oom_reasons(outputStream* st) {
|
static void print_oom_reasons(outputStream* st) {
|
||||||
st->print_cr("# Possible reasons:");
|
st->print_cr("# Possible reasons:");
|
||||||
st->print_cr("# The system is out of physical RAM or swap space");
|
st->print_cr("# The system is out of physical RAM or swap space");
|
||||||
st->print_cr("# In 32 bit mode, the process size limit was hit");
|
if (UseCompressedOops) {
|
||||||
|
st->print_cr("# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap");
|
||||||
|
}
|
||||||
|
if (LogBytesPerWord == 2) {
|
||||||
|
st->print_cr("# In 32 bit mode, the process size limit was hit");
|
||||||
|
}
|
||||||
st->print_cr("# Possible solutions:");
|
st->print_cr("# Possible solutions:");
|
||||||
st->print_cr("# Reduce memory load on the system");
|
st->print_cr("# Reduce memory load on the system");
|
||||||
st->print_cr("# Increase physical memory or swap space");
|
st->print_cr("# Increase physical memory or swap space");
|
||||||
st->print_cr("# Check if swap backing store is full");
|
st->print_cr("# Check if swap backing store is full");
|
||||||
st->print_cr("# Use 64 bit Java on a 64 bit OS");
|
if (LogBytesPerWord == 2) {
|
||||||
|
st->print_cr("# Use 64 bit Java on a 64 bit OS");
|
||||||
|
}
|
||||||
st->print_cr("# Decrease Java heap size (-Xmx/-Xms)");
|
st->print_cr("# Decrease Java heap size (-Xmx/-Xms)");
|
||||||
st->print_cr("# Decrease number of Java threads");
|
st->print_cr("# Decrease number of Java threads");
|
||||||
st->print_cr("# Decrease Java thread stack sizes (-Xss)");
|
st->print_cr("# Decrease Java thread stack sizes (-Xss)");
|
||||||
st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize=");
|
st->print_cr("# Set larger code cache with -XX:ReservedCodeCacheSize=");
|
||||||
|
if (UseCompressedOops) {
|
||||||
|
switch (Universe::narrow_oop_mode()) {
|
||||||
|
case Universe::UnscaledNarrowOop:
|
||||||
|
st->print_cr("# JVM is running with Unscaled Compressed Oops mode in which the Java heap is");
|
||||||
|
st->print_cr("# placed in the first 4GB address space. The Java Heap base address is the");
|
||||||
|
st->print_cr("# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress");
|
||||||
|
st->print_cr("# to set the Java Heap base and to place the Java Heap above 4GB virtual address.");
|
||||||
|
break;
|
||||||
|
case Universe::ZeroBasedNarrowOop:
|
||||||
|
st->print_cr("# JVM is running with Zero Based Compressed Oops mode in which the Java heap is");
|
||||||
|
st->print_cr("# placed in the first 32GB address space. The Java Heap base address is the");
|
||||||
|
st->print_cr("# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress");
|
||||||
|
st->print_cr("# to set the Java Heap base and to place the Java Heap above 32GB virtual address.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
st->print_cr("# This output file may be truncated or incomplete.");
|
st->print_cr("# This output file may be truncated or incomplete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +395,17 @@ hotspot_jprt = \
|
|||||||
:hotspot_fast_gc_gcold \
|
:hotspot_fast_gc_gcold \
|
||||||
:hotspot_fast_runtime \
|
:hotspot_fast_runtime \
|
||||||
:hotspot_fast_serviceability
|
:hotspot_fast_serviceability
|
||||||
|
|
||||||
|
hotspot_runtime_tier2 = \
|
||||||
|
runtime/ \
|
||||||
|
serviceability/ \
|
||||||
|
-:hotspot_fast_runtime \
|
||||||
|
-:hotspot_fast_serviceability \
|
||||||
|
-:hotspot_runtime_tier2_platform_agnostic
|
||||||
|
|
||||||
|
hotspot_runtime_tier2_platform_agnostic = \
|
||||||
|
runtime/SelectionResolution \
|
||||||
|
-:hotspot_fast_runtime
|
||||||
|
|
||||||
#All tests that depends on nashorn extension.
|
#All tests that depends on nashorn extension.
|
||||||
#
|
#
|
||||||
|
@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* 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 gc.g1.humongousObjects;
|
||||||
|
|
||||||
|
import jdk.test.lib.Utils;
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test TestNoAllocationsInHRegions
|
||||||
|
* @summary Checks that no additional allocations are made in humongous regions
|
||||||
|
* @requires vm.gc.G1
|
||||||
|
* @library /testlibrary /test/lib /
|
||||||
|
* @modules java.management java.base/jdk.internal.misc
|
||||||
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* gc.testlibrary.Helpers
|
||||||
|
* gc.g1.humongousObjects.TestNoAllocationsInHRegions
|
||||||
|
*
|
||||||
|
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||||
|
* -XX:G1HeapRegionSize=1M -Xms200m -Xmx200m -XX:MaxTenuringThreshold=0
|
||||||
|
* -Xlog:gc=trace:file=TestNoAllocationsInHRegions10.log
|
||||||
|
* gc.g1.humongousObjects.TestNoAllocationsInHRegions 30 10
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||||
|
* -XX:G1HeapRegionSize=1M -Xms200m -Xmx200m -XX:MaxTenuringThreshold=0
|
||||||
|
* -Xlog:gc=trace:file=TestNoAllocationsInHRegions50.log
|
||||||
|
* gc.g1.humongousObjects.TestNoAllocationsInHRegions 30 50
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||||
|
* -XX:G1HeapRegionSize=1M -Xms200m -Xmx200m -XX:MaxTenuringThreshold=0
|
||||||
|
* -Xlog:gc=trace:file=TestNoAllocationsInHRegions70.log
|
||||||
|
* gc.g1.humongousObjects.TestNoAllocationsInHRegions 30 70
|
||||||
|
*/
|
||||||
|
public class TestNoAllocationsInHRegions {
|
||||||
|
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||||
|
private static final Random RND = Utils.getRandomInstance();
|
||||||
|
private static final int G1_REGION_SIZE = WB.g1RegionSize();
|
||||||
|
private static final int[] HUMONGOUS_SIZES = {G1_REGION_SIZE / 2, G1_REGION_SIZE + 1, G1_REGION_SIZE * 2 + 1};
|
||||||
|
private static final int ALLOC_THREAD_COUNT = 5;
|
||||||
|
|
||||||
|
// We fill specified part of heap with humongous objects - we need public static to prevent escape analysis to
|
||||||
|
// collect this field
|
||||||
|
public static LinkedList<byte[]> humongousAllocations = new LinkedList<>();
|
||||||
|
|
||||||
|
private static volatile boolean shouldStop = false;
|
||||||
|
private static volatile Error error = null;
|
||||||
|
|
||||||
|
static class Allocator implements Runnable {
|
||||||
|
|
||||||
|
private final List<byte[]> liveObjects = new LinkedList<>();
|
||||||
|
private int usedMemory = 0;
|
||||||
|
public final Runnable[] actions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size of simple allocation
|
||||||
|
*/
|
||||||
|
private static final int MAX_ALLOCATION_SIZE = (int) (G1_REGION_SIZE / 2 * 0.9);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size of dead (i.e. one which is made unreachable right after allocation) object
|
||||||
|
*/
|
||||||
|
private static final int DEAD_OBJECT_MAX_SIZE = G1_REGION_SIZE / 10;
|
||||||
|
|
||||||
|
public Allocator(int maxAllocationMemory) {
|
||||||
|
|
||||||
|
actions = new Runnable[]{
|
||||||
|
// Allocation
|
||||||
|
() -> {
|
||||||
|
if (maxAllocationMemory - usedMemory != 0) {
|
||||||
|
int arraySize = RND.nextInt(Math.min(maxAllocationMemory - usedMemory,
|
||||||
|
MAX_ALLOCATION_SIZE));
|
||||||
|
|
||||||
|
if (arraySize != 0) {
|
||||||
|
byte[] allocation = new byte[arraySize];
|
||||||
|
liveObjects.add(allocation);
|
||||||
|
usedMemory += arraySize;
|
||||||
|
|
||||||
|
// Sanity check
|
||||||
|
if (WB.g1IsHumongous(allocation)) {
|
||||||
|
String errorMessage = String.format("Test Bug: Byte array of size"
|
||||||
|
+ " %d is expected to be non-humongous but it is humongous",
|
||||||
|
allocation.length);
|
||||||
|
|
||||||
|
System.out.println(errorMessage);
|
||||||
|
error = new Error(errorMessage);
|
||||||
|
shouldStop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test check
|
||||||
|
if (WB.g1BelongsToHumongousRegion(WB.getObjectAddress(allocation))) {
|
||||||
|
String errorMessage = String.format("Non-humongous allocation of byte array of "
|
||||||
|
+ "length %d and size %d with address %d was made in Humongous Region",
|
||||||
|
allocation.length, WB.getObjectSize(allocation),
|
||||||
|
WB.getObjectAddress(allocation));
|
||||||
|
|
||||||
|
System.out.println(errorMessage);
|
||||||
|
error = new Error(errorMessage);
|
||||||
|
shouldStop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Deallocation
|
||||||
|
() -> {
|
||||||
|
if (liveObjects.size() != 0) {
|
||||||
|
int elementNum = RND.nextInt(liveObjects.size());
|
||||||
|
int shouldFree = liveObjects.get(elementNum).length;
|
||||||
|
liveObjects.remove(elementNum);
|
||||||
|
usedMemory -= shouldFree;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Dead object allocation
|
||||||
|
() -> {
|
||||||
|
int size = RND.nextInt(DEAD_OBJECT_MAX_SIZE);
|
||||||
|
byte[] deadObject = new byte[size];
|
||||||
|
},
|
||||||
|
|
||||||
|
// Check
|
||||||
|
() -> {
|
||||||
|
List<byte[]> wrongHumongousAllocations = liveObjects.stream()
|
||||||
|
.filter(WB::g1IsHumongous)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (wrongHumongousAllocations.size() > 0) {
|
||||||
|
wrongHumongousAllocations.stream().forEach(a ->
|
||||||
|
System.out.format("Non-humongous allocation of byte array of length %d and"
|
||||||
|
+ " size %d with address %d was made in Humongous Region",
|
||||||
|
a.length, WB.getObjectSize(a), WB.getObjectAddress(a)));
|
||||||
|
error = new Error("Some non-humongous allocations were made to humongous region");
|
||||||
|
shouldStop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (!shouldStop) {
|
||||||
|
actions[RND.nextInt(actions.length)].run();
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
if (args.length != 2) {
|
||||||
|
throw new Error("Test Bug: Expected duration (in seconds) and percent of allocated regions were not "
|
||||||
|
+ "provided as command line argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
// test duration
|
||||||
|
long duration = Integer.parseInt(args[0]) * 1000L;
|
||||||
|
// part of heap preallocated with humongous objects (in percents)
|
||||||
|
int percentOfAllocatedHeap = Integer.parseInt(args[1]);
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
long initialFreeRegionsCount = WB.g1NumFreeRegions();
|
||||||
|
int regionsToAllocate = (int) ((double) initialFreeRegionsCount / 100.0 * percentOfAllocatedHeap);
|
||||||
|
long freeRegionLeft = initialFreeRegionsCount - regionsToAllocate;
|
||||||
|
|
||||||
|
System.out.println("Regions to allocate: " + regionsToAllocate + "; regions to left free: " + freeRegionLeft);
|
||||||
|
|
||||||
|
int maxMemoryPerAllocThread = (int) ((Runtime.getRuntime().freeMemory() / 100.0
|
||||||
|
* (100 - percentOfAllocatedHeap)) / ALLOC_THREAD_COUNT * 0.5);
|
||||||
|
|
||||||
|
System.out.println("Using " + maxMemoryPerAllocThread / 1024 + "KB for each of " + ALLOC_THREAD_COUNT
|
||||||
|
+ " allocation threads");
|
||||||
|
|
||||||
|
while (WB.g1NumFreeRegions() > freeRegionLeft) {
|
||||||
|
try {
|
||||||
|
humongousAllocations.add(new byte[HUMONGOUS_SIZES[RND.nextInt(HUMONGOUS_SIZES.length)]]);
|
||||||
|
} catch (OutOfMemoryError oom) {
|
||||||
|
//We got OOM trying to fill heap with humongous objects
|
||||||
|
//It probably means that heap is fragmented which is strange since the test logic should avoid it
|
||||||
|
System.out.println("Warning: OOM while allocating humongous objects - it likely means "
|
||||||
|
+ "that heap is fragmented");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Initial free regions " + initialFreeRegionsCount + "; Free regions left "
|
||||||
|
+ WB.g1NumFreeRegions());
|
||||||
|
|
||||||
|
LinkedList<Thread> threads = new LinkedList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < ALLOC_THREAD_COUNT; i++) {
|
||||||
|
threads.add(new Thread(new Allocator(maxMemoryPerAllocThread)));
|
||||||
|
}
|
||||||
|
|
||||||
|
threads.stream().forEach(Thread::start);
|
||||||
|
|
||||||
|
while ((System.currentTimeMillis() - startTime < duration) && error == null) {
|
||||||
|
Thread.yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldStop = true;
|
||||||
|
System.out.println("Finished test");
|
||||||
|
if (error != null) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -138,6 +138,41 @@ public enum GC {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
MIXED_GC {
|
||||||
|
@Override
|
||||||
|
public Runnable get() {
|
||||||
|
return () -> {
|
||||||
|
WHITE_BOX.youngGC();
|
||||||
|
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||||
|
WHITE_BOX.youngGC();
|
||||||
|
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||||
|
|
||||||
|
WHITE_BOX.g1StartConcMarkCycle();
|
||||||
|
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||||
|
|
||||||
|
WHITE_BOX.youngGC();
|
||||||
|
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||||
|
// Provoking Mixed GC
|
||||||
|
WHITE_BOX.youngGC();// second evacuation pause will be mixed
|
||||||
|
Helpers.waitTillCMCFinished(WHITE_BOX, 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public Consumer<ReferenceInfo<Object[]>> getChecker() {
|
||||||
|
return getCheckerImpl(true, false, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> shouldContain() {
|
||||||
|
return Arrays.asList(GCTokens.WB_INITIATED_CMC);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> shouldNotContain() {
|
||||||
|
return Arrays.asList(GCTokens.YOUNG_GC);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
FULL_GC_MEMORY_PRESSURE {
|
FULL_GC_MEMORY_PRESSURE {
|
||||||
@Override
|
@Override
|
||||||
public Runnable get() {
|
public Runnable get() {
|
||||||
|
@ -38,6 +38,9 @@ The test checks that after different type of GC unreachable objects behave as ex
|
|||||||
non-humongous and humongous objects are not collected since we make 2 Young GC to promote all
|
non-humongous and humongous objects are not collected since we make 2 Young GC to promote all
|
||||||
weak references to Old Gen.
|
weak references to Old Gen.
|
||||||
|
|
||||||
|
6. Mixed GC - weakly referenced non-humongous and humongous objects are collected, softly referenced non-humongous and
|
||||||
|
humongous objects are not collected.
|
||||||
|
|
||||||
The test gets gc type as a command line argument.
|
The test gets gc type as a command line argument.
|
||||||
Then the test allocates object graph in heap (currently testing scenarios are pre-generated and stored in
|
Then the test allocates object graph in heap (currently testing scenarios are pre-generated and stored in
|
||||||
TestcaseData.getPregeneratedTestcases()) with TestObjectGraphAfterGC::allocateObjectGraph.
|
TestcaseData.getPregeneratedTestcases()) with TestObjectGraphAfterGC::allocateObjectGraph.
|
||||||
|
@ -66,6 +66,12 @@ import java.util.stream.Collectors;
|
|||||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
*
|
*
|
||||||
* @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
* @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||||
|
* -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=30000 -XX:G1MixedGCLiveThresholdPercent=100 -XX:G1HeapWastePercent=0
|
||||||
|
* -XX:G1HeapRegionSize=1M -Xlog:gc=info:file=TestObjectGraphAfterGC_MIXED_GC.gc.log -XX:MaxTenuringThreshold=1
|
||||||
|
* -XX:G1MixedGCCountTarget=1 -XX:G1OldCSetRegionThresholdPercent=100 -XX:SurvivorRatio=1 -XX:InitiatingHeapOccupancyPercent=0
|
||||||
|
* gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC MIXED_GC
|
||||||
|
*
|
||||||
|
* @run main/othervm -Xms200M -XX:+UseG1GC -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:.
|
||||||
* -XX:G1HeapRegionSize=1M -Xlog:gc*=debug:file=TestObjectGraphAfterGC_YOUNG_GC.gc.log
|
* -XX:G1HeapRegionSize=1M -Xlog:gc*=debug:file=TestObjectGraphAfterGC_YOUNG_GC.gc.log
|
||||||
* gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC YOUNG_GC
|
* gc.g1.humongousObjects.objectGraphTest.TestObjectGraphAfterGC YOUNG_GC
|
||||||
*
|
*
|
||||||
|
71
hotspot/test/native/runtime/test_arguments.cpp
Normal file
71
hotspot/test/native/runtime/test_arguments.cpp
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "precompiled.hpp"
|
||||||
|
#include "runtime/arguments.hpp"
|
||||||
|
#include "unittest.hpp"
|
||||||
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
|
TEST(arguments, atojulong) {
|
||||||
|
char ullong_max[32];
|
||||||
|
int ret = jio_snprintf(ullong_max, sizeof(ullong_max), JULONG_FORMAT, ULLONG_MAX);
|
||||||
|
ASSERT_NE(-1, ret);
|
||||||
|
|
||||||
|
julong value;
|
||||||
|
const char* invalid_strings[] = {
|
||||||
|
"", "-1", "-100", " 1", "2 ", "3 2", "1.0",
|
||||||
|
"0x4.5", "0x", "0x0x1" "0.001", "4e10", "e"
|
||||||
|
"K", "M", "G", "1MB", "1KM", "AA", "0B",
|
||||||
|
"18446744073709551615K", "17179869184G",
|
||||||
|
"999999999999999999999999999999"
|
||||||
|
};
|
||||||
|
for (uint i = 0; i < ARRAY_SIZE(invalid_strings); i++) {
|
||||||
|
ASSERT_FALSE(Arguments::atojulong(invalid_strings[i], &value))
|
||||||
|
<< "Invalid string '" << invalid_strings[i] << "' parsed without error.";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char* str;
|
||||||
|
julong expected_value;
|
||||||
|
} valid_strings[] = {
|
||||||
|
{ "0", 0 },
|
||||||
|
{ "4711", 4711 },
|
||||||
|
{ "1K", 1ULL * K },
|
||||||
|
{ "1k", 1ULL * K },
|
||||||
|
{ "2M", 2ULL * M },
|
||||||
|
{ "2m", 2ULL * M },
|
||||||
|
{ "4G", 4ULL * G },
|
||||||
|
{ "4g", 4ULL * G },
|
||||||
|
{ "0K", 0 },
|
||||||
|
{ ullong_max, ULLONG_MAX },
|
||||||
|
{ "0xcafebabe", 0xcafebabe },
|
||||||
|
{ "0XCAFEBABE", 0xcafebabe },
|
||||||
|
{ "0XCAFEbabe", 0xcafebabe },
|
||||||
|
{ "0x10K", 0x10 * K }
|
||||||
|
};
|
||||||
|
for (uint i = 0; i < ARRAY_SIZE(valid_strings); i++) {
|
||||||
|
ASSERT_TRUE(Arguments::atojulong(valid_strings[i].str, &value))
|
||||||
|
<< "Valid string '" << valid_strings[i].str << "' did not parse.";
|
||||||
|
ASSERT_EQ(valid_strings[i].expected_value, value);
|
||||||
|
}
|
||||||
|
}
|
55
hotspot/test/runtime/Final/Bad.jasm
Normal file
55
hotspot/test/runtime/Final/Bad.jasm
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Recoded in jasm to provoke an ICCE assigning a non-static final field with putstatic.
|
||||||
|
class Bad {
|
||||||
|
public static final int i; //rewritten
|
||||||
|
//rewritten to: public final int i;
|
||||||
|
static { i = 5; } // putstatic instruction
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
super class Bad
|
||||||
|
version 53:0
|
||||||
|
{
|
||||||
|
|
||||||
|
// Remove 'static' keyword
|
||||||
|
public final Field i:I;
|
||||||
|
|
||||||
|
Method "<init>":"()V"
|
||||||
|
stack 1 locals 1
|
||||||
|
{
|
||||||
|
aload_0;
|
||||||
|
invokespecial Method java/lang/Object."<init>":"()V";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Method "<clinit>":"()V"
|
||||||
|
stack 1 locals 0
|
||||||
|
{
|
||||||
|
iconst_5;
|
||||||
|
putstatic Field i:"I";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end Class Bad
|
42
hotspot/test/runtime/Final/PutfieldError.java
Normal file
42
hotspot/test/runtime/Final/PutfieldError.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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 PutfieldError
|
||||||
|
* @bug 8160551
|
||||||
|
* @summary Throw ICCE rather than crashing for nonstatic final field in static initializer
|
||||||
|
* @compile Bad.jasm
|
||||||
|
* @run main PutfieldError
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PutfieldError {
|
||||||
|
public static void main(java.lang.String[] unused) {
|
||||||
|
try {
|
||||||
|
Bad b = new Bad();
|
||||||
|
System.out.println("Bad.i = " + 5);
|
||||||
|
throw new RuntimeException("ICCE NOT thrown as expected");
|
||||||
|
} catch (IncompatibleClassChangeError icce) {
|
||||||
|
System.out.println("ICCE thrown as expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 SharedStringsDedup
|
||||||
|
* @summary Test -Xshare:auto with shared strings and -XX:+UseStringDeduplication
|
||||||
|
* Feature support: G1GC only, compressed oops/kptrs, 64-bit os, not on windows
|
||||||
|
* @requires (sun.arch.data.model != "32") & (os.family != "windows")
|
||||||
|
* @requires (vm.opt.UseCompressedOops == null) | (vm.opt.UseCompressedOops == true)
|
||||||
|
* @requires vm.gc.G1
|
||||||
|
* @library /testlibrary
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* java.management
|
||||||
|
* @run main SharedStringsDedup
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
// The main purpose is to test the interaction between shared strings
|
||||||
|
// and -XX:+UseStringDeduplication. We run in -Xshare:auto mode so
|
||||||
|
// we don't need to worry about CDS archive mapping failure (which
|
||||||
|
// doesn't happen often so it won't impact coverage).
|
||||||
|
public class SharedStringsDedup {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// Dump
|
||||||
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
"-XX:SharedArchiveFile=./SharedStringsDedup.jsa",
|
||||||
|
"-XX:+UseCompressedOops", "-XX:+UseG1GC",
|
||||||
|
"-XX:+PrintSharedSpaces",
|
||||||
|
"-Xshare:dump");
|
||||||
|
|
||||||
|
new OutputAnalyzer(pb.start())
|
||||||
|
.shouldContain("Loading classes to share")
|
||||||
|
.shouldContain("Shared string table stats")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
// Run with -Xshare:auto
|
||||||
|
pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-XX:+UnlockDiagnosticVMOptions",
|
||||||
|
"-XX:SharedArchiveFile=./SharedStringsDedup.jsa",
|
||||||
|
"-XX:+UseCompressedOops", "-XX:+UseG1GC",
|
||||||
|
"-XX:+UseStringDeduplication",
|
||||||
|
"-Xshare:auto",
|
||||||
|
"-version");
|
||||||
|
|
||||||
|
new OutputAnalyzer(pb.start())
|
||||||
|
.shouldMatch("(java|openjdk) version")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom system ClassLoader to define the module "m2" to during iterations of
|
||||||
|
* differing test runs within the test ModuleStress.java
|
||||||
|
*/
|
||||||
|
public class CustomSystemClassLoader extends ClassLoader {
|
||||||
|
public CustomSystemClassLoader() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
public CustomSystemClassLoader(ClassLoader parent) {
|
||||||
|
super(parent);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static jdk.test.lib.Asserts.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Layer;
|
||||||
|
import java.lang.module.Configuration;
|
||||||
|
import java.lang.module.ModuleDescriptor;
|
||||||
|
import java.lang.module.ModuleFinder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ClassLoader1 --> defines m1 --> packages p1
|
||||||
|
// ClassLoader2 --> defines m2 --> packages p2
|
||||||
|
// Java System Class Loader --> defines m3 --> packages p3
|
||||||
|
//
|
||||||
|
// m1 can read m2
|
||||||
|
// package p2 in m2 is exported to m1 and m3
|
||||||
|
//
|
||||||
|
// class p1.c1 defined in m1 tries to access p2.c2 defined in m2
|
||||||
|
// Access allowed since m1 can read m2 and package p2 is exported to m1.
|
||||||
|
//
|
||||||
|
public class ModuleNonBuiltinCLMain {
|
||||||
|
|
||||||
|
// Create a Layer over the boot layer.
|
||||||
|
// Define modules within this layer to test access between
|
||||||
|
// publically defined classes within packages of those modules.
|
||||||
|
public void createLayerOnBoot() throws Throwable {
|
||||||
|
|
||||||
|
// Define module: m1
|
||||||
|
// Can read: java.base, m2
|
||||||
|
// Packages: p1
|
||||||
|
// Packages exported: p1 is exported to unqualifiedly
|
||||||
|
ModuleDescriptor descriptor_m1 =
|
||||||
|
new ModuleDescriptor.Builder("m1")
|
||||||
|
.requires("java.base")
|
||||||
|
.requires("m2")
|
||||||
|
.exports("p1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Define module: m2
|
||||||
|
// Can read: java.base, m3
|
||||||
|
// Packages: p2
|
||||||
|
// Packages exported: package p2 is exported to m1 and m3
|
||||||
|
Set<String> targets = new HashSet<>();
|
||||||
|
targets.add("m1");
|
||||||
|
targets.add("m3");
|
||||||
|
ModuleDescriptor descriptor_m2 =
|
||||||
|
new ModuleDescriptor.Builder("m2")
|
||||||
|
.requires("java.base")
|
||||||
|
.requires("m3")
|
||||||
|
.exports("p2", targets)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Define module: m3
|
||||||
|
// Can read: java.base
|
||||||
|
// Packages: p3
|
||||||
|
// Packages exported: none
|
||||||
|
ModuleDescriptor descriptor_m3 =
|
||||||
|
new ModuleDescriptor.Builder("m3")
|
||||||
|
.requires("java.base")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Set up a ModuleFinder containing all modules for this layer.
|
||||||
|
ModuleFinder finder = ModuleLibrary.of(descriptor_m1, descriptor_m2, descriptor_m3);
|
||||||
|
|
||||||
|
// Resolves "m1"
|
||||||
|
Configuration cf = Layer.boot()
|
||||||
|
.configuration()
|
||||||
|
.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
|
||||||
|
|
||||||
|
// map each module to differing user defined class loaders for this test
|
||||||
|
Map<String, ClassLoader> map = new HashMap<>();
|
||||||
|
Loader1 cl1 = new Loader1();
|
||||||
|
Loader2 cl2 = new Loader2();
|
||||||
|
ClassLoader cl3 = ClassLoader.getSystemClassLoader();
|
||||||
|
map.put("m1", cl1);
|
||||||
|
map.put("m2", cl2);
|
||||||
|
map.put("m3", cl3);
|
||||||
|
|
||||||
|
// Create Layer that contains m1 & m2
|
||||||
|
Layer layer = Layer.boot().defineModules(cf, map::get);
|
||||||
|
assertTrue(layer.findLoader("m1") == cl1);
|
||||||
|
assertTrue(layer.findLoader("m2") == cl2);
|
||||||
|
assertTrue(layer.findLoader("m3") == cl3);
|
||||||
|
assertTrue(layer.findLoader("java.base") == null);
|
||||||
|
|
||||||
|
// now use the same loader to load class p1.c1
|
||||||
|
Class p1_c1_class = cl1.loadClass("p1.c1");
|
||||||
|
try {
|
||||||
|
p1_c1_class.newInstance();
|
||||||
|
} catch (IllegalAccessError e) {
|
||||||
|
throw new RuntimeException("Test Failed, an IAE should not be thrown since p2 is exported qualifiedly to m1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Throwable {
|
||||||
|
ModuleNonBuiltinCLMain test = new ModuleNonBuiltinCLMain();
|
||||||
|
test.createLayerOnBoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Loader1 extends ClassLoader { }
|
||||||
|
static class Loader2 extends ClassLoader { }
|
||||||
|
}
|
109
hotspot/test/runtime/modules/ModuleStress/ModuleSameCLMain.java
Normal file
109
hotspot/test/runtime/modules/ModuleStress/ModuleSameCLMain.java
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import static jdk.test.lib.Asserts.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Layer;
|
||||||
|
import java.lang.module.Configuration;
|
||||||
|
import java.lang.module.ModuleDescriptor;
|
||||||
|
import java.lang.module.ModuleFinder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
//
|
||||||
|
// ClassLoader1 --> defines m1 --> packages p1
|
||||||
|
// ClassLoader1 --> defines m2 --> packages p2
|
||||||
|
//
|
||||||
|
// m1 can read m2
|
||||||
|
// package p2 in m2 is exported to m1
|
||||||
|
//
|
||||||
|
// class p1.c1 defined in m1 tries to access p2.c2 defined in m2
|
||||||
|
// Access allowed since m1 can read m2 and package p2 is exported to m1.
|
||||||
|
//
|
||||||
|
public class ModuleSameCLMain {
|
||||||
|
|
||||||
|
// Create a Layer over the boot layer.
|
||||||
|
// Define modules within this layer to test access between
|
||||||
|
// publically defined classes within packages of those modules.
|
||||||
|
public void createLayerOnBoot() throws Throwable {
|
||||||
|
|
||||||
|
// Define module: m1
|
||||||
|
// Can read: java.base, m2
|
||||||
|
// Packages: p1
|
||||||
|
// Packages exported: p1 is exported to unqualifiedly
|
||||||
|
ModuleDescriptor descriptor_m1 =
|
||||||
|
new ModuleDescriptor.Builder("m1")
|
||||||
|
.requires("java.base")
|
||||||
|
.requires("m2")
|
||||||
|
.exports("p1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Define module: m2
|
||||||
|
// Can read: java.base
|
||||||
|
// Packages: p2
|
||||||
|
// Packages exported: package p2 is exported to m1
|
||||||
|
ModuleDescriptor descriptor_m2 =
|
||||||
|
new ModuleDescriptor.Builder("m2")
|
||||||
|
.requires("java.base")
|
||||||
|
.exports("p2", "m1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Set up a ModuleFinder containing all modules for this layer.
|
||||||
|
ModuleFinder finder = ModuleLibrary.of(descriptor_m1, descriptor_m2);
|
||||||
|
|
||||||
|
// Resolves "m1"
|
||||||
|
Configuration cf = Layer.boot()
|
||||||
|
.configuration()
|
||||||
|
.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
|
||||||
|
|
||||||
|
// map each module to the same class loader for this test
|
||||||
|
Map<String, ClassLoader> map = new HashMap<>();
|
||||||
|
Loader1 cl1 = new Loader1();
|
||||||
|
map.put("m1", cl1);
|
||||||
|
map.put("m2", cl1);
|
||||||
|
|
||||||
|
// Create Layer that contains m1 & m2
|
||||||
|
Layer layer = Layer.boot().defineModules(cf, map::get);
|
||||||
|
assertTrue(layer.findLoader("m1") == cl1);
|
||||||
|
assertTrue(layer.findLoader("m2") == cl1);
|
||||||
|
assertTrue(layer.findLoader("java.base") == null);
|
||||||
|
|
||||||
|
// now use the same loader to load class p1.c1
|
||||||
|
Class p1_c1_class = cl1.loadClass("p1.c1");
|
||||||
|
try {
|
||||||
|
p1_c1_class.newInstance();
|
||||||
|
} catch (IllegalAccessError e) {
|
||||||
|
throw new RuntimeException("Test Failed, an IAE should not be thrown since p2 is exported qualifiedly to m1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) throws Throwable {
|
||||||
|
ModuleSameCLMain test = new ModuleSameCLMain();
|
||||||
|
test.createLayerOnBoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Loader1 extends ClassLoader { }
|
||||||
|
}
|
131
hotspot/test/runtime/modules/ModuleStress/ModuleStress.java
Normal file
131
hotspot/test/runtime/modules/ModuleStress/ModuleStress.java
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* 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 8159262
|
||||||
|
* @summary Test differing scenarios where a module's readability list and a package's exportability list should be walked
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @library /testlibrary /test/lib
|
||||||
|
* @compile ../AccessCheck/ModuleLibrary.java
|
||||||
|
* @compile ModuleSameCLMain.java
|
||||||
|
* @compile ModuleNonBuiltinCLMain.java
|
||||||
|
* @compile CustomSystemClassLoader.java
|
||||||
|
* @build ModuleStress
|
||||||
|
* @run main/othervm ModuleStress
|
||||||
|
*/
|
||||||
|
|
||||||
|
import jdk.test.lib.*;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class ModuleStress {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
// Test #1: java -version
|
||||||
|
// All modules' readability lists and packages' exportability
|
||||||
|
// lists should contain only modules defined to the 3 builtin
|
||||||
|
// loaders (boot, application, platform). Thus there is
|
||||||
|
// not a need to walk those lists at a GC safepoint since
|
||||||
|
// those loaders never die.
|
||||||
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-Xbootclasspath/a:.",
|
||||||
|
"-Xlog:modules=trace",
|
||||||
|
"-version");
|
||||||
|
|
||||||
|
OutputAnalyzer oa = new OutputAnalyzer(pb.start());
|
||||||
|
oa.shouldNotContain("must be walked")
|
||||||
|
.shouldNotContain("being walked")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
// Next 2 tests involve the use of class p1.c1 and p2.c2
|
||||||
|
String source1 = "package p1;" +
|
||||||
|
"import p2.c2;" +
|
||||||
|
"public class c1 {" +
|
||||||
|
" public c1() {" +
|
||||||
|
" p2.c2 c2_obj = new p2.c2();" +
|
||||||
|
" c2_obj.method2();" +
|
||||||
|
" }" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
String source2 = "package p2;" +
|
||||||
|
"public class c2 {" +
|
||||||
|
" public void method2() { }" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
ClassFileInstaller.writeClassToDisk("p2/c2",
|
||||||
|
InMemoryJavaCompiler.compile("p2.c2", source2), System.getProperty("test.classes"));
|
||||||
|
|
||||||
|
ClassFileInstaller.writeClassToDisk("p1/c1",
|
||||||
|
InMemoryJavaCompiler.compile("p1.c1", source1), System.getProperty("test.classes"));
|
||||||
|
|
||||||
|
// Test #2: Load two modules defined to the same customer class loader.
|
||||||
|
// m1's module readability list and package p2's exportability should
|
||||||
|
// not be walked at a GC safepoint since both modules are defined to
|
||||||
|
// the same loader and thus have the exact same life cycle.
|
||||||
|
pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-Xbootclasspath/a:.",
|
||||||
|
"-Xlog:modules=trace",
|
||||||
|
"ModuleSameCLMain");
|
||||||
|
|
||||||
|
oa = new OutputAnalyzer(pb.start());
|
||||||
|
oa.shouldNotContain("must be walked")
|
||||||
|
.shouldNotContain("being walked")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
// Test #3: Load two modules in differing custom class loaders.
|
||||||
|
// m1's module readability list and package p2's exportability list must
|
||||||
|
// be walked at a GC safepoint since both modules are defined to non-builtin
|
||||||
|
// class loaders which could die and thus be unloaded.
|
||||||
|
pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-Xbootclasspath/a:.",
|
||||||
|
"-Xlog:modules=trace",
|
||||||
|
"ModuleNonBuiltinCLMain");
|
||||||
|
|
||||||
|
oa = new OutputAnalyzer(pb.start());
|
||||||
|
oa.shouldContain("module m1 reads list must be walked")
|
||||||
|
.shouldContain("package p2 defined in module m2, exports list must be walked")
|
||||||
|
.shouldNotContain("module m2 reads list must be walked")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
// Test #4: Load two modules in differing custom class loaders,
|
||||||
|
// of which one has been designated as the custom system class loader
|
||||||
|
// via -Djava.system.class.loader=CustomSystemClassLoader. Since
|
||||||
|
// m3 is defined to the system class loader, m2's module readability
|
||||||
|
// list does not have to be walked at a GC safepoint, but package p2's
|
||||||
|
// exportability list does.
|
||||||
|
pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-Djava.system.class.loader=CustomSystemClassLoader",
|
||||||
|
"-Xbootclasspath/a:.",
|
||||||
|
"-Xlog:modules=trace",
|
||||||
|
"ModuleNonBuiltinCLMain");
|
||||||
|
|
||||||
|
oa = new OutputAnalyzer(pb.start());
|
||||||
|
oa.shouldContain("package p2 defined in module m2, exports list must be walked")
|
||||||
|
.shouldNotContain("module m2 reads list must be walked")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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 8159262
|
||||||
|
* @summary layers over the boot layer are repeatedly created, during this iteration, GCs are forced to verify correct walk of module and package lists.
|
||||||
|
* @modules java.base/jdk.internal.misc
|
||||||
|
* @library /testlibrary /test/lib
|
||||||
|
* @compile ../CompilerUtils.java
|
||||||
|
* @build ModuleStressGC
|
||||||
|
* @run main/othervm ModuleStressGC
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import jdk.test.lib.*;
|
||||||
|
|
||||||
|
public class ModuleStressGC {
|
||||||
|
|
||||||
|
private static final String TEST_SRC = System.getProperty("test.src");
|
||||||
|
private static final String TEST_CLASSES = System.getProperty("test.classes");
|
||||||
|
|
||||||
|
private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||||
|
private static final Path MODS_DIR = Paths.get(TEST_CLASSES, "mods");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile two module definitions used by the test, jdk.test and jdk.translet.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
boolean compiled;
|
||||||
|
// Compile module jdk.test declaration
|
||||||
|
compiled = CompilerUtils.compile(
|
||||||
|
SRC_DIR.resolve("jdk.test"),
|
||||||
|
MODS_DIR.resolve("jdk.test"));
|
||||||
|
if (!compiled) {
|
||||||
|
throw new RuntimeException("Test failed to compile module jdk.test");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile module jdk.translet declaration
|
||||||
|
compiled = CompilerUtils.compile(
|
||||||
|
SRC_DIR.resolve("jdk.translet"),
|
||||||
|
MODS_DIR.resolve("jdk.translet"),
|
||||||
|
"-XaddExports:jdk.test/test=jdk.translet",
|
||||||
|
"-mp", MODS_DIR.toString());
|
||||||
|
if (!compiled) {
|
||||||
|
throw new RuntimeException("Test failed to compile module jdk.translet");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check that the test, jdk.test/test/MainGC.java,
|
||||||
|
// correctly walks module jdk.test's reads list and package
|
||||||
|
// test's, defined to module jdk.translet, export list at
|
||||||
|
// GC safepoints.
|
||||||
|
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||||
|
"-Xlog:modules=trace",
|
||||||
|
"-mp", MODS_DIR.toString(),
|
||||||
|
"-m", "jdk.test/test.MainGC");
|
||||||
|
OutputAnalyzer oa = new OutputAnalyzer(pb.start());
|
||||||
|
oa.shouldContain("package test defined in module jdk.test, exports list being walked")
|
||||||
|
.shouldContain("module jdk.test reads list being walked")
|
||||||
|
.shouldHaveExitValue(0);
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package test;
|
||||||
|
|
||||||
|
import java.lang.module.Configuration;
|
||||||
|
import java.lang.module.ModuleFinder;
|
||||||
|
import java.lang.reflect.Layer;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Module;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class MainGC {
|
||||||
|
|
||||||
|
private static final Path MODS_DIR = Paths.get(System.getProperty("jdk.module.path"));
|
||||||
|
static final String MODULE_NAME = "jdk.translet";
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
|
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
|
||||||
|
Layer layerBoot = Layer.boot();
|
||||||
|
|
||||||
|
Configuration cf = layerBoot
|
||||||
|
.configuration()
|
||||||
|
.resolveRequires(ModuleFinder.of(), finder, Set.of(MODULE_NAME));
|
||||||
|
|
||||||
|
Module testModule = MainGC.class.getModule();
|
||||||
|
ClassLoader scl = ClassLoader.getSystemClassLoader();
|
||||||
|
|
||||||
|
// Create an unique module/class loader in a layer above the boot layer.
|
||||||
|
// Export this module to the jdk.test/test package.
|
||||||
|
// Add a read edge from module jdk.test to this module.
|
||||||
|
Callable<Void> task = new Callable<Void>() {
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
|
||||||
|
Module transletModule = layer.findModule(MODULE_NAME).get();
|
||||||
|
testModule.addExports("test", transletModule);
|
||||||
|
testModule.addReads(transletModule);
|
||||||
|
Class<?> c = layer.findLoader(MODULE_NAME).loadClass("translet.MainGC");
|
||||||
|
Method method = c.getDeclaredMethod("go");
|
||||||
|
method.invoke(null);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
List<Future<Void>> results = new ArrayList<>();
|
||||||
|
|
||||||
|
// Repeatedly create the layer above stressing the exportation of
|
||||||
|
// package jdk.test/test to several different modules.
|
||||||
|
ExecutorService pool = Executors.newFixedThreadPool(Math.min(100, Runtime.getRuntime().availableProcessors()*10));
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < 10000; i++) {
|
||||||
|
results.add(pool.submit(task));
|
||||||
|
// At specified intervals, force a GC. This provides an
|
||||||
|
// opportunity to verify that both the module jdk.test's reads
|
||||||
|
// and the package test's, which is defined to jdk.test, exports
|
||||||
|
// lists are being walked.
|
||||||
|
if (i == 3000 || i == 6000 || i == 9000) {
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
pool.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
int passed = 0;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
// The failed state should be 0, the created modules in layers above the
|
||||||
|
// boot layer should be allowed access to the contents of the jdk.test/test
|
||||||
|
// package since that package was exported to the transletModule above.
|
||||||
|
for (Future<Void> result : results) {
|
||||||
|
try {
|
||||||
|
result.get();
|
||||||
|
passed++;
|
||||||
|
} catch (Throwable x) {
|
||||||
|
x.printStackTrace();
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("passed: " + passed);
|
||||||
|
System.out.println("failed: " + failed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void callback() { }
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package translet;
|
||||||
|
|
||||||
|
public class MainGC {
|
||||||
|
public static void go() {
|
||||||
|
test.MainGC.callback();
|
||||||
|
}
|
||||||
|
}
|
@ -369,3 +369,4 @@ c40c8739bcdc88892ff58ebee3fd8a3f287be94d jdk-9+123
|
|||||||
7ff61c55b5c6c124592f09b18953222009a204a6 jdk-9+124
|
7ff61c55b5c6c124592f09b18953222009a204a6 jdk-9+124
|
||||||
073ab1d4edf5590cf1af7b6d819350c14e425c1a jdk-9+125
|
073ab1d4edf5590cf1af7b6d819350c14e425c1a jdk-9+125
|
||||||
6fda66a5bdf2da8994032b9da2078a4137f4d954 jdk-9+126
|
6fda66a5bdf2da8994032b9da2078a4137f4d954 jdk-9+126
|
||||||
|
7a97b89ba83077ca62e4aa5a05437adc8f315343 jdk-9+127
|
||||||
|
@ -693,6 +693,8 @@ public class CLDRConverter {
|
|||||||
"field.weekday",
|
"field.weekday",
|
||||||
"field.dayperiod",
|
"field.dayperiod",
|
||||||
"field.hour",
|
"field.hour",
|
||||||
|
"timezone.hourFormat",
|
||||||
|
"timezone.gmtFormat",
|
||||||
"field.minute",
|
"field.minute",
|
||||||
"field.second",
|
"field.second",
|
||||||
"field.zone",
|
"field.zone",
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -41,12 +41,12 @@ class CopyrightHeaders {
|
|||||||
" * Copyright (c) 2012, %d, Oracle and/or its affiliates. All rights reserved.\n" +
|
" * Copyright (c) 2012, %d, Oracle and/or its affiliates. All rights reserved.\n" +
|
||||||
" */\n";
|
" */\n";
|
||||||
|
|
||||||
// Last updated: - 1/16/2015, 1:42:31 PM
|
// Last updated: - 6/06/2016, 1:42:31 PM
|
||||||
private static final String UNICODE =
|
private static final String UNICODE =
|
||||||
"/*\n" +
|
"/*\n" +
|
||||||
" * COPYRIGHT AND PERMISSION NOTICE\n" +
|
" * COPYRIGHT AND PERMISSION NOTICE\n" +
|
||||||
" *\n" +
|
" *\n" +
|
||||||
" * Copyright (C) 1991-2015 Unicode, Inc. All rights reserved.\n" +
|
" * Copyright (C) 1991-2016 Unicode, Inc. All rights reserved.\n" +
|
||||||
" * Distributed under the Terms of Use in \n" +
|
" * Distributed under the Terms of Use in \n" +
|
||||||
" * http://www.unicode.org/copyright.html.\n" +
|
" * http://www.unicode.org/copyright.html.\n" +
|
||||||
" *\n" +
|
" *\n" +
|
||||||
|
@ -417,6 +417,12 @@ class LDMLParseHandler extends AbstractLDMLHandler<Object> {
|
|||||||
case "timeZoneNames":
|
case "timeZoneNames":
|
||||||
pushContainer(qName, attributes);
|
pushContainer(qName, attributes);
|
||||||
break;
|
break;
|
||||||
|
case "hourFormat":
|
||||||
|
pushStringEntry(qName, attributes, "timezone.hourFormat");
|
||||||
|
break;
|
||||||
|
case "gmtFormat":
|
||||||
|
pushStringEntry(qName, attributes, "timezone.gmtFormat");
|
||||||
|
break;
|
||||||
case "zone":
|
case "zone":
|
||||||
{
|
{
|
||||||
String tzid = attributes.getValue("type"); // Olson tz id
|
String tzid = attributes.getValue("type"); // Olson tz id
|
||||||
|
@ -169,7 +169,7 @@ class NTLM {
|
|||||||
|
|
||||||
byte[] readSecurityBuffer(int offset) throws NTLMException {
|
byte[] readSecurityBuffer(int offset) throws NTLMException {
|
||||||
int pos = readInt(offset+4);
|
int pos = readInt(offset+4);
|
||||||
if (pos == 0) return null;
|
if (pos == 0) return new byte[0];
|
||||||
try {
|
try {
|
||||||
return Arrays.copyOfRange(
|
return Arrays.copyOfRange(
|
||||||
internal, pos, pos + readShort(offset));
|
internal, pos, pos + readShort(offset));
|
||||||
|
@ -1613,6 +1613,8 @@ public final class Math {
|
|||||||
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
||||||
* computed, as if with unlimited range and precision, and rounded
|
* computed, as if with unlimited range and precision, and rounded
|
||||||
* once to the nearest {@code double} value
|
* once to the nearest {@code double} value
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
*/
|
*/
|
||||||
// @HotSpotIntrinsicCandidate
|
// @HotSpotIntrinsicCandidate
|
||||||
public static double fma(double a, double b, double c) {
|
public static double fma(double a, double b, double c) {
|
||||||
@ -1728,6 +1730,8 @@ public final class Math {
|
|||||||
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
||||||
* computed, as if with unlimited range and precision, and rounded
|
* computed, as if with unlimited range and precision, and rounded
|
||||||
* once to the nearest {@code float} value
|
* once to the nearest {@code float} value
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
*/
|
*/
|
||||||
// @HotSpotIntrinsicCandidate
|
// @HotSpotIntrinsicCandidate
|
||||||
public static float fma(float a, float b, float c) {
|
public static float fma(float a, float b, float c) {
|
||||||
|
@ -1276,6 +1276,8 @@ public final class StrictMath {
|
|||||||
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
||||||
* computed, as if with unlimited range and precision, and rounded
|
* computed, as if with unlimited range and precision, and rounded
|
||||||
* once to the nearest {@code double} value
|
* once to the nearest {@code double} value
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
*/
|
*/
|
||||||
public static double fma(double a, double b, double c) {
|
public static double fma(double a, double b, double c) {
|
||||||
return Math.fma(a, b, c);
|
return Math.fma(a, b, c);
|
||||||
@ -1328,6 +1330,8 @@ public final class StrictMath {
|
|||||||
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
* @return (<i>a</i> × <i>b</i> + <i>c</i>)
|
||||||
* computed, as if with unlimited range and precision, and rounded
|
* computed, as if with unlimited range and precision, and rounded
|
||||||
* once to the nearest {@code float} value
|
* once to the nearest {@code float} value
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
*/
|
*/
|
||||||
public static float fma(float a, float b, float c) {
|
public static float fma(float a, float b, float c) {
|
||||||
return Math.fma(a, b, c);
|
return Math.fma(a, b, c);
|
||||||
|
@ -67,19 +67,35 @@ class VersionProps {
|
|||||||
System.setProperty("java.runtime.name", java_runtime_name);
|
System.setProperty("java.runtime.name", java_runtime_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Integer> versionNumbers() {
|
private static int parseVersionNumber(String version, int prevIndex, int index) {
|
||||||
List<Integer> versionNumbers = new ArrayList<>(4);
|
if (index - prevIndex > 1 &&
|
||||||
|
Character.digit(version.charAt(prevIndex), 10) <= 0)
|
||||||
|
throw new IllegalArgumentException("Leading zeros not supported (" +
|
||||||
|
version.substring(prevIndex, index) + ")");
|
||||||
|
return Integer.parseInt(version, prevIndex, index, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is reflectively used by regression tests.
|
||||||
|
static List<Integer> parseVersionNumbers(String version) {
|
||||||
|
List<Integer> verNumbers = new ArrayList<>(4);
|
||||||
int prevIndex = 0;
|
int prevIndex = 0;
|
||||||
int index = VERSION_NUMBER.indexOf('.');
|
int index = version.indexOf('.');
|
||||||
while (index > 0) {
|
while (index > 0) {
|
||||||
versionNumbers.add(
|
verNumbers.add(parseVersionNumber(version, prevIndex, index));
|
||||||
Integer.parseInt(VERSION_NUMBER, prevIndex, index, 10));
|
|
||||||
prevIndex = index + 1; // Skip the period
|
prevIndex = index + 1; // Skip the period
|
||||||
index = VERSION_NUMBER.indexOf('.', prevIndex);
|
index = version.indexOf('.', prevIndex);
|
||||||
}
|
}
|
||||||
versionNumbers.add(Integer.parseInt(VERSION_NUMBER,
|
verNumbers.add(parseVersionNumber(version, prevIndex, version.length()));
|
||||||
prevIndex, VERSION_NUMBER.length(), 10));
|
|
||||||
return versionNumbers;
|
if (verNumbers.get(0) == 0 || verNumbers.get(verNumbers.size() - 1) == 0)
|
||||||
|
throw new IllegalArgumentException("Leading/trailing zeros not supported (" +
|
||||||
|
verNumbers + ")");
|
||||||
|
|
||||||
|
return verNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<Integer> versionNumbers() {
|
||||||
|
return parseVersionNumbers(VERSION_NUMBER);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Optional<String> pre() {
|
static Optional<String> pre() {
|
||||||
|
@ -523,7 +523,7 @@ class ModulePath implements ConfigurableModuleFinder {
|
|||||||
try (JarFile jf = new JarFile(file.toFile(),
|
try (JarFile jf = new JarFile(file.toFile(),
|
||||||
true, // verify
|
true, // verify
|
||||||
ZipFile.OPEN_READ,
|
ZipFile.OPEN_READ,
|
||||||
JarFile.Release.RUNTIME))
|
JarFile.runtimeVersion()))
|
||||||
{
|
{
|
||||||
ModuleDescriptor md;
|
ModuleDescriptor md;
|
||||||
JarEntry entry = jf.getJarEntry(MODULE_INFO);
|
JarEntry entry = jf.getJarEntry(MODULE_INFO);
|
||||||
|
@ -201,7 +201,7 @@ class ModuleReferences {
|
|||||||
return new JarFile(path.toFile(),
|
return new JarFile(path.toFile(),
|
||||||
true, // verify
|
true, // verify
|
||||||
ZipFile.OPEN_READ,
|
ZipFile.OPEN_READ,
|
||||||
JarFile.Release.RUNTIME);
|
JarFile.runtimeVersion());
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new UncheckedIOException(ioe);
|
throw new UncheckedIOException(ioe);
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -59,9 +59,11 @@ import sun.security.util.SecurityConstants;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class loader is used to load classes and resources from a search
|
* This class loader is used to load classes and resources from a search
|
||||||
* path of URLs referring to both JAR files and directories. Any URL that
|
* path of URLs referring to both JAR files and directories. Any {@code jar:}
|
||||||
* ends with a '/' is assumed to refer to a directory. Otherwise, the URL
|
* scheme URL (see {@link java.net.JarURLConnection}) is assumed to refer to a
|
||||||
* is assumed to refer to a JAR file which will be opened as needed.
|
* JAR file. Any {@code file:} scheme URL that ends with a '/' is assumed to
|
||||||
|
* refer to a directory. Otherwise, the URL is assumed to refer to a JAR file
|
||||||
|
* which will be opened as needed.
|
||||||
* <p>
|
* <p>
|
||||||
* The AccessControlContext of the thread that created the instance of
|
* The AccessControlContext of the thread that created the instance of
|
||||||
* URLClassLoader will be used when subsequently loading classes and
|
* URLClassLoader will be used when subsequently loading classes and
|
||||||
@ -83,9 +85,11 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
|
|||||||
/**
|
/**
|
||||||
* Constructs a new URLClassLoader for the given URLs. The URLs will be
|
* Constructs a new URLClassLoader for the given URLs. The URLs will be
|
||||||
* searched in the order specified for classes and resources after first
|
* searched in the order specified for classes and resources after first
|
||||||
* searching in the specified parent class loader. Any URL that ends with
|
* searching in the specified parent class loader. Any {@code jar:}
|
||||||
* a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
|
* scheme URL is assumed to refer to a JAR file. Any {@code file:} scheme
|
||||||
* to refer to a JAR file which will be downloaded and opened as needed.
|
* URL that ends with a '/' is assumed to refer to a directory. Otherwise,
|
||||||
|
* the URL is assumed to refer to a JAR file which will be downloaded and
|
||||||
|
* opened as needed.
|
||||||
*
|
*
|
||||||
* <p>If there is a security manager, this method first
|
* <p>If there is a security manager, this method first
|
||||||
* calls the security manager's {@code checkCreateClassLoader} method
|
* calls the security manager's {@code checkCreateClassLoader} method
|
||||||
|
@ -3290,8 +3290,8 @@ public final class Files {
|
|||||||
* a size of {@code 0}. All bytes in the byte array are written to the file.
|
* a size of {@code 0}. All bytes in the byte array are written to the file.
|
||||||
* The method ensures that the file is closed when all bytes have been
|
* The method ensures that the file is closed when all bytes have been
|
||||||
* written (or an I/O error or other runtime exception is thrown). If an I/O
|
* written (or an I/O error or other runtime exception is thrown). If an I/O
|
||||||
* error occurs then it may do so after the file has created or truncated,
|
* error occurs then it may do so after the file has been created or
|
||||||
* or after some bytes have been written to the file.
|
* truncated, or after some bytes have been written to the file.
|
||||||
*
|
*
|
||||||
* <p> <b>Usage example</b>: By default the method creates a new file or
|
* <p> <b>Usage example</b>: By default the method creates a new file or
|
||||||
* overwrites an existing file. Suppose you instead want to append bytes
|
* overwrites an existing file. Suppose you instead want to append bytes
|
||||||
@ -3360,7 +3360,8 @@ public final class Files {
|
|||||||
* a size of {@code 0}. The method ensures that the file is closed when all
|
* a size of {@code 0}. The method ensures that the file is closed when all
|
||||||
* lines have been written (or an I/O error or other runtime exception is
|
* lines have been written (or an I/O error or other runtime exception is
|
||||||
* thrown). If an I/O error occurs then it may do so after the file has
|
* thrown). If an I/O error occurs then it may do so after the file has
|
||||||
* created or truncated, or after some bytes have been written to the file.
|
* been created or truncated, or after some bytes have been written to the
|
||||||
|
* file.
|
||||||
*
|
*
|
||||||
* @param path
|
* @param path
|
||||||
* the path to the file
|
* the path to the file
|
||||||
|
@ -439,7 +439,12 @@ public abstract class MessageDigest extends MessageDigestSpi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares two digests for equality. Does a simple byte compare.
|
* Compares two digests for equality. Two digests are equal if they have
|
||||||
|
* the same length and all bytes at corresponding positions are equal.
|
||||||
|
*
|
||||||
|
* @implNote
|
||||||
|
* If the digests are the same length, all bytes are examined to
|
||||||
|
* determine equality.
|
||||||
*
|
*
|
||||||
* @param digesta one of the digests to compare.
|
* @param digesta one of the digests to compare.
|
||||||
*
|
*
|
||||||
|
@ -64,8 +64,8 @@ import sun.security.util.SignatureFileVerifier;
|
|||||||
* file, and as such an entry name is associated with at most one base entry.
|
* file, and as such an entry name is associated with at most one base entry.
|
||||||
* The {@code JarFile} may be configured to process a multi-release jar file by
|
* The {@code JarFile} may be configured to process a multi-release jar file by
|
||||||
* creating the {@code JarFile} with the
|
* creating the {@code JarFile} with the
|
||||||
* {@link JarFile#JarFile(File, boolean, int, Release)} constructor. The
|
* {@link JarFile#JarFile(File, boolean, int, Runtime.Version)} constructor. The
|
||||||
* {@code Release} object sets a maximum version used when searching for
|
* {@code Runtime.Version} object sets a maximum version used when searching for
|
||||||
* versioned entries. When so configured, an entry name
|
* versioned entries. When so configured, an entry name
|
||||||
* can correspond with at most one base entry and zero or more versioned
|
* can correspond with at most one base entry and zero or more versioned
|
||||||
* entries. A search is required to associate the entry name with the latest
|
* entries. A search is required to associate the entry name with the latest
|
||||||
@ -74,8 +74,8 @@ import sun.security.util.SignatureFileVerifier;
|
|||||||
*
|
*
|
||||||
* <p>Class loaders that utilize {@code JarFile} to load classes from the
|
* <p>Class loaders that utilize {@code JarFile} to load classes from the
|
||||||
* contents of {@code JarFile} entries should construct the {@code JarFile}
|
* contents of {@code JarFile} entries should construct the {@code JarFile}
|
||||||
* by invoking the {@link JarFile#JarFile(File, boolean, int, Release)}
|
* by invoking the {@link JarFile#JarFile(File, boolean, int, Runtime.Version)}
|
||||||
* constructor with the value {@code Release.RUNTIME} assigned to the last
|
* constructor with the value {@code Runtime.version()} assigned to the last
|
||||||
* argument. This assures that classes compatible with the major
|
* argument. This assures that classes compatible with the major
|
||||||
* version of the running JVM are loaded from multi-release jar files.
|
* version of the running JVM are loaded from multi-release jar files.
|
||||||
*
|
*
|
||||||
@ -99,12 +99,12 @@ import sun.security.util.SignatureFileVerifier;
|
|||||||
* <li>
|
* <li>
|
||||||
* {@code jdk.util.jar.version} can be assigned a value that is the
|
* {@code jdk.util.jar.version} can be assigned a value that is the
|
||||||
* {@code String} representation of a non-negative integer
|
* {@code String} representation of a non-negative integer
|
||||||
* {@code <= Version.current().major()}. The value is used to set the effective
|
* {@code <= Runtime.version().major()}. The value is used to set the effective
|
||||||
* runtime version to something other than the default value obtained by
|
* runtime version to something other than the default value obtained by
|
||||||
* evaluating {@code Version.current().major()}. The effective runtime version
|
* evaluating {@code Runtime.version().major()}. The effective runtime version
|
||||||
* is the version that the {@link JarFile#JarFile(File, boolean, int, Release)}
|
* is the version that the {@link JarFile#JarFile(File, boolean, int, Runtime.Version)}
|
||||||
* constructor uses when the value of the last argument is
|
* constructor uses when the value of the last argument is
|
||||||
* {@code Release.RUNTIME}.
|
* {@code JarFile.runtimeVersion()}.
|
||||||
* </li>
|
* </li>
|
||||||
* <li>
|
* <li>
|
||||||
* {@code jdk.util.jar.enableMultiRelease} can be assigned one of the three
|
* {@code jdk.util.jar.enableMultiRelease} can be assigned one of the three
|
||||||
@ -116,7 +116,7 @@ import sun.security.util.SignatureFileVerifier;
|
|||||||
* the method {@link JarFile#isMultiRelease()} returns <em>false</em>. The value
|
* the method {@link JarFile#isMultiRelease()} returns <em>false</em>. The value
|
||||||
* <em>force</em> causes the {@code JarFile} to be initialized to runtime
|
* <em>force</em> causes the {@code JarFile} to be initialized to runtime
|
||||||
* versioning after construction. It effectively does the same as this code:
|
* versioning after construction. It effectively does the same as this code:
|
||||||
* {@code (new JarFile(File, boolean, int, Release.RUNTIME)}.
|
* {@code (new JarFile(File, boolean, int, JarFile.runtimeVersion())}.
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* </div>
|
* </div>
|
||||||
@ -129,8 +129,9 @@ import sun.security.util.SignatureFileVerifier;
|
|||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class JarFile extends ZipFile {
|
class JarFile extends ZipFile {
|
||||||
private final static int BASE_VERSION;
|
private final static Runtime.Version BASE_VERSION;
|
||||||
private final static int RUNTIME_VERSION;
|
private final static int BASE_VERSION_MAJOR;
|
||||||
|
private final static Runtime.Version RUNTIME_VERSION;
|
||||||
private final static boolean MULTI_RELEASE_ENABLED;
|
private final static boolean MULTI_RELEASE_ENABLED;
|
||||||
private final static boolean MULTI_RELEASE_FORCED;
|
private final static boolean MULTI_RELEASE_FORCED;
|
||||||
private SoftReference<Manifest> manRef;
|
private SoftReference<Manifest> manRef;
|
||||||
@ -138,10 +139,10 @@ class JarFile extends ZipFile {
|
|||||||
private JarVerifier jv;
|
private JarVerifier jv;
|
||||||
private boolean jvInitialized;
|
private boolean jvInitialized;
|
||||||
private boolean verify;
|
private boolean verify;
|
||||||
private final int version;
|
private final Runtime.Version version; // current version
|
||||||
private boolean notVersioned;
|
private final int versionMajor; // version.major()
|
||||||
private final boolean runtimeVersioned;
|
private boolean notVersioned; // legacy constructor called
|
||||||
private boolean isMultiRelease; // is jar multi-release?
|
private boolean isMultiRelease; // is jar multi-release?
|
||||||
|
|
||||||
// indicates if Class-Path attribute present
|
// indicates if Class-Path attribute present
|
||||||
private boolean hasClassPathAttribute;
|
private boolean hasClassPathAttribute;
|
||||||
@ -151,17 +152,18 @@ class JarFile extends ZipFile {
|
|||||||
static {
|
static {
|
||||||
// Set up JavaUtilJarAccess in SharedSecrets
|
// Set up JavaUtilJarAccess in SharedSecrets
|
||||||
SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
|
SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
|
||||||
|
// multi-release jar file versions >= 9
|
||||||
BASE_VERSION = 8; // one less than lowest version for versioned entries
|
BASE_VERSION = Runtime.Version.parse(Integer.toString(8));
|
||||||
|
BASE_VERSION_MAJOR = BASE_VERSION.major();
|
||||||
|
String jarVersion = GetPropertyAction.privilegedGetProperty("jdk.util.jar.version");
|
||||||
int runtimeVersion = Runtime.version().major();
|
int runtimeVersion = Runtime.version().major();
|
||||||
String jarVersion =
|
|
||||||
GetPropertyAction.privilegedGetProperty("jdk.util.jar.version");
|
|
||||||
if (jarVersion != null) {
|
if (jarVersion != null) {
|
||||||
int jarVer = Integer.parseInt(jarVersion);
|
int jarVer = Integer.parseInt(jarVersion);
|
||||||
runtimeVersion = (jarVer > runtimeVersion)
|
runtimeVersion = (jarVer > runtimeVersion)
|
||||||
? runtimeVersion : Math.max(jarVer, 0);
|
? runtimeVersion
|
||||||
|
: Math.max(jarVer, BASE_VERSION_MAJOR);
|
||||||
}
|
}
|
||||||
RUNTIME_VERSION = runtimeVersion;
|
RUNTIME_VERSION = Runtime.Version.parse(Integer.toString(runtimeVersion));
|
||||||
String enableMultiRelease = GetPropertyAction
|
String enableMultiRelease = GetPropertyAction
|
||||||
.privilegedGetProperty("jdk.util.jar.enableMultiRelease", "true");
|
.privilegedGetProperty("jdk.util.jar.enableMultiRelease", "true");
|
||||||
switch (enableMultiRelease) {
|
switch (enableMultiRelease) {
|
||||||
@ -181,61 +183,6 @@ class JarFile extends ZipFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A set of constants that represent the entries in either the base directory
|
|
||||||
* or one of the versioned directories in a multi-release jar file. It's
|
|
||||||
* possible for a multi-release jar file to contain versioned directories
|
|
||||||
* that are not represented by the constants of the {@code Release} enum.
|
|
||||||
* In those cases, the entries will not be located by this {@code JarFile}
|
|
||||||
* through the aliasing mechanism, but they can be directly accessed by
|
|
||||||
* specifying the full path name of the entry.
|
|
||||||
*
|
|
||||||
* @since 9
|
|
||||||
*/
|
|
||||||
public enum Release {
|
|
||||||
/**
|
|
||||||
* Represents unversioned entries, or entries in "regular", as opposed
|
|
||||||
* to multi-release jar files.
|
|
||||||
*/
|
|
||||||
BASE(BASE_VERSION),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents entries found in the META-INF/versions/9 directory of a
|
|
||||||
* multi-release jar file.
|
|
||||||
*/
|
|
||||||
VERSION_9(9),
|
|
||||||
|
|
||||||
// fill in the "blanks" for future releases
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents entries found in the META-INF/versions/{n} directory of a
|
|
||||||
* multi-release jar file, where {@code n} is the effective runtime
|
|
||||||
* version of the jar file.
|
|
||||||
*
|
|
||||||
* @implNote
|
|
||||||
* <div class="block">
|
|
||||||
* The effective runtime version is determined
|
|
||||||
* by evaluating {@code Version.current().major()} or by using the value
|
|
||||||
* of the {@code jdk.util.jar.version} System property if it exists.
|
|
||||||
* </div>
|
|
||||||
*/
|
|
||||||
RUNTIME(RUNTIME_VERSION);
|
|
||||||
|
|
||||||
Release(int version) {
|
|
||||||
this.version = version;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Release valueOf(int version) {
|
|
||||||
return version <= BASE.value() ? BASE : valueOf("VERSION_" + version);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int version;
|
|
||||||
|
|
||||||
private int value() {
|
|
||||||
return this.version;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String META_INF = "META-INF/";
|
private static final String META_INF = "META-INF/";
|
||||||
|
|
||||||
private static final String META_INF_VERSIONS = META_INF + "versions/";
|
private static final String META_INF_VERSIONS = META_INF + "versions/";
|
||||||
@ -245,6 +192,32 @@ class JarFile extends ZipFile {
|
|||||||
*/
|
*/
|
||||||
public static final String MANIFEST_NAME = META_INF + "MANIFEST.MF";
|
public static final String MANIFEST_NAME = META_INF + "MANIFEST.MF";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version that represents the unversioned configuration of a multi-release jar file.
|
||||||
|
*
|
||||||
|
* @return Runtime.Version that represents the unversioned configuration
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static Runtime.Version baseVersion() {
|
||||||
|
return BASE_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The version that represents the effective runtime versioned configuration of a
|
||||||
|
* multi-release jar file. In most cases, {@code runtimeVersion()} is equal to
|
||||||
|
* {@code Runtime.version()}. However, if the {@code jdk.util.jar.version} property is set,
|
||||||
|
* {@code runtimeVersion()} is derived from that property and may not be equal to
|
||||||
|
* {@code Runtime.version()}.
|
||||||
|
*
|
||||||
|
* @return Runtime.Version that represents the runtime versioned configuration
|
||||||
|
*
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static Runtime.Version runtimeVersion() {
|
||||||
|
return RUNTIME_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@code JarFile} to read from the specified
|
* Creates a new {@code JarFile} to read from the specified
|
||||||
* file {@code name}. The {@code JarFile} will be verified if
|
* file {@code name}. The {@code JarFile} will be verified if
|
||||||
@ -316,7 +289,7 @@ class JarFile extends ZipFile {
|
|||||||
* @since 1.3
|
* @since 1.3
|
||||||
*/
|
*/
|
||||||
public JarFile(File file, boolean verify, int mode) throws IOException {
|
public JarFile(File file, boolean verify, int mode) throws IOException {
|
||||||
this(file, verify, mode, Release.BASE);
|
this(file, verify, mode, BASE_VERSION);
|
||||||
this.notVersioned = true;
|
this.notVersioned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,8 +297,13 @@ class JarFile extends ZipFile {
|
|||||||
* Creates a new {@code JarFile} to read from the specified
|
* Creates a new {@code JarFile} to read from the specified
|
||||||
* {@code File} object in the specified mode. The mode argument
|
* {@code File} object in the specified mode. The mode argument
|
||||||
* must be either {@code OPEN_READ} or {@code OPEN_READ | OPEN_DELETE}.
|
* must be either {@code OPEN_READ} or {@code OPEN_READ | OPEN_DELETE}.
|
||||||
* The version argument configures the {@code JarFile} for processing
|
* The version argument, after being converted to a canonical form, is
|
||||||
|
* used to configure the {@code JarFile} for processing
|
||||||
* multi-release jar files.
|
* multi-release jar files.
|
||||||
|
* <p>
|
||||||
|
* The canonical form derived from the version parameter is
|
||||||
|
* {@code Runtime.Version.parse(Integer.toString(n))} where {@code n} is
|
||||||
|
* {@code Math.max(version.major(), JarFile.baseVersion().major())}.
|
||||||
*
|
*
|
||||||
* @param file the jar file to be opened for reading
|
* @param file the jar file to be opened for reading
|
||||||
* @param verify whether or not to verify the jar file if
|
* @param verify whether or not to verify the jar file if
|
||||||
@ -340,47 +318,31 @@ class JarFile extends ZipFile {
|
|||||||
* @throws NullPointerException if {@code version} is {@code null}
|
* @throws NullPointerException if {@code version} is {@code null}
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
public JarFile(File file, boolean verify, int mode, Release version) throws IOException {
|
public JarFile(File file, boolean verify, int mode, Runtime.Version version) throws IOException {
|
||||||
super(file, mode);
|
super(file, mode);
|
||||||
Objects.requireNonNull(version);
|
|
||||||
this.verify = verify;
|
this.verify = verify;
|
||||||
// version applies to multi-release jar files, ignored for regular jar files
|
Objects.requireNonNull(version);
|
||||||
if (MULTI_RELEASE_FORCED) {
|
if (MULTI_RELEASE_FORCED || version.major() == RUNTIME_VERSION.major()) {
|
||||||
|
// This deals with the common case where the value from JarFile.runtimeVersion() is passed
|
||||||
this.version = RUNTIME_VERSION;
|
this.version = RUNTIME_VERSION;
|
||||||
version = Release.RUNTIME;
|
} else if (version.major() <= BASE_VERSION_MAJOR) {
|
||||||
|
// This also deals with the common case where the value from JarFile.baseVersion() is passed
|
||||||
|
this.version = BASE_VERSION;
|
||||||
} else {
|
} else {
|
||||||
this.version = version.value();
|
// Canonicalize
|
||||||
}
|
this.version = Runtime.Version.parse(Integer.toString(version.major()));
|
||||||
this.runtimeVersioned = version == Release.RUNTIME;
|
|
||||||
|
|
||||||
assert runtimeVersionExists();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean runtimeVersionExists() {
|
|
||||||
int version = Runtime.version().major();
|
|
||||||
try {
|
|
||||||
Release.valueOf(version);
|
|
||||||
return true;
|
|
||||||
} catch (IllegalArgumentException x) {
|
|
||||||
System.err.println("No JarFile.Release object for release " + version);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
this.versionMajor = this.version.major();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the maximum version used when searching for versioned entries.
|
* Returns the maximum version used when searching for versioned entries.
|
||||||
*
|
*
|
||||||
* @return the maximum version, or {@code Release.BASE} if this jar file is
|
* @return the maximum version
|
||||||
* processed as if it is an unversioned jar file or is not a
|
|
||||||
* multi-release jar file
|
|
||||||
* @since 9
|
* @since 9
|
||||||
*/
|
*/
|
||||||
public final Release getVersion() {
|
public final Runtime.Version getVersion() {
|
||||||
if (isMultiRelease()) {
|
return isMultiRelease() ? this.version : BASE_VERSION;
|
||||||
return runtimeVersioned ? Release.RUNTIME : Release.valueOf(version);
|
|
||||||
} else {
|
|
||||||
return Release.BASE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -393,7 +355,7 @@ class JarFile extends ZipFile {
|
|||||||
if (isMultiRelease) {
|
if (isMultiRelease) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
|
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
|
||||||
try {
|
try {
|
||||||
checkForSpecialAttributes();
|
checkForSpecialAttributes();
|
||||||
} catch (IOException io) {
|
} catch (IOException io) {
|
||||||
@ -639,7 +601,7 @@ class JarFile extends ZipFile {
|
|||||||
ZipEntry vze = null;
|
ZipEntry vze = null;
|
||||||
String sname = "/" + name;
|
String sname = "/" + name;
|
||||||
int i = version;
|
int i = version;
|
||||||
while (i > BASE_VERSION) {
|
while (i > BASE_VERSION_MAJOR) {
|
||||||
vze = super.getEntry(META_INF_VERSIONS + i + sname);
|
vze = super.getEntry(META_INF_VERSIONS + i + sname);
|
||||||
if (vze != null) break;
|
if (vze != null) break;
|
||||||
i--;
|
i--;
|
||||||
@ -649,10 +611,10 @@ class JarFile extends ZipFile {
|
|||||||
|
|
||||||
private ZipEntry getVersionedEntry(ZipEntry ze) {
|
private ZipEntry getVersionedEntry(ZipEntry ze) {
|
||||||
ZipEntry vze = null;
|
ZipEntry vze = null;
|
||||||
if (version > BASE_VERSION && !ze.isDirectory()) {
|
if (BASE_VERSION_MAJOR < versionMajor && !ze.isDirectory()) {
|
||||||
String name = ze.getName();
|
String name = ze.getName();
|
||||||
if (!name.startsWith(META_INF)) {
|
if (!name.startsWith(META_INF)) {
|
||||||
vze = searchForVersionedEntry(version, name);
|
vze = searchForVersionedEntry(versionMajor, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vze == null ? ze : vze;
|
return vze == null ? ze : vze;
|
||||||
@ -1038,7 +1000,7 @@ class JarFile extends ZipFile {
|
|||||||
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
hasClassPathAttribute = match(CLASSPATH_CHARS, b,
|
||||||
CLASSPATH_LASTOCC) != -1;
|
CLASSPATH_LASTOCC) != -1;
|
||||||
// is this a multi-release jar file
|
// is this a multi-release jar file
|
||||||
if (MULTI_RELEASE_ENABLED && version != BASE_VERSION) {
|
if (MULTI_RELEASE_ENABLED && versionMajor != BASE_VERSION_MAJOR) {
|
||||||
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
|
int i = match(MULTIRELEASE_CHARS, b, MULTIRELEASE_LASTOCC);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
i += MULTIRELEASE_CHARS.length;
|
i += MULTIRELEASE_CHARS.length;
|
||||||
|
@ -179,6 +179,10 @@ class InflaterInputStream extends FilterInputStream {
|
|||||||
ensureOpen();
|
ensureOpen();
|
||||||
if (reachEOF) {
|
if (reachEOF) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (inf.finished()) {
|
||||||
|
// the end of the compressed data stream has been reached
|
||||||
|
reachEOF = true;
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -695,7 +695,7 @@ public class URLClassPath {
|
|||||||
throw new FileNotFoundException(p.getPath());
|
throw new FileNotFoundException(p.getPath());
|
||||||
}
|
}
|
||||||
return checkJar(new JarFile(new File(p.getPath()), true, ZipFile.OPEN_READ,
|
return checkJar(new JarFile(new File(p.getPath()), true, ZipFile.OPEN_READ,
|
||||||
JarFile.Release.RUNTIME));
|
JarFile.runtimeVersion()));
|
||||||
}
|
}
|
||||||
URLConnection uc = (new URL(getBaseURL(), "#runtime")).openConnection();
|
URLConnection uc = (new URL(getBaseURL(), "#runtime")).openConnection();
|
||||||
uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
|
uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION);
|
||||||
|
@ -66,7 +66,9 @@ public class URLJarFile extends JarFile {
|
|||||||
|
|
||||||
static JarFile getJarFile(URL url, URLJarFileCloseController closeController) throws IOException {
|
static JarFile getJarFile(URL url, URLJarFileCloseController closeController) throws IOException {
|
||||||
if (isFileURL(url)) {
|
if (isFileURL(url)) {
|
||||||
Release version = "runtime".equals(url.getRef()) ? Release.RUNTIME : Release.BASE;
|
Runtime.Version version = "runtime".equals(url.getRef())
|
||||||
|
? JarFile.runtimeVersion()
|
||||||
|
: JarFile.baseVersion();
|
||||||
return new URLJarFile(url, closeController, version);
|
return new URLJarFile(url, closeController, version);
|
||||||
} else {
|
} else {
|
||||||
return retrieve(url, closeController);
|
return retrieve(url, closeController);
|
||||||
@ -90,12 +92,14 @@ public class URLJarFile extends JarFile {
|
|||||||
this.closeController = closeController;
|
this.closeController = closeController;
|
||||||
}
|
}
|
||||||
|
|
||||||
private URLJarFile(File file, URLJarFileCloseController closeController, Release version) throws IOException {
|
private URLJarFile(File file, URLJarFileCloseController closeController, Runtime.Version version)
|
||||||
|
throws IOException {
|
||||||
super(file, true, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE, version);
|
super(file, true, ZipFile.OPEN_READ | ZipFile.OPEN_DELETE, version);
|
||||||
this.closeController = closeController;
|
this.closeController = closeController;
|
||||||
}
|
}
|
||||||
|
|
||||||
private URLJarFile(URL url, URLJarFileCloseController closeController, Release version) throws IOException {
|
private URLJarFile(URL url, URLJarFileCloseController closeController, Runtime.Version version)
|
||||||
|
throws IOException {
|
||||||
super(new File(ParseUtil.decode(url.getFile())), true, ZipFile.OPEN_READ, version);
|
super(new File(ParseUtil.decode(url.getFile())), true, ZipFile.OPEN_READ, version);
|
||||||
this.closeController = closeController;
|
this.closeController = closeController;
|
||||||
}
|
}
|
||||||
@ -200,7 +204,9 @@ public class URLJarFile extends JarFile {
|
|||||||
{
|
{
|
||||||
|
|
||||||
JarFile result = null;
|
JarFile result = null;
|
||||||
Release version = "runtime".equals(url.getRef()) ? Release.RUNTIME : Release.BASE;
|
Runtime.Version version = "runtime".equals(url.getRef())
|
||||||
|
? JarFile.runtimeVersion()
|
||||||
|
: JarFile.baseVersion();
|
||||||
|
|
||||||
/* get the stream before asserting privileges */
|
/* get the stream before asserting privileges */
|
||||||
try (final InputStream in = url.openConnection().getInputStream()) {
|
try (final InputStream in = url.openConnection().getInputStream()) {
|
||||||
|
@ -38,6 +38,8 @@ import java.net.URL;
|
|||||||
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
|
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.Security;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.text.Collator;
|
import java.text.Collator;
|
||||||
|
|
||||||
@ -46,6 +48,7 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
|
||||||
import sun.security.util.PropertyExpander;
|
import sun.security.util.PropertyExpander;
|
||||||
|
|
||||||
@ -209,6 +212,7 @@ public class KeyStoreUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepends matched options from a pre-configured options file.
|
* Prepends matched options from a pre-configured options file.
|
||||||
|
*
|
||||||
* @param tool the name of the tool, can be "keytool" or "jarsigner"
|
* @param tool the name of the tool, can be "keytool" or "jarsigner"
|
||||||
* @param file the pre-configured options file
|
* @param file the pre-configured options file
|
||||||
* @param c1 the name of the command, with the "-" prefix,
|
* @param c1 the name of the command, with the "-" prefix,
|
||||||
@ -259,4 +263,68 @@ public class KeyStoreUtil {
|
|||||||
return result.toArray(new String[result.size()]);
|
return result.toArray(new String[result.size()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a security provider as a service.
|
||||||
|
*
|
||||||
|
* @param provName the name
|
||||||
|
* @param arg optional arg
|
||||||
|
* @throws IllegalArgumentException if no provider matches the name
|
||||||
|
*/
|
||||||
|
public static void loadProviderByName(String provName, String arg) {
|
||||||
|
Provider loaded = Security.getProvider(provName);
|
||||||
|
if (loaded != null) {
|
||||||
|
if (arg != null) {
|
||||||
|
loaded = loaded.configure(arg);
|
||||||
|
Security.addProvider(loaded);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Provider p : ServiceLoader.load(Provider.class,
|
||||||
|
ClassLoader.getSystemClassLoader())) {
|
||||||
|
if (p.getName().equals(provName)) {
|
||||||
|
if (arg != null) {
|
||||||
|
p = p.configure(arg);
|
||||||
|
}
|
||||||
|
Security.addProvider(p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No provider found");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a security provider by a fully-qualified class name.
|
||||||
|
*
|
||||||
|
* @param provClass the class name
|
||||||
|
* @param arg optional arg
|
||||||
|
* @param cl optional class loader
|
||||||
|
* @throws IllegalArgumentException if no provider matches the class name
|
||||||
|
* @throws ClassCastException if the class has not extended Provider
|
||||||
|
*/
|
||||||
|
public static void loadProviderByClass(
|
||||||
|
String provClass, String arg, ClassLoader cl) {
|
||||||
|
|
||||||
|
// For compatibility, SunPKCS11 and OracleUcrypto can still be
|
||||||
|
// loadable with -providerClass.
|
||||||
|
if (provClass.equals("sun.security.pkcs11.SunPKCS11")) {
|
||||||
|
loadProviderByName("SunPKCS11", arg);
|
||||||
|
return;
|
||||||
|
} else if (provClass.equals("com.oracle.security.crypto.UcryptoProvider")) {
|
||||||
|
loadProviderByName("OracleUcrypto", arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Provider prov;
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName(provClass, false, cl);
|
||||||
|
prov = (Provider) clazz.getConstructor().newInstance();
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
if (arg != null) {
|
||||||
|
prov = prov.configure(arg);
|
||||||
|
}
|
||||||
|
Security.addProvider(prov);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,11 @@ import java.security.MessageDigest;
|
|||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.Security;
|
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.security.Timestamp;
|
import java.security.Timestamp;
|
||||||
import java.security.UnrecoverableEntryException;
|
import java.security.UnrecoverableEntryException;
|
||||||
import java.security.UnrecoverableKeyException;
|
import java.security.UnrecoverableKeyException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.security.Provider;
|
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.CertStoreException;
|
import java.security.cert.CertStoreException;
|
||||||
@ -128,6 +126,7 @@ public final class Main {
|
|||||||
// them through the command line.
|
// them through the command line.
|
||||||
|
|
||||||
private Set<Pair <String, String>> providers = null;
|
private Set<Pair <String, String>> providers = null;
|
||||||
|
private Set<Pair <String, String>> providerClasses = null;
|
||||||
private String storetype = null;
|
private String storetype = null;
|
||||||
private boolean hasStoretypeOption = false;
|
private boolean hasStoretypeOption = false;
|
||||||
private String srcProviderName = null;
|
private String srcProviderName = null;
|
||||||
@ -166,57 +165,57 @@ public final class Main {
|
|||||||
enum Command {
|
enum Command {
|
||||||
CERTREQ("Generates.a.certificate.request",
|
CERTREQ("Generates.a.certificate.request",
|
||||||
ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
|
ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
|
||||||
CHANGEALIAS("Changes.an.entry.s.alias",
|
CHANGEALIAS("Changes.an.entry.s.alias",
|
||||||
ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
|
ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
|
||||||
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
|
||||||
PROVIDERPATH, V, PROTECTED),
|
PROVIDERPATH, V, PROTECTED),
|
||||||
DELETE("Deletes.an.entry",
|
DELETE("Deletes.an.entry",
|
||||||
ALIAS, KEYSTORE, STOREPASS, STORETYPE,
|
ALIAS, KEYSTORE, STOREPASS, STORETYPE,
|
||||||
PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
|
||||||
PROVIDERPATH, V, PROTECTED),
|
PROVIDERPATH, V, PROTECTED),
|
||||||
EXPORTCERT("Exports.certificate",
|
EXPORTCERT("Exports.certificate",
|
||||||
RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
|
RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
|
||||||
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
|
||||||
PROVIDERPATH, V, PROTECTED),
|
PROVIDERPATH, V, PROTECTED),
|
||||||
GENKEYPAIR("Generates.a.key.pair",
|
GENKEYPAIR("Generates.a.key.pair",
|
||||||
ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,
|
ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,
|
||||||
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
|
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
|
||||||
GENSECKEY("Generates.a.secret.key",
|
GENSECKEY("Generates.a.secret.key",
|
||||||
ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
|
ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
|
||||||
GENCERT("Generates.certificate.from.a.certificate.request",
|
GENCERT("Generates.certificate.from.a.certificate.request",
|
||||||
RFC, INFILE, OUTFILE, ALIAS, SIGALG, DNAME,
|
RFC, INFILE, OUTFILE, ALIAS, SIGALG, DNAME,
|
||||||
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
|
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
|
||||||
IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
|
IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
|
||||||
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
|
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
|
||||||
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
|
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
|
||||||
PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
|
||||||
PROVIDERPATH, V),
|
PROVIDERPATH, V),
|
||||||
IMPORTPASS("Imports.a.password",
|
IMPORTPASS("Imports.a.password",
|
||||||
ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
|
ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
|
||||||
IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
|
IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
|
||||||
SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
|
SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
|
||||||
DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
|
DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
|
||||||
SRCPROTECTED, DESTPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
|
SRCPROTECTED, DESTPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
|
||||||
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
|
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
|
||||||
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
|
NOPROMPT, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH,
|
||||||
V),
|
V),
|
||||||
KEYPASSWD("Changes.the.key.password.of.an.entry",
|
KEYPASSWD("Changes.the.key.password.of.an.entry",
|
||||||
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
|
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
|
||||||
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
|
||||||
PROVIDERPATH, V),
|
PROVIDERPATH, V),
|
||||||
LIST("Lists.entries.in.a.keystore",
|
LIST("Lists.entries.in.a.keystore",
|
||||||
RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
|
RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
|
||||||
PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
|
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
|
||||||
PROVIDERPATH, V, PROTECTED),
|
PROVIDERPATH, V, PROTECTED),
|
||||||
PRINTCERT("Prints.the.content.of.a.certificate",
|
PRINTCERT("Prints.the.content.of.a.certificate",
|
||||||
RFC, FILEIN, SSLSERVER, JARFILE, V),
|
RFC, FILEIN, SSLSERVER, JARFILE, V),
|
||||||
@ -226,26 +225,26 @@ public final class Main {
|
|||||||
FILEIN, V),
|
FILEIN, V),
|
||||||
STOREPASSWD("Changes.the.store.password.of.a.keystore",
|
STOREPASSWD("Changes.the.store.password.of.a.keystore",
|
||||||
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
|
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
|
||||||
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
|
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
|
||||||
|
|
||||||
// Undocumented start here, KEYCLONE is used a marker in -help;
|
// Undocumented start here, KEYCLONE is used a marker in -help;
|
||||||
|
|
||||||
KEYCLONE("Clones.a.key.entry",
|
KEYCLONE("Clones.a.key.entry",
|
||||||
ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
|
ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
|
||||||
KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
|
KEYSTORE, STOREPASS, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V),
|
PROVIDERCLASS, PROVIDERPATH, V),
|
||||||
SELFCERT("Generates.a.self.signed.certificate",
|
SELFCERT("Generates.a.self.signed.certificate",
|
||||||
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
|
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
|
||||||
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
||||||
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
|
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
|
||||||
GENCRL("Generates.CRL",
|
GENCRL("Generates.CRL",
|
||||||
RFC, FILEOUT, ID,
|
RFC, FILEOUT, ID,
|
||||||
ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
|
ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
|
||||||
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
|
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
|
||||||
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
|
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
|
||||||
IDENTITYDB("Imports.entries.from.a.JDK.1.1.x.style.identity.database",
|
IDENTITYDB("Imports.entries.from.a.JDK.1.1.x.style.identity.database",
|
||||||
FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
|
||||||
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
|
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V);
|
||||||
|
|
||||||
final String description;
|
final String description;
|
||||||
final Option[] options;
|
final Option[] options;
|
||||||
@ -289,48 +288,48 @@ public final class Main {
|
|||||||
|
|
||||||
enum Option {
|
enum Option {
|
||||||
ALIAS("alias", "<alias>", "alias.name.of.the.entry.to.process"),
|
ALIAS("alias", "<alias>", "alias.name.of.the.entry.to.process"),
|
||||||
DESTALIAS("destalias", "<destalias>", "destination.alias"),
|
DESTALIAS("destalias", "<alias>", "destination.alias"),
|
||||||
DESTKEYPASS("destkeypass", "<arg>", "destination.key.password"),
|
DESTKEYPASS("destkeypass", "<arg>", "destination.key.password"),
|
||||||
DESTKEYSTORE("destkeystore", "<destkeystore>", "destination.keystore.name"),
|
DESTKEYSTORE("destkeystore", "<keystore>", "destination.keystore.name"),
|
||||||
DESTPROTECTED("destprotected", null, "destination.keystore.password.protected"),
|
DESTPROTECTED("destprotected", null, "destination.keystore.password.protected"),
|
||||||
DESTPROVIDERNAME("destprovidername", "<destprovidername>", "destination.keystore.provider.name"),
|
DESTPROVIDERNAME("destprovidername", "<name>", "destination.keystore.provider.name"),
|
||||||
DESTSTOREPASS("deststorepass", "<arg>", "destination.keystore.password"),
|
DESTSTOREPASS("deststorepass", "<arg>", "destination.keystore.password"),
|
||||||
DESTSTORETYPE("deststoretype", "<deststoretype>", "destination.keystore.type"),
|
DESTSTORETYPE("deststoretype", "<type>", "destination.keystore.type"),
|
||||||
DNAME("dname", "<dname>", "distinguished.name"),
|
DNAME("dname", "<name>", "distinguished.name"),
|
||||||
EXT("ext", "<value>", "X.509.extension"),
|
EXT("ext", "<value>", "X.509.extension"),
|
||||||
FILEOUT("file", "<filename>", "output.file.name"),
|
FILEOUT("file", "<file>", "output.file.name"),
|
||||||
FILEIN("file", "<filename>", "input.file.name"),
|
FILEIN("file", "<file>", "input.file.name"),
|
||||||
ID("id", "<id:reason>", "Serial.ID.of.cert.to.revoke"),
|
ID("id", "<id:reason>", "Serial.ID.of.cert.to.revoke"),
|
||||||
INFILE("infile", "<filename>", "input.file.name"),
|
INFILE("infile", "<file>", "input.file.name"),
|
||||||
KEYALG("keyalg", "<keyalg>", "key.algorithm.name"),
|
KEYALG("keyalg", "<alg>", "key.algorithm.name"),
|
||||||
KEYPASS("keypass", "<arg>", "key.password"),
|
KEYPASS("keypass", "<arg>", "key.password"),
|
||||||
KEYSIZE("keysize", "<keysize>", "key.bit.size"),
|
KEYSIZE("keysize", "<size>", "key.bit.size"),
|
||||||
KEYSTORE("keystore", "<keystore>", "keystore.name"),
|
KEYSTORE("keystore", "<keystore>", "keystore.name"),
|
||||||
NEW("new", "<arg>", "new.password"),
|
NEW("new", "<arg>", "new.password"),
|
||||||
NOPROMPT("noprompt", null, "do.not.prompt"),
|
NOPROMPT("noprompt", null, "do.not.prompt"),
|
||||||
OUTFILE("outfile", "<filename>", "output.file.name"),
|
OUTFILE("outfile", "<file>", "output.file.name"),
|
||||||
PROTECTED("protected", null, "password.through.protected.mechanism"),
|
PROTECTED("protected", null, "password.through.protected.mechanism"),
|
||||||
PROVIDERARG("providerarg", "<arg>", "provider.argument"),
|
PROVIDERCLASS("providerclass", "<class>\n[-providerarg <arg>]", "provider.class.option"),
|
||||||
PROVIDERCLASS("providerclass", "<providerclass>", "provider.class.name"),
|
ADDPROVIDER("addprovider", "<name>\n[-providerarg <arg>]", "addprovider.option"),
|
||||||
PROVIDERNAME("providername", "<providername>", "provider.name"),
|
PROVIDERNAME("providername", "<name>", "provider.name"),
|
||||||
PROVIDERPATH("providerpath", "<pathlist>", "provider.classpath"),
|
PROVIDERPATH("providerpath", "<list>", "provider.classpath"),
|
||||||
RFC("rfc", null, "output.in.RFC.style"),
|
RFC("rfc", null, "output.in.RFC.style"),
|
||||||
SIGALG("sigalg", "<sigalg>", "signature.algorithm.name"),
|
SIGALG("sigalg", "<alg>", "signature.algorithm.name"),
|
||||||
SRCALIAS("srcalias", "<srcalias>", "source.alias"),
|
SRCALIAS("srcalias", "<alias>", "source.alias"),
|
||||||
SRCKEYPASS("srckeypass", "<arg>", "source.key.password"),
|
SRCKEYPASS("srckeypass", "<arg>", "source.key.password"),
|
||||||
SRCKEYSTORE("srckeystore", "<srckeystore>", "source.keystore.name"),
|
SRCKEYSTORE("srckeystore", "<keystore>", "source.keystore.name"),
|
||||||
SRCPROTECTED("srcprotected", null, "source.keystore.password.protected"),
|
SRCPROTECTED("srcprotected", null, "source.keystore.password.protected"),
|
||||||
SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source.keystore.provider.name"),
|
SRCPROVIDERNAME("srcprovidername", "<name>", "source.keystore.provider.name"),
|
||||||
SRCSTOREPASS("srcstorepass", "<arg>", "source.keystore.password"),
|
SRCSTOREPASS("srcstorepass", "<arg>", "source.keystore.password"),
|
||||||
SRCSTORETYPE("srcstoretype", "<srcstoretype>", "source.keystore.type"),
|
SRCSTORETYPE("srcstoretype", "<type>", "source.keystore.type"),
|
||||||
SSLSERVER("sslserver", "<server[:port]>", "SSL.server.host.and.port"),
|
SSLSERVER("sslserver", "<server[:port]>", "SSL.server.host.and.port"),
|
||||||
JARFILE("jarfile", "<filename>", "signed.jar.file"),
|
JARFILE("jarfile", "<file>", "signed.jar.file"),
|
||||||
STARTDATE("startdate", "<startdate>", "certificate.validity.start.date.time"),
|
STARTDATE("startdate", "<date>", "certificate.validity.start.date.time"),
|
||||||
STOREPASS("storepass", "<arg>", "keystore.password"),
|
STOREPASS("storepass", "<arg>", "keystore.password"),
|
||||||
STORETYPE("storetype", "<storetype>", "keystore.type"),
|
STORETYPE("storetype", "<type>", "keystore.type"),
|
||||||
TRUSTCACERTS("trustcacerts", null, "trust.certificates.from.cacerts"),
|
TRUSTCACERTS("trustcacerts", null, "trust.certificates.from.cacerts"),
|
||||||
V("v", null, "verbose.output"),
|
V("v", null, "verbose.output"),
|
||||||
VALIDITY("validity", "<valDays>", "validity.number.of.days");
|
VALIDITY("validity", "<days>", "validity.number.of.days");
|
||||||
|
|
||||||
final String name, arg, description;
|
final String name, arg, description;
|
||||||
Option(String name, String arg, String description) {
|
Option(String name, String arg, String description) {
|
||||||
@ -344,8 +343,6 @@ public final class Main {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final Class<?>[] PARAM_STRING = { String.class };
|
|
||||||
|
|
||||||
private static final String NONE = "NONE";
|
private static final String NONE = "NONE";
|
||||||
private static final String P11KEYSTORE = "PKCS11";
|
private static final String P11KEYSTORE = "PKCS11";
|
||||||
private static final String P12KEYSTORE = "PKCS12";
|
private static final String P12KEYSTORE = "PKCS12";
|
||||||
@ -549,10 +546,10 @@ public final class Main {
|
|||||||
jarfile = args[++i];
|
jarfile = args[++i];
|
||||||
} else if (collator.compare(flags, "-srckeystore") == 0) {
|
} else if (collator.compare(flags, "-srckeystore") == 0) {
|
||||||
srcksfname = args[++i];
|
srcksfname = args[++i];
|
||||||
} else if ((collator.compare(flags, "-provider") == 0) ||
|
} else if (collator.compare(flags, "-provider") == 0 ||
|
||||||
(collator.compare(flags, "-providerclass") == 0)) {
|
collator.compare(flags, "-providerclass") == 0) {
|
||||||
if (providers == null) {
|
if (providerClasses == null) {
|
||||||
providers = new HashSet<Pair <String, String>> (3);
|
providerClasses = new HashSet<Pair <String, String>> (3);
|
||||||
}
|
}
|
||||||
String providerClass = args[++i];
|
String providerClass = args[++i];
|
||||||
String providerArg = null;
|
String providerArg = null;
|
||||||
@ -565,8 +562,25 @@ public final class Main {
|
|||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
providers.add(
|
providerClasses.add(
|
||||||
Pair.of(providerClass, providerArg));
|
Pair.of(providerClass, providerArg));
|
||||||
|
} else if (collator.compare(flags, "-addprovider") == 0) {
|
||||||
|
if (providers == null) {
|
||||||
|
providers = new HashSet<Pair <String, String>> (3);
|
||||||
|
}
|
||||||
|
String provider = args[++i];
|
||||||
|
String providerArg = null;
|
||||||
|
|
||||||
|
if (args.length > (i+1)) {
|
||||||
|
flags = args[i+1];
|
||||||
|
if (collator.compare(flags, "-providerarg") == 0) {
|
||||||
|
if (args.length == (i+2)) errorNeedArgument(flags);
|
||||||
|
providerArg = args[i+2];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
providers.add(
|
||||||
|
Pair.of(provider, providerArg));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -617,7 +631,6 @@ public final class Main {
|
|||||||
return cmd != PRINTCERT && cmd != PRINTCERTREQ;
|
return cmd != PRINTCERT && cmd != PRINTCERTREQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the commands.
|
* Execute the commands.
|
||||||
*/
|
*/
|
||||||
@ -703,6 +716,20 @@ public final class Main {
|
|||||||
|
|
||||||
// Try to load and install specified provider
|
// Try to load and install specified provider
|
||||||
if (providers != null) {
|
if (providers != null) {
|
||||||
|
for (Pair<String, String> provider : providers) {
|
||||||
|
try {
|
||||||
|
KeyStoreUtil.loadProviderByName(
|
||||||
|
provider.fst, provider.snd);
|
||||||
|
if (debug) {
|
||||||
|
System.out.println("loadProviderByName: " + provider.fst);
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new Exception(String.format(rb.getString(
|
||||||
|
"provider.name.not.found"), provider.fst));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (providerClasses != null) {
|
||||||
ClassLoader cl = null;
|
ClassLoader cl = null;
|
||||||
if (pathlist != null) {
|
if (pathlist != null) {
|
||||||
String path = null;
|
String path = null;
|
||||||
@ -717,30 +744,20 @@ public final class Main {
|
|||||||
} else {
|
} else {
|
||||||
cl = ClassLoader.getSystemClassLoader();
|
cl = ClassLoader.getSystemClassLoader();
|
||||||
}
|
}
|
||||||
|
for (Pair<String, String> provider : providerClasses) {
|
||||||
for (Pair <String, String> provider: providers) {
|
try {
|
||||||
String provName = provider.fst;
|
KeyStoreUtil.loadProviderByClass(
|
||||||
Class<?> provClass;
|
provider.fst, provider.snd, cl);
|
||||||
if (cl != null) {
|
if (debug) {
|
||||||
provClass = cl.loadClass(provName);
|
System.out.println("loadProviderByClass: " + provider.fst);
|
||||||
} else {
|
}
|
||||||
provClass = Class.forName(provName);
|
} catch (ClassCastException cce) {
|
||||||
|
throw new Exception(String.format(rb.getString(
|
||||||
|
"provclass.not.a.provider"), provider.fst));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new Exception(String.format(rb.getString(
|
||||||
|
"provider.class.not.found"), provider.fst), e.getCause());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
Object obj = provClass.newInstance();
|
|
||||||
if (!(obj instanceof Provider)) {
|
|
||||||
MessageFormat form = new MessageFormat
|
|
||||||
(rb.getString("provName.not.a.provider"));
|
|
||||||
Object[] source = {provName};
|
|
||||||
throw new Exception(form.format(source));
|
|
||||||
}
|
|
||||||
Provider p = (Provider) obj;
|
|
||||||
String provArg = provider.snd;
|
|
||||||
if (provArg != null) {
|
|
||||||
p = p.configure(provArg);
|
|
||||||
}
|
|
||||||
Security.addProvider(p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4132,27 +4149,40 @@ public final class Main {
|
|||||||
System.err.println(rb.getString("Options."));
|
System.err.println(rb.getString("Options."));
|
||||||
System.err.println();
|
System.err.println();
|
||||||
|
|
||||||
// Left and right sides of the options list
|
// Left and right sides of the options list. Both might
|
||||||
|
// contain "\n" and span multiple lines
|
||||||
String[] left = new String[command.options.length];
|
String[] left = new String[command.options.length];
|
||||||
String[] right = new String[command.options.length];
|
String[] right = new String[command.options.length];
|
||||||
|
|
||||||
// Check if there's an unknown option
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
// Length of left side of options list
|
// Length of left side of options list
|
||||||
int lenLeft = 0;
|
int lenLeft = 0;
|
||||||
for (int j=0; j<left.length; j++) {
|
|
||||||
|
for (int j = 0; j < command.options.length; j++) {
|
||||||
Option opt = command.options[j];
|
Option opt = command.options[j];
|
||||||
left[j] = opt.toString();
|
left[j] = opt.toString();
|
||||||
if (opt.arg != null) left[j] += " " + opt.arg;
|
if (opt.arg != null) {
|
||||||
if (left[j].length() > lenLeft) {
|
left[j] += " " + opt.arg;
|
||||||
lenLeft = left[j].length();
|
}
|
||||||
|
String[] lefts = left[j].split("\n");
|
||||||
|
for (String s : lefts) {
|
||||||
|
if (s.length() > lenLeft) {
|
||||||
|
lenLeft = s.length();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
right[j] = rb.getString(opt.description);
|
right[j] = rb.getString(opt.description);
|
||||||
}
|
}
|
||||||
for (int j=0; j<left.length; j++) {
|
for (int j = 0; j < left.length; j++) {
|
||||||
System.err.printf(" %-" + lenLeft + "s %s\n",
|
String[] lefts = left[j].split("\n");
|
||||||
left[j], right[j]);
|
String[] rights = right[j].split("\n");
|
||||||
|
for (int i = 0; i < lefts.length && i < rights.length; i++) {
|
||||||
|
String s1 = i < lefts.length ? lefts[i] : "";
|
||||||
|
String s2 = i < rights.length ? rights[i] : "";
|
||||||
|
if (i == 0) {
|
||||||
|
System.err.printf(" %-" + lenLeft + "s %s\n", s1, s2);
|
||||||
|
} else {
|
||||||
|
System.err.printf(" %-" + lenLeft + "s %s\n", s1, s2);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
System.err.println();
|
System.err.println();
|
||||||
System.err.println(rb.getString(
|
System.err.println(rb.getString(
|
||||||
|
@ -133,10 +133,16 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
"do not prompt"}, //-noprompt
|
"do not prompt"}, //-noprompt
|
||||||
{"password.through.protected.mechanism",
|
{"password.through.protected.mechanism",
|
||||||
"password through protected mechanism"}, //-protected
|
"password through protected mechanism"}, //-protected
|
||||||
{"provider.argument",
|
|
||||||
"provider argument"}, //-providerarg
|
// The following 2 values should span 2 lines, the first for the
|
||||||
{"provider.class.name",
|
// option itself, the second for its -providerArg value.
|
||||||
"provider class name"}, //-providerclass
|
{"addprovider.option",
|
||||||
|
"add security provider by name (e.g. SunPKCS11)\n" +
|
||||||
|
"configure argument for -addprovider"}, //-addprovider
|
||||||
|
{"provider.class.option",
|
||||||
|
"add security provider by fully-qualified class name\n" +
|
||||||
|
"configure argument for -providerclass"}, //-providerclass
|
||||||
|
|
||||||
{"provider.name",
|
{"provider.name",
|
||||||
"provider name"}, //-providername
|
"provider name"}, //-providername
|
||||||
{"provider.classpath",
|
{"provider.classpath",
|
||||||
@ -209,7 +215,9 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
{"Illegal.startdate.value", "Illegal startdate value"},
|
{"Illegal.startdate.value", "Illegal startdate value"},
|
||||||
{"Validity.must.be.greater.than.zero",
|
{"Validity.must.be.greater.than.zero",
|
||||||
"Validity must be greater than zero"},
|
"Validity must be greater than zero"},
|
||||||
{"provName.not.a.provider", "{0} not a provider"},
|
{"provclass.not.a.provider", "%s not a provider"},
|
||||||
|
{"provider.name.not.found", "Provider named \"%s\" not found"},
|
||||||
|
{"provider.class.not.found", "Provider \"%s\" not found"},
|
||||||
{"Usage.error.no.command.provided", "Usage error: no command provided"},
|
{"Usage.error.no.command.provided", "Usage error: no command provided"},
|
||||||
{"Source.keystore.file.exists.but.is.empty.", "Source keystore file exists, but is empty: "},
|
{"Source.keystore.file.exists.but.is.empty.", "Source keystore file exists, but is empty: "},
|
||||||
{"Please.specify.srckeystore", "Please specify -srckeystore"},
|
{"Please.specify.srckeystore", "Please specify -srckeystore"},
|
||||||
|
@ -343,6 +343,10 @@ public class JavaTimeSupplementary extends OpenListResourceBundle {
|
|||||||
sharedShortEras },
|
sharedShortEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedShortEras },
|
sharedShortEras },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"GMT{0}" },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH:mm;-HH:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,8 @@ grant codeBase "jrt:/jdk.crypto.ucrypto" {
|
|||||||
permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto";
|
permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto";
|
||||||
permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto";
|
permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto";
|
||||||
permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto";
|
permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto";
|
||||||
permission java.io.FilePermission "${java.home}/conf/security/ucrypto-solaris.cfg", "read";
|
// Needed for reading Ucrypto config file
|
||||||
|
permission java.io.FilePermission "<<ALL FILES>>", "read";
|
||||||
};
|
};
|
||||||
|
|
||||||
grant codeBase "jrt:/java.sql" {
|
grant codeBase "jrt:/java.sql" {
|
||||||
|
@ -130,7 +130,7 @@ static void checkArg(const char *arg) {
|
|||||||
expectingNoDashArg = JNI_FALSE;
|
expectingNoDashArg = JNI_FALSE;
|
||||||
}
|
}
|
||||||
// only update on java mode and not yet found main class
|
// only update on java mode and not yet found main class
|
||||||
if (firstAppArgIndex == -1 && idx != 0) {
|
if (firstAppArgIndex == NOT_FOUND && idx != 0) {
|
||||||
firstAppArgIndex = (int) idx;
|
firstAppArgIndex = (int) idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -943,26 +943,6 @@ ProcessPlatformOption(const char *arg)
|
|||||||
return JNI_FALSE;
|
return JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
filterArgs(StdArg *stdargs, const int nargc, StdArg **pargv) {
|
|
||||||
StdArg* argv = NULL;
|
|
||||||
int nargs = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* Copy the non-vm args */
|
|
||||||
for (i = 0; i < nargc ; i++) {
|
|
||||||
const char *arg = stdargs[i].arg;
|
|
||||||
if (arg[0] == '-' && arg[1] == 'J')
|
|
||||||
continue;
|
|
||||||
argv = (StdArg*) JLI_MemRealloc(argv, (nargs+1) * sizeof(StdArg));
|
|
||||||
argv[nargs].arg = JLI_StringDup(arg);
|
|
||||||
argv[nargs].has_wildcard = stdargs[i].has_wildcard;
|
|
||||||
nargs++;
|
|
||||||
}
|
|
||||||
*pargv = argv;
|
|
||||||
return nargs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point we have the arguments to the application, and we need to
|
* At this point we have the arguments to the application, and we need to
|
||||||
* check with original stdargs in order to compare which of these truly
|
* check with original stdargs in order to compare which of these truly
|
||||||
@ -975,12 +955,13 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
|
|||||||
int i, j, idx;
|
int i, j, idx;
|
||||||
size_t tlen;
|
size_t tlen;
|
||||||
jobjectArray outArray, inArray;
|
jobjectArray outArray, inArray;
|
||||||
char *ostart, *astart, **nargv;
|
char *arg, **nargv;
|
||||||
jboolean needs_expansion = JNI_FALSE;
|
jboolean needs_expansion = JNI_FALSE;
|
||||||
jmethodID mid;
|
jmethodID mid;
|
||||||
int filteredargc, stdargc;
|
int stdargc;
|
||||||
StdArg *stdargs;
|
StdArg *stdargs;
|
||||||
StdArg *filteredargs;
|
int *appArgIdx;
|
||||||
|
int isTool;
|
||||||
jclass cls = GetLauncherHelperClass(env);
|
jclass cls = GetLauncherHelperClass(env);
|
||||||
NULL_CHECK0(cls);
|
NULL_CHECK0(cls);
|
||||||
|
|
||||||
@ -991,8 +972,6 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
|
|||||||
stdargs = JLI_GetStdArgs();
|
stdargs = JLI_GetStdArgs();
|
||||||
stdargc = JLI_GetStdArgc();
|
stdargc = JLI_GetStdArgc();
|
||||||
|
|
||||||
filteredargc = filterArgs(stdargs, stdargc, &filteredargs);
|
|
||||||
|
|
||||||
// sanity check, this should never happen
|
// sanity check, this should never happen
|
||||||
if (argc > stdargc) {
|
if (argc > stdargc) {
|
||||||
JLI_TraceLauncher("Warning: app args is larger than the original, %d %d\n", argc, stdargc);
|
JLI_TraceLauncher("Warning: app args is larger than the original, %d %d\n", argc, stdargc);
|
||||||
@ -1001,22 +980,35 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sanity check, match the args we have, to the holy grail
|
// sanity check, match the args we have, to the holy grail
|
||||||
idx = filteredargc - argc;
|
idx = JLI_GetAppArgIndex();
|
||||||
ostart = filteredargs[idx].arg;
|
isTool = (idx == 0);
|
||||||
astart = strv[0];
|
if (isTool) { idx++; } // skip tool name
|
||||||
// sanity check, ensure that the first argument of the arrays are the same
|
JLI_TraceLauncher("AppArgIndex: %d points to %s\n", idx, stdargs[idx].arg);
|
||||||
if (JLI_StrCmp(ostart, astart) != 0) {
|
|
||||||
// some thing is amiss the args don't match
|
appArgIdx = calloc(argc, sizeof(int));
|
||||||
JLI_TraceLauncher("Warning: app args parsing error\n");
|
for (i = idx, j = 0; i < stdargc; i++) {
|
||||||
JLI_TraceLauncher("passing arguments as-is\n");
|
if (isTool) { // filter -J used by tools to pass JVM options
|
||||||
|
arg = stdargs[i].arg;
|
||||||
|
if (arg[0] == '-' && arg[1] == 'J') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appArgIdx[j++] = i;
|
||||||
|
}
|
||||||
|
// sanity check, ensure same number of arguments for application
|
||||||
|
if (j != argc) {
|
||||||
|
JLI_TraceLauncher("Warning: app args count doesn't match, %d %d\n", j, argc);
|
||||||
|
JLI_TraceLauncher("passing arguments as-is.\n");
|
||||||
|
JLI_MemFree(appArgIdx);
|
||||||
return NewPlatformStringArray(env, strv, argc);
|
return NewPlatformStringArray(env, strv, argc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a copy of the args which will be expanded in java if required.
|
// make a copy of the args which will be expanded in java if required.
|
||||||
nargv = (char **)JLI_MemAlloc(argc * sizeof(char*));
|
nargv = (char **)JLI_MemAlloc(argc * sizeof(char*));
|
||||||
for (i = 0, j = idx; i < argc; i++, j++) {
|
for (i = 0; i < argc; i++) {
|
||||||
jboolean arg_expand = (JLI_StrCmp(filteredargs[j].arg, strv[i]) == 0)
|
j = appArgIdx[i];
|
||||||
? filteredargs[j].has_wildcard
|
jboolean arg_expand = (JLI_StrCmp(stdargs[j].arg, strv[i]) == 0)
|
||||||
|
? stdargs[j].has_wildcard
|
||||||
: JNI_FALSE;
|
: JNI_FALSE;
|
||||||
if (needs_expansion == JNI_FALSE)
|
if (needs_expansion == JNI_FALSE)
|
||||||
needs_expansion = arg_expand;
|
needs_expansion = arg_expand;
|
||||||
@ -1039,6 +1031,7 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
|
|||||||
JLI_MemFree(nargv[i]);
|
JLI_MemFree(nargv[i]);
|
||||||
}
|
}
|
||||||
JLI_MemFree(nargv);
|
JLI_MemFree(nargv);
|
||||||
|
JLI_MemFree(appArgIdx);
|
||||||
return NewPlatformStringArray(env, strv, argc);
|
return NewPlatformStringArray(env, strv, argc);
|
||||||
}
|
}
|
||||||
NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
|
NULL_CHECK0(mid = (*env)->GetStaticMethodID(env, cls,
|
||||||
@ -1053,6 +1046,6 @@ CreateApplicationArgs(JNIEnv *env, char **strv, int argc)
|
|||||||
JLI_MemFree(nargv[i]);
|
JLI_MemFree(nargv[i]);
|
||||||
}
|
}
|
||||||
JLI_MemFree(nargv);
|
JLI_MemFree(nargv);
|
||||||
JLI_MemFree(filteredargs);
|
JLI_MemFree(appArgIdx);
|
||||||
return outArray;
|
return outArray;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -387,11 +387,15 @@ public class LogManager {
|
|||||||
assert rootLogger == null;
|
assert rootLogger == null;
|
||||||
assert initializedCalled && !initializationDone;
|
assert initializedCalled && !initializationDone;
|
||||||
|
|
||||||
|
// create root logger before reading primordial
|
||||||
|
// configuration - to ensure that it will be added
|
||||||
|
// before the global logger, and not after.
|
||||||
|
owner.rootLogger = owner.new RootLogger();
|
||||||
|
|
||||||
// Read configuration.
|
// Read configuration.
|
||||||
owner.readPrimordialConfiguration();
|
owner.readPrimordialConfiguration();
|
||||||
|
|
||||||
// Create and retain Logger for the root of the namespace.
|
// Create and retain Logger for the root of the namespace.
|
||||||
owner.rootLogger = owner.new RootLogger();
|
|
||||||
owner.addLogger(owner.rootLogger);
|
owner.addLogger(owner.rootLogger);
|
||||||
if (!owner.rootLogger.isLevelInitialized()) {
|
if (!owner.rootLogger.isLevelInitialized()) {
|
||||||
owner.rootLogger.setLevel(defaultLevel);
|
owner.rootLogger.setLevel(defaultLevel);
|
||||||
@ -516,7 +520,7 @@ public class LogManager {
|
|||||||
if (result == null) {
|
if (result == null) {
|
||||||
// only allocate the new logger once
|
// only allocate the new logger once
|
||||||
Logger newLogger = new Logger(name, resourceBundleName,
|
Logger newLogger = new Logger(name, resourceBundleName,
|
||||||
module == null ? null : module, this, false);
|
module, this, false);
|
||||||
do {
|
do {
|
||||||
if (addLogger(newLogger)) {
|
if (addLogger(newLogger)) {
|
||||||
// We successfully added the new Logger that we
|
// We successfully added the new Logger that we
|
||||||
@ -569,15 +573,13 @@ public class LogManager {
|
|||||||
} while (logger == null);
|
} while (logger == null);
|
||||||
|
|
||||||
// LogManager will set the sysLogger's handlers via LogManager.addLogger method.
|
// LogManager will set the sysLogger's handlers via LogManager.addLogger method.
|
||||||
if (logger != sysLogger && sysLogger.accessCheckedHandlers().length == 0) {
|
if (logger != sysLogger) {
|
||||||
// if logger already exists but handlers not set
|
// if logger already exists we merge the two logger configurations.
|
||||||
final Logger l = logger;
|
final Logger l = logger;
|
||||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void run() {
|
public Void run() {
|
||||||
for (Handler hdl : l.accessCheckedHandlers()) {
|
l.mergeWithSystemLogger(sysLogger);
|
||||||
sysLogger.addHandler(hdl);
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -259,13 +259,185 @@ public class Logger {
|
|||||||
private static final RuntimePermission GET_CLASS_LOADER_PERMISSION =
|
private static final RuntimePermission GET_CLASS_LOADER_PERMISSION =
|
||||||
new RuntimePermission("getClassLoader");
|
new RuntimePermission("getClassLoader");
|
||||||
|
|
||||||
|
// A value class that holds the logger configuration data.
|
||||||
|
// This configuration can be shared between an application logger
|
||||||
|
// and a system logger of the same name.
|
||||||
|
private static final class ConfigurationData {
|
||||||
|
|
||||||
|
// The delegate field is used to avoid races while
|
||||||
|
// merging configuration. This will ensure that any pending
|
||||||
|
// configuration action on an application logger will either
|
||||||
|
// be finished before the merge happens, or will be forwarded
|
||||||
|
// to the system logger configuration after the merge is completed.
|
||||||
|
// By default delegate=this.
|
||||||
|
private volatile ConfigurationData delegate;
|
||||||
|
|
||||||
|
volatile boolean useParentHandlers;
|
||||||
|
volatile Filter filter;
|
||||||
|
volatile Level levelObject;
|
||||||
|
volatile int levelValue; // current effective level value
|
||||||
|
final CopyOnWriteArrayList<Handler> handlers =
|
||||||
|
new CopyOnWriteArrayList<>();
|
||||||
|
|
||||||
|
ConfigurationData() {
|
||||||
|
delegate = this;
|
||||||
|
useParentHandlers = true;
|
||||||
|
levelValue = Level.INFO.intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUseParentHandlers(boolean flag) {
|
||||||
|
useParentHandlers = flag;
|
||||||
|
if (delegate != this) {
|
||||||
|
// merge in progress - propagate value to system peer.
|
||||||
|
final ConfigurationData system = delegate;
|
||||||
|
synchronized (system) {
|
||||||
|
system.useParentHandlers = useParentHandlers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFilter(Filter f) {
|
||||||
|
filter = f;
|
||||||
|
if (delegate != this) {
|
||||||
|
// merge in progress - propagate value to system peer.
|
||||||
|
final ConfigurationData system = delegate;
|
||||||
|
synchronized (system) {
|
||||||
|
system.filter = filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLevelObject(Level l) {
|
||||||
|
levelObject = l;
|
||||||
|
if (delegate != this) {
|
||||||
|
// merge in progress - propagate value to system peer.
|
||||||
|
final ConfigurationData system = delegate;
|
||||||
|
synchronized (system) {
|
||||||
|
system.levelObject = levelObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLevelValue(int v) {
|
||||||
|
levelValue = v;
|
||||||
|
if (delegate != this) {
|
||||||
|
// merge in progress - propagate value to system peer.
|
||||||
|
final ConfigurationData system = delegate;
|
||||||
|
synchronized (system) {
|
||||||
|
system.levelValue = levelValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addHandler(Handler h) {
|
||||||
|
if (handlers.add(h)) {
|
||||||
|
if (delegate != this) {
|
||||||
|
// merge in progress - propagate value to system peer.
|
||||||
|
final ConfigurationData system = delegate;
|
||||||
|
synchronized (system) {
|
||||||
|
system.handlers.addIfAbsent(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeHandler(Handler h) {
|
||||||
|
if (handlers.remove(h)) {
|
||||||
|
if (delegate != this) {
|
||||||
|
// merge in progress - propagate value to system peer.
|
||||||
|
final ConfigurationData system = delegate;
|
||||||
|
synchronized (system) {
|
||||||
|
system.handlers.remove(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationData merge(Logger systemPeer) {
|
||||||
|
if (!systemPeer.isSystemLogger) {
|
||||||
|
// should never come here
|
||||||
|
throw new InternalError("not a system logger");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationData system = systemPeer.config;
|
||||||
|
|
||||||
|
if (system == this) {
|
||||||
|
// nothing to do
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (system) {
|
||||||
|
// synchronize before checking on delegate to counter
|
||||||
|
// race conditions where two threads might attempt to
|
||||||
|
// merge concurrently
|
||||||
|
if (delegate == system) {
|
||||||
|
// merge already performed;
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
// publish system as the temporary delegate configuration.
|
||||||
|
// This should take care of potential race conditions where
|
||||||
|
// an other thread might attempt to call e.g. setlevel on
|
||||||
|
// the application logger while merge is in progress.
|
||||||
|
// (see implementation of ConfigurationData::setLevel)
|
||||||
|
delegate = system;
|
||||||
|
|
||||||
|
// merge this config object data into the system config
|
||||||
|
system.useParentHandlers = useParentHandlers;
|
||||||
|
system.filter = filter;
|
||||||
|
system.levelObject = levelObject;
|
||||||
|
system.levelValue = levelValue;
|
||||||
|
|
||||||
|
// Prevent race condition in case two threads attempt to merge
|
||||||
|
// configuration and add handlers at the same time. We don't want
|
||||||
|
// to add the same handlers twice.
|
||||||
|
//
|
||||||
|
// Handlers are created and loaded by LogManager.addLogger. If we
|
||||||
|
// reach here, then it means that the application logger has
|
||||||
|
// been created first and added with LogManager.addLogger, and the
|
||||||
|
// system logger was created after - and no handler has been added
|
||||||
|
// to it by LogManager.addLogger. Therefore, system.handlers
|
||||||
|
// should be empty.
|
||||||
|
//
|
||||||
|
// A non empty cfg.handlers list indicates a race condition
|
||||||
|
// where two threads might attempt to merge the configuration
|
||||||
|
// or add handlers concurrently. Though of no consequence for
|
||||||
|
// the other data (level etc...) this would be an issue if we
|
||||||
|
// added the same handlers twice.
|
||||||
|
//
|
||||||
|
for (Handler h : handlers) {
|
||||||
|
if (!system.handlers.contains(h)) {
|
||||||
|
systemPeer.addHandler(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
system.handlers.retainAll(handlers);
|
||||||
|
system.handlers.addAllAbsent(handlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity: update effective level after merging
|
||||||
|
synchronized(treeLock) {
|
||||||
|
systemPeer.updateEffectiveLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return system;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// The logger configuration data. Ideally, this should be final
|
||||||
|
// for system loggers, and replace-once for application loggers.
|
||||||
|
// When an application requests a logger by name, we do not know a-priori
|
||||||
|
// whether that corresponds to a system logger name or not.
|
||||||
|
// So if no system logger by that name already exists, we simply return an
|
||||||
|
// application logger.
|
||||||
|
// If a system class later requests a system logger of the same name, then
|
||||||
|
// the application logger and system logger configurations will be merged
|
||||||
|
// in a single instance of ConfigurationData that both loggers will share.
|
||||||
|
private volatile ConfigurationData config;
|
||||||
|
|
||||||
private volatile LogManager manager;
|
private volatile LogManager manager;
|
||||||
private String name;
|
private String name;
|
||||||
private final CopyOnWriteArrayList<Handler> handlers =
|
|
||||||
new CopyOnWriteArrayList<>();
|
|
||||||
private volatile LoggerBundle loggerBundle = NO_RESOURCE_BUNDLE;
|
private volatile LoggerBundle loggerBundle = NO_RESOURCE_BUNDLE;
|
||||||
private volatile boolean useParentHandlers = true;
|
|
||||||
private volatile Filter filter;
|
|
||||||
private boolean anonymous;
|
private boolean anonymous;
|
||||||
|
|
||||||
// Cache to speed up behavior of findResourceBundle:
|
// Cache to speed up behavior of findResourceBundle:
|
||||||
@ -280,8 +452,6 @@ public class Logger {
|
|||||||
// references from children to parents.
|
// references from children to parents.
|
||||||
private volatile Logger parent; // our nearest parent.
|
private volatile Logger parent; // our nearest parent.
|
||||||
private ArrayList<LogManager.LoggerWeakRef> kids; // WeakReferences to loggers that have us as parent
|
private ArrayList<LogManager.LoggerWeakRef> kids; // WeakReferences to loggers that have us as parent
|
||||||
private volatile Level levelObject;
|
|
||||||
private volatile int levelValue; // current effective level value
|
|
||||||
private WeakReference<Module> callerModuleRef;
|
private WeakReference<Module> callerModuleRef;
|
||||||
private final boolean isSystemLogger;
|
private final boolean isSystemLogger;
|
||||||
|
|
||||||
@ -384,9 +554,29 @@ public class Logger {
|
|||||||
LogManager manager, boolean isSystemLogger) {
|
LogManager manager, boolean isSystemLogger) {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
this.isSystemLogger = isSystemLogger;
|
this.isSystemLogger = isSystemLogger;
|
||||||
setupResourceInfo(resourceBundleName, caller);
|
this.config = new ConfigurationData();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
levelValue = Level.INFO.intValue();
|
setupResourceInfo(resourceBundleName, caller);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by LogManager when a system logger is created
|
||||||
|
// after a user logger of the same name.
|
||||||
|
// Ensure that both loggers will share the same
|
||||||
|
// configuration.
|
||||||
|
final void mergeWithSystemLogger(Logger system) {
|
||||||
|
// sanity checks
|
||||||
|
if (!system.isSystemLogger
|
||||||
|
|| anonymous
|
||||||
|
|| name == null
|
||||||
|
|| !name.equals(system.name)) {
|
||||||
|
// should never come here
|
||||||
|
throw new InternalError("invalid logger merge");
|
||||||
|
}
|
||||||
|
checkPermission();
|
||||||
|
final ConfigurationData cfg = config;
|
||||||
|
if (cfg != system.config) {
|
||||||
|
config = cfg.merge(system);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCallerModuleRef(Module callerModule) {
|
private void setCallerModuleRef(Module callerModule) {
|
||||||
@ -408,7 +598,7 @@ public class Logger {
|
|||||||
// The manager field is not initialized here.
|
// The manager field is not initialized here.
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.isSystemLogger = true;
|
this.isSystemLogger = true;
|
||||||
levelValue = Level.INFO.intValue();
|
config = new ConfigurationData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is called from LoggerContext.addLocalLogger() when the logger
|
// It is called from LoggerContext.addLocalLogger() when the logger
|
||||||
@ -451,7 +641,7 @@ public class Logger {
|
|||||||
private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
|
private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
|
||||||
LogManager manager = LogManager.getLogManager();
|
LogManager manager = LogManager.getLogManager();
|
||||||
if (!SystemLoggerHelper.disableCallerCheck) {
|
if (!SystemLoggerHelper.disableCallerCheck) {
|
||||||
if (caller.getClassLoader() == null) {
|
if (isSystem(caller.getModule())) {
|
||||||
return manager.demandSystemLogger(name, resourceBundleName, caller);
|
return manager.demandSystemLogger(name, resourceBundleName, caller);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -740,7 +930,7 @@ public class Logger {
|
|||||||
*/
|
*/
|
||||||
public void setFilter(Filter newFilter) throws SecurityException {
|
public void setFilter(Filter newFilter) throws SecurityException {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
filter = newFilter;
|
config.setFilter(newFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -749,7 +939,7 @@ public class Logger {
|
|||||||
* @return a filter object (may be null)
|
* @return a filter object (may be null)
|
||||||
*/
|
*/
|
||||||
public Filter getFilter() {
|
public Filter getFilter() {
|
||||||
return filter;
|
return config.filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -765,7 +955,7 @@ public class Logger {
|
|||||||
if (!isLoggable(record.getLevel())) {
|
if (!isLoggable(record.getLevel())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Filter theFilter = filter;
|
Filter theFilter = config.filter;
|
||||||
if (theFilter != null && !theFilter.isLoggable(record)) {
|
if (theFilter != null && !theFilter.isLoggable(record)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -784,7 +974,7 @@ public class Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final boolean useParentHdls = isSystemLogger
|
final boolean useParentHdls = isSystemLogger
|
||||||
? logger.useParentHandlers
|
? logger.config.useParentHandlers
|
||||||
: logger.getUseParentHandlers();
|
: logger.getUseParentHandlers();
|
||||||
|
|
||||||
if (!useParentHdls) {
|
if (!useParentHdls) {
|
||||||
@ -1804,13 +1994,13 @@ public class Logger {
|
|||||||
public void setLevel(Level newLevel) throws SecurityException {
|
public void setLevel(Level newLevel) throws SecurityException {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
synchronized (treeLock) {
|
synchronized (treeLock) {
|
||||||
levelObject = newLevel;
|
config.setLevelObject(newLevel);
|
||||||
updateEffectiveLevel();
|
updateEffectiveLevel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean isLevelInitialized() {
|
final boolean isLevelInitialized() {
|
||||||
return levelObject != null;
|
return config.levelObject != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1821,7 +2011,7 @@ public class Logger {
|
|||||||
* @return this Logger's level
|
* @return this Logger's level
|
||||||
*/
|
*/
|
||||||
public Level getLevel() {
|
public Level getLevel() {
|
||||||
return levelObject;
|
return config.levelObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1833,6 +2023,7 @@ public class Logger {
|
|||||||
* @return true if the given message level is currently being logged.
|
* @return true if the given message level is currently being logged.
|
||||||
*/
|
*/
|
||||||
public boolean isLoggable(Level level) {
|
public boolean isLoggable(Level level) {
|
||||||
|
int levelValue = config.levelValue;
|
||||||
if (level.intValue() < levelValue || levelValue == offValue) {
|
if (level.intValue() < levelValue || levelValue == offValue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1862,7 +2053,7 @@ public class Logger {
|
|||||||
public void addHandler(Handler handler) throws SecurityException {
|
public void addHandler(Handler handler) throws SecurityException {
|
||||||
Objects.requireNonNull(handler);
|
Objects.requireNonNull(handler);
|
||||||
checkPermission();
|
checkPermission();
|
||||||
handlers.add(handler);
|
config.addHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1880,7 +2071,7 @@ public class Logger {
|
|||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handlers.remove(handler);
|
config.removeHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1895,7 +2086,7 @@ public class Logger {
|
|||||||
// This method should ideally be marked final - but unfortunately
|
// This method should ideally be marked final - but unfortunately
|
||||||
// it needs to be overridden by LogManager.RootLogger
|
// it needs to be overridden by LogManager.RootLogger
|
||||||
Handler[] accessCheckedHandlers() {
|
Handler[] accessCheckedHandlers() {
|
||||||
return handlers.toArray(emptyHandlers);
|
return config.handlers.toArray(emptyHandlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1912,7 +2103,7 @@ public class Logger {
|
|||||||
*/
|
*/
|
||||||
public void setUseParentHandlers(boolean useParentHandlers) {
|
public void setUseParentHandlers(boolean useParentHandlers) {
|
||||||
checkPermission();
|
checkPermission();
|
||||||
this.useParentHandlers = useParentHandlers;
|
config.setUseParentHandlers(useParentHandlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1922,7 +2113,7 @@ public class Logger {
|
|||||||
* @return true if output is to be sent to the logger's parent
|
* @return true if output is to be sent to the logger's parent
|
||||||
*/
|
*/
|
||||||
public boolean getUseParentHandlers() {
|
public boolean getUseParentHandlers() {
|
||||||
return useParentHandlers;
|
return config.useParentHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2256,11 +2447,13 @@ public class Logger {
|
|||||||
|
|
||||||
// Figure out our current effective level.
|
// Figure out our current effective level.
|
||||||
int newLevelValue;
|
int newLevelValue;
|
||||||
|
final ConfigurationData cfg = config;
|
||||||
|
final Level levelObject = cfg.levelObject;
|
||||||
if (levelObject != null) {
|
if (levelObject != null) {
|
||||||
newLevelValue = levelObject.intValue();
|
newLevelValue = levelObject.intValue();
|
||||||
} else {
|
} else {
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
newLevelValue = parent.levelValue;
|
newLevelValue = parent.config.levelValue;
|
||||||
} else {
|
} else {
|
||||||
// This may happen during initialization.
|
// This may happen during initialization.
|
||||||
newLevelValue = Level.INFO.intValue();
|
newLevelValue = Level.INFO.intValue();
|
||||||
@ -2268,11 +2461,11 @@ public class Logger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If our effective value hasn't changed, we're done.
|
// If our effective value hasn't changed, we're done.
|
||||||
if (levelValue == newLevelValue) {
|
if (cfg.levelValue == newLevelValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
levelValue = newLevelValue;
|
cfg.setLevelValue(newLevelValue);
|
||||||
|
|
||||||
// System.err.println("effective level: \"" + getName() + "\" := " + level);
|
// System.err.println("effective level: \"" + getName() + "\" := " + level);
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ abstract class AbstractLdapNamingEnumeration<T extends NameClassPair>
|
|||||||
errEx = e;
|
errEx = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract AbstractLdapNamingEnumeration<T> getReferredResults(
|
protected abstract AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
|
||||||
LdapReferralContext refCtx) throws NamingException;
|
LdapReferralContext refCtx) throws NamingException;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -360,7 +360,7 @@ abstract class AbstractLdapNamingEnumeration<T extends NameClassPair>
|
|||||||
* Merge the entries and/or referrals from the supplied enumeration
|
* Merge the entries and/or referrals from the supplied enumeration
|
||||||
* with those of the current enumeration.
|
* with those of the current enumeration.
|
||||||
*/
|
*/
|
||||||
protected void update(AbstractLdapNamingEnumeration<T> ne) {
|
protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
|
||||||
// Cleanup previous context first
|
// Cleanup previous context first
|
||||||
homeCtx.decEnumCount();
|
homeCtx.decEnumCount();
|
||||||
|
|
||||||
|
@ -104,9 +104,9 @@ final class LdapBindingEnumeration
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LdapBindingEnumeration getReferredResults(
|
protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
|
||||||
LdapReferralContext refCtx) throws NamingException{
|
LdapReferralContext refCtx) throws NamingException{
|
||||||
// repeat the original operation at the new context
|
// repeat the original operation at the new context
|
||||||
return (LdapBindingEnumeration)refCtx.listBindings(listArg);
|
return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.listBindings(listArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,9 +72,9 @@ final class LdapNamingEnumeration
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LdapNamingEnumeration getReferredResults(
|
protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
|
||||||
LdapReferralContext refCtx) throws NamingException {
|
LdapReferralContext refCtx) throws NamingException {
|
||||||
// repeat the original operation at the new context
|
// repeat the original operation at the new context
|
||||||
return (LdapNamingEnumeration)refCtx.list(listArg);
|
return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.list(listArg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,15 +199,15 @@ final class LdapSearchEnumeration
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected LdapSearchEnumeration getReferredResults(
|
protected AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
|
||||||
LdapReferralContext refCtx) throws NamingException {
|
LdapReferralContext refCtx) throws NamingException {
|
||||||
// repeat the original operation at the new context
|
// repeat the original operation at the new context
|
||||||
return (LdapSearchEnumeration)refCtx.search(
|
return (AbstractLdapNamingEnumeration<? extends NameClassPair>)refCtx.search(
|
||||||
searchArgs.name, searchArgs.filter, searchArgs.cons);
|
searchArgs.name, searchArgs.filter, searchArgs.cons);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void update(AbstractLdapNamingEnumeration<SearchResult> ne) {
|
protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
|
||||||
super.update(ne);
|
super.update(ne);
|
||||||
|
|
||||||
// Update search-specific variables
|
// Update search-specific variables
|
||||||
|
@ -235,13 +235,14 @@ public final class UcryptoProvider extends Provider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Provider configure(String configArg) throws InvalidParameterException {
|
public Provider configure(String configArg) throws InvalidParameterException {
|
||||||
// default policy entry only grants read access to default config
|
try {
|
||||||
if (!defConfigName.equals(configArg)) {
|
init(configArg);
|
||||||
throw new InvalidParameterException("Ucrypto provider can only be " +
|
} catch (UcryptoException ue) {
|
||||||
"configured with default configuration file");
|
InvalidParameterException ipe =
|
||||||
|
new InvalidParameterException("Error using " + configArg);
|
||||||
|
ipe.initCause(ue.getCause());
|
||||||
|
throw ipe;
|
||||||
}
|
}
|
||||||
// re-read the config
|
|
||||||
init(defConfigName);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
}
|
}
|
||||||
...
|
...
|
||||||
|
|
||||||
HttpServer server = HttpServer.create(new InetSocketAddress(8000));
|
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
|
||||||
server.createContext("/applications/myapp", new MyHandler());
|
server.createContext("/applications/myapp", new MyHandler());
|
||||||
server.setExecutor(null); // creates a default executor
|
server.setExecutor(null); // creates a default executor
|
||||||
server.start();
|
server.start();
|
||||||
|
@ -118,7 +118,8 @@ public class Main {
|
|||||||
boolean protectedPath; // protected authentication path
|
boolean protectedPath; // protected authentication path
|
||||||
String storetype; // keystore type
|
String storetype; // keystore type
|
||||||
String providerName; // provider name
|
String providerName; // provider name
|
||||||
Vector<String> providers = null; // list of providers
|
List<String> providers = null; // list of provider names
|
||||||
|
List<String> providerClasses = null; // list of provider classes
|
||||||
// arguments for provider constructors
|
// arguments for provider constructors
|
||||||
HashMap<String,String> providerArgs = new HashMap<>();
|
HashMap<String,String> providerArgs = new HashMap<>();
|
||||||
char[] keypass; // private key password
|
char[] keypass; // private key password
|
||||||
@ -174,30 +175,36 @@ public class Main {
|
|||||||
|
|
||||||
// Try to load and install the specified providers
|
// Try to load and install the specified providers
|
||||||
if (providers != null) {
|
if (providers != null) {
|
||||||
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
for (String provName: providers) {
|
||||||
Enumeration<String> e = providers.elements();
|
try {
|
||||||
while (e.hasMoreElements()) {
|
KeyStoreUtil.loadProviderByName(provName,
|
||||||
String provName = e.nextElement();
|
providerArgs.get(provName));
|
||||||
Class<?> provClass;
|
if (debug) {
|
||||||
if (cl != null) {
|
System.out.println("loadProviderByName: " + provName);
|
||||||
provClass = cl.loadClass(provName);
|
}
|
||||||
} else {
|
} catch (IllegalArgumentException e) {
|
||||||
provClass = Class.forName(provName);
|
throw new Exception(String.format(rb.getString(
|
||||||
|
"provider.name.not.found"), provName));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Object obj = provClass.newInstance();
|
if (providerClasses != null) {
|
||||||
if (!(obj instanceof Provider)) {
|
ClassLoader cl = ClassLoader.getSystemClassLoader();
|
||||||
MessageFormat form = new MessageFormat(rb.getString
|
for (String provClass: providerClasses) {
|
||||||
("provName.not.a.provider"));
|
try {
|
||||||
Object[] source = {provName};
|
KeyStoreUtil.loadProviderByClass(provClass,
|
||||||
throw new Exception(form.format(source));
|
providerArgs.get(provClass), cl);
|
||||||
|
if (debug) {
|
||||||
|
System.out.println("loadProviderByClass: " + provClass);
|
||||||
|
}
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
throw new Exception(String.format(rb.getString(
|
||||||
|
"provclass.not.a.provider"), provClass));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new Exception(String.format(rb.getString(
|
||||||
|
"provider.class.not.found"), provClass), e.getCause());
|
||||||
}
|
}
|
||||||
Provider p = (Provider) obj;
|
|
||||||
String provArg = providerArgs.get(provName);
|
|
||||||
if (provArg != null) {
|
|
||||||
p = p.configure(provArg);
|
|
||||||
}
|
|
||||||
Security.addProvider(p);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,11 +342,26 @@ public class Main {
|
|||||||
} else if (collator.compare(flags, "-providerName") ==0) {
|
} else if (collator.compare(flags, "-providerName") ==0) {
|
||||||
if (++n == args.length) usageNoArg();
|
if (++n == args.length) usageNoArg();
|
||||||
providerName = args[n];
|
providerName = args[n];
|
||||||
} else if ((collator.compare(flags, "-provider") == 0) ||
|
} else if (collator.compare(flags, "-provider") == 0 ||
|
||||||
(collator.compare(flags, "-providerClass") == 0)) {
|
collator.compare(flags, "-providerClass") == 0) {
|
||||||
|
if (++n == args.length) usageNoArg();
|
||||||
|
if (providerClasses == null) {
|
||||||
|
providerClasses = new ArrayList<>(3);
|
||||||
|
}
|
||||||
|
providerClasses.add(args[n]);
|
||||||
|
|
||||||
|
if (args.length > (n+1)) {
|
||||||
|
flags = args[n+1];
|
||||||
|
if (collator.compare(flags, "-providerArg") == 0) {
|
||||||
|
if (args.length == (n+2)) usageNoArg();
|
||||||
|
providerArgs.put(args[n], args[n+2]);
|
||||||
|
n += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (collator.compare(flags, "-addprovider") == 0) {
|
||||||
if (++n == args.length) usageNoArg();
|
if (++n == args.length) usageNoArg();
|
||||||
if (providers == null) {
|
if (providers == null) {
|
||||||
providers = new Vector<String>(3);
|
providers = new ArrayList<>(3);
|
||||||
}
|
}
|
||||||
providers.add(args[n]);
|
providers.add(args[n]);
|
||||||
|
|
||||||
@ -584,9 +606,14 @@ public class Main {
|
|||||||
(".providerName.name.provider.name"));
|
(".providerName.name.provider.name"));
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
(".providerClass.class.name.of.cryptographic.service.provider.s"));
|
(".add.provider.option"));
|
||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
(".providerArg.arg.master.class.file.and.constructor.argument"));
|
(".providerArg.option.1"));
|
||||||
|
System.out.println();
|
||||||
|
System.out.println(rb.getString
|
||||||
|
(".providerClass.option"));
|
||||||
|
System.out.println(rb.getString
|
||||||
|
(".providerArg.option.2"));
|
||||||
System.out.println();
|
System.out.println();
|
||||||
System.out.println(rb.getString
|
System.out.println(rb.getString
|
||||||
(".strict.treat.warnings.as.errors"));
|
(".strict.treat.warnings.as.errors"));
|
||||||
|
@ -40,8 +40,9 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
{"6SPACE", " "},
|
{"6SPACE", " "},
|
||||||
{"COMMA", ", "},
|
{"COMMA", ", "},
|
||||||
|
|
||||||
{"provName.not.a.provider", "{0} not a provider"},
|
{"provclass.not.a.provider", "%s not a provider"},
|
||||||
{"signerClass.is.not.a.signing.mechanism", "{0} is not a signing mechanism"},
|
{"provider.name.not.found", "Provider named \"%s\" not found"},
|
||||||
|
{"provider.class.not.found", "Provider \"%s\" not found"},
|
||||||
{"jarsigner.error.", "jarsigner error: "},
|
{"jarsigner.error.", "jarsigner error: "},
|
||||||
{"Illegal.option.", "Illegal option: "},
|
{"Illegal.option.", "Illegal option: "},
|
||||||
{"This.option.is.deprecated", "This option is deprecated: "},
|
{"This.option.is.deprecated", "This option is deprecated: "},
|
||||||
@ -105,10 +106,14 @@ public class Resources extends java.util.ListResourceBundle {
|
|||||||
"[-protected] keystore has protected authentication path"},
|
"[-protected] keystore has protected authentication path"},
|
||||||
{".providerName.name.provider.name",
|
{".providerName.name.provider.name",
|
||||||
"[-providerName <name>] provider name"},
|
"[-providerName <name>] provider name"},
|
||||||
{".providerClass.class.name.of.cryptographic.service.provider.s",
|
{".add.provider.option",
|
||||||
"[-providerClass <class> name of cryptographic service provider's"},
|
"[-addprovider <name> add security provider by name (e.g. SunPKCS11)"},
|
||||||
{".providerArg.arg.master.class.file.and.constructor.argument",
|
{".providerArg.option.1",
|
||||||
" [-providerArg <arg>]] ... master class file and constructor argument"},
|
" [-providerArg <arg>]] ... configure argument for -addprovider"},
|
||||||
|
{".providerClass.option",
|
||||||
|
"[-providerClass <class> add security provider by fully-qualified class name"},
|
||||||
|
{".providerArg.option.2",
|
||||||
|
" [-providerArg <arg>]] ... configure argument for -providerClass"},
|
||||||
{".strict.treat.warnings.as.errors",
|
{".strict.treat.warnings.as.errors",
|
||||||
"[-strict] treat warnings as errors"},
|
"[-strict] treat warnings as errors"},
|
||||||
{".conf.url.specify.a.pre.configured.options.file",
|
{".conf.url.specify.a.pre.configured.options.file",
|
||||||
|
@ -399,6 +399,14 @@ public final class ImagePluginStack {
|
|||||||
return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
|
return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
|
||||||
|
Objects.requireNonNull(path);
|
||||||
|
Objects.requireNonNull(context);
|
||||||
|
Optional<ModuleEntry> res = pool.findEntryInContext(path, context);
|
||||||
|
return res.map(this::getUncompressed);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contains(ModuleEntry res) {
|
public boolean contains(ModuleEntry res) {
|
||||||
return pool.contains(res);
|
return pool.contains(res);
|
||||||
|
@ -51,16 +51,32 @@ public final class ModuleEntryFactory {
|
|||||||
original.getPath(), original.getType(), file);
|
original.getPath(), original.getType(), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String moduleFrom(String path) {
|
static String moduleFrom(String path) {
|
||||||
Objects.requireNonNull(path);
|
Objects.requireNonNull(path);
|
||||||
if (path.isEmpty() || path.charAt(0) != '/') {
|
if (path.isEmpty() || path.charAt(0) != '/') {
|
||||||
throw new IllegalArgumentException(path + " must start with /");
|
throw new IllegalArgumentException(path + " must start with /");
|
||||||
}
|
}
|
||||||
String noRoot = path.substring(1);
|
int idx = path.indexOf('/', 1);
|
||||||
int idx = noRoot.indexOf('/');
|
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
throw new IllegalArgumentException("/ missing after module: " + path);
|
throw new IllegalArgumentException("/ missing after module: " + path);
|
||||||
}
|
}
|
||||||
return noRoot.substring(0, idx);
|
return path.substring(1, idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String packageFrom(String path) {
|
||||||
|
Objects.requireNonNull(path);
|
||||||
|
int idx = path.lastIndexOf('/');
|
||||||
|
if (idx == -1) {
|
||||||
|
throw new IllegalArgumentException("/ missing from path: " + path);
|
||||||
|
}
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
int jdx = path.indexOf('/', 1);
|
||||||
|
if (jdx == -1) {
|
||||||
|
throw new IllegalArgumentException("/ missing after module: " + path);
|
||||||
|
}
|
||||||
|
return path.substring(jdx + 1, idx);
|
||||||
|
} else {
|
||||||
|
return path.substring(0, idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,6 +264,25 @@ public class ModulePoolImpl implements ModulePool {
|
|||||||
return Optional.ofNullable(resources.get(path));
|
return Optional.ofNullable(resources.get(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ModuleEntry for the passed path restricted to supplied context.
|
||||||
|
*
|
||||||
|
* @param path A data path
|
||||||
|
* @param context A context of the search
|
||||||
|
* @return A ModuleEntry instance or null if the data is not found
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context) {
|
||||||
|
Objects.requireNonNull(path);
|
||||||
|
Objects.requireNonNull(context);
|
||||||
|
LinkModule module = modules.get(context.getModule());
|
||||||
|
Objects.requireNonNull(module);
|
||||||
|
Optional<ModuleEntry> entry = module.findEntry(path);
|
||||||
|
// Navigating other modules via requires and exports is problematic
|
||||||
|
// since we cannot construct the runtime model of loaders and layers.
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the ModulePool contains the given ModuleEntry.
|
* Check if the ModulePool contains the given ModuleEntry.
|
||||||
*
|
*
|
||||||
|
@ -28,7 +28,7 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.Optional;
|
||||||
import jdk.tools.jlink.plugin.ModulePool;
|
import jdk.tools.jlink.plugin.ModulePool;
|
||||||
import jdk.tools.jlink.plugin.Plugin.Category;
|
import jdk.tools.jlink.plugin.Plugin.Category;
|
||||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||||
@ -67,7 +67,7 @@ public final class ClassForNamePlugin implements Plugin {
|
|||||||
return index == -1 ? "" : binaryName.substring(0, index);
|
return index == -1 ? "" : binaryName.substring(0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModuleEntry transform(ModuleEntry resource, Map<String, ModuleEntry> classes) {
|
private ModuleEntry transform(ModuleEntry resource, ModulePool pool) {
|
||||||
byte[] inBytes = resource.getBytes();
|
byte[] inBytes = resource.getBytes();
|
||||||
ClassReader cr = new ClassReader(inBytes);
|
ClassReader cr = new ClassReader(inBytes);
|
||||||
ClassNode cn = new ClassNode();
|
ClassNode cn = new ClassNode();
|
||||||
@ -96,10 +96,11 @@ public final class ClassForNamePlugin implements Plugin {
|
|||||||
min.desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {
|
min.desc.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {
|
||||||
String ldcClassName = ldc.cst.toString();
|
String ldcClassName = ldc.cst.toString();
|
||||||
String thatClassName = ldcClassName.replaceAll("\\.", "/");
|
String thatClassName = ldcClassName.replaceAll("\\.", "/");
|
||||||
ModuleEntry thatClass = classes.get(thatClassName);
|
Optional<ModuleEntry> thatClass =
|
||||||
|
pool.findEntryInContext(thatClassName + ".class", resource);
|
||||||
|
|
||||||
if (thatClass != null) {
|
if (thatClass.isPresent()) {
|
||||||
int thatAccess = getAccess(thatClass);
|
int thatAccess = getAccess(thatClass.get());
|
||||||
String thatPackage = getPackage(thatClassName);
|
String thatPackage = getPackage(thatClassName);
|
||||||
|
|
||||||
if ((thatAccess & Opcodes.ACC_PRIVATE) != Opcodes.ACC_PRIVATE &&
|
if ((thatAccess & Opcodes.ACC_PRIVATE) != Opcodes.ACC_PRIVATE &&
|
||||||
@ -142,19 +143,13 @@ public final class ClassForNamePlugin implements Plugin {
|
|||||||
public void visit(ModulePool in, ModulePool out) {
|
public void visit(ModulePool in, ModulePool out) {
|
||||||
Objects.requireNonNull(in);
|
Objects.requireNonNull(in);
|
||||||
Objects.requireNonNull(out);
|
Objects.requireNonNull(out);
|
||||||
Map<String, ModuleEntry> classes = in.entries()
|
|
||||||
.filter(resource -> resource != null &&
|
|
||||||
resource.getPath().endsWith(".class") &&
|
|
||||||
!resource.getPath().endsWith("/module-info.class"))
|
|
||||||
.collect(Collectors.toMap(resource -> binaryClassName(resource.getPath()),
|
|
||||||
resource -> resource));
|
|
||||||
in.entries()
|
in.entries()
|
||||||
.filter(resource -> resource != null)
|
|
||||||
.forEach(resource -> {
|
.forEach(resource -> {
|
||||||
String path = resource.getPath();
|
String path = resource.getPath();
|
||||||
|
|
||||||
if (path.endsWith(".class") && !path.endsWith("/module-info.class")) {
|
if (path.endsWith(".class") && !path.endsWith("/module-info.class")) {
|
||||||
out.add(transform(resource, classes));
|
out.add(transform(resource, in));
|
||||||
} else {
|
} else {
|
||||||
out.add(resource);
|
out.add(resource);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,16 @@ public interface ModulePool {
|
|||||||
* @param path A data path
|
* @param path A data path
|
||||||
* @return A ModuleEntry instance or null if the data is not found
|
* @return A ModuleEntry instance or null if the data is not found
|
||||||
*/
|
*/
|
||||||
public Optional<ModuleEntry> findEntry(String path);
|
public Optional<ModuleEntry> findEntry(String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the ModuleEntry for the passed path restricted to supplied context.
|
||||||
|
*
|
||||||
|
* @param path A data path
|
||||||
|
* @param context A context of the search
|
||||||
|
* @return A ModuleEntry instance or null if the data is not found
|
||||||
|
*/
|
||||||
|
public Optional<ModuleEntry> findEntryInContext(String path, ModuleEntry context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the ModulePool contains the given ModuleEntry.
|
* Check if the ModulePool contains the given ModuleEntry.
|
||||||
|
@ -371,6 +371,8 @@ public class JavaTimeSupplementary_ar extends OpenListResourceBundle {
|
|||||||
sharedShortEras },
|
sharedShortEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedShortEras },
|
sharedShortEras },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"\u062c\u0631\u064a\u0646\u062a\u0634{0}" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,6 +308,8 @@ public class JavaTimeSupplementary_be extends OpenListResourceBundle {
|
|||||||
sharedAbbreviatedAmPmMarkers },
|
sharedAbbreviatedAmPmMarkers },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedNarrowAmPmMarkers },
|
sharedNarrowAmPmMarkers },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH.mm;-HH.mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,6 +309,8 @@ public class JavaTimeSupplementary_bg extends OpenListResourceBundle {
|
|||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"\u0413\u0440\u0438\u043d\u0443\u0438\u0447{0}" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,8 @@ public class JavaTimeSupplementary_cs extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+H:mm;-H:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -308,6 +308,8 @@ public class JavaTimeSupplementary_da extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH.mm;-HH.mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,6 +280,8 @@ public class JavaTimeSupplementary_et extends OpenListResourceBundle {
|
|||||||
sharedTimePatterns },
|
sharedTimePatterns },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedNarrowAmPmMarkers },
|
sharedNarrowAmPmMarkers },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH:mm;\u2212HH:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,6 +324,10 @@ public class JavaTimeSupplementary_fi extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"UTC{0}" },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+H.mm;-H.mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,6 +329,10 @@ public class JavaTimeSupplementary_fr extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"UTC{0}" },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH:mm;\u2212HH:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,6 +284,8 @@ public class JavaTimeSupplementary_ga extends OpenListResourceBundle {
|
|||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedNarrowAmPmMarkers },
|
sharedNarrowAmPmMarkers },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"MAG{0}" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,6 +335,8 @@ public class JavaTimeSupplementary_hr extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH:mm; -HH:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,6 +347,8 @@ public class JavaTimeSupplementary_in extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH.mm;-HH.mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,6 +324,10 @@ public class JavaTimeSupplementary_iw extends OpenListResourceBundle {
|
|||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"GMT{0}\u200e" },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"\u200e+HH:mm;-HH:mm\u200e" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,6 +325,8 @@ public class JavaTimeSupplementary_lt extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH:mm;\u2212HH:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,6 +389,8 @@ public class JavaTimeSupplementary_no extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH.mm;-HH.mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,6 +286,8 @@ public class JavaTimeSupplementary_sl extends OpenListResourceBundle {
|
|||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedNarrowAmPmMarkers },
|
sharedNarrowAmPmMarkers },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH.mm;-HH.mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,6 +294,8 @@ public class JavaTimeSupplementary_sq extends OpenListResourceBundle {
|
|||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
{ "roc.narrow.AmPmMarkers",
|
{ "roc.narrow.AmPmMarkers",
|
||||||
sharedAmPmMarkers },
|
sharedAmPmMarkers },
|
||||||
|
{ "timezone.gmtFormat",
|
||||||
|
"Ora e Grenui\u00e7it: {0}" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,6 +386,8 @@ public class JavaTimeSupplementary_sr extends OpenListResourceBundle {
|
|||||||
sharedShortEras },
|
sharedShortEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedShortEras },
|
sharedShortEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HHmm;-HHmm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,6 +345,8 @@ public class JavaTimeSupplementary_sv extends OpenListResourceBundle {
|
|||||||
sharedEras },
|
sharedEras },
|
||||||
{ "roc.short.Eras",
|
{ "roc.short.Eras",
|
||||||
sharedEras },
|
sharedEras },
|
||||||
|
{ "timezone.hourFormat",
|
||||||
|
"+HH:mm;\u2212HH:mm" },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1376,10 +1376,6 @@ class ToolWindow extends JFrame {
|
|||||||
ToolDialog ed = new ToolDialog
|
ToolDialog ed = new ToolDialog
|
||||||
(PolicyTool.getMessage("Error"), tool, this, true);
|
(PolicyTool.getMessage("Error"), tool, this, true);
|
||||||
|
|
||||||
// find where the PolicyTool gui is
|
|
||||||
Point location = ((w == null) ?
|
|
||||||
getLocationOnScreen() : w.getLocationOnScreen());
|
|
||||||
//ed.setBounds(location.x + 50, location.y + 50, 600, 100);
|
|
||||||
ed.setLayout(new GridBagLayout());
|
ed.setLayout(new GridBagLayout());
|
||||||
|
|
||||||
JLabel label = new JLabel(error);
|
JLabel label = new JLabel(error);
|
||||||
|
@ -213,9 +213,9 @@ java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-a
|
|||||||
|
|
||||||
# jdk_security
|
# jdk_security
|
||||||
|
|
||||||
sun/security/pkcs11/ec/TestKeyFactory.java 7157786 generic-all
|
sun/security/pkcs11/ec/TestKeyFactory.java 8026976 generic-all
|
||||||
|
|
||||||
sun/security/krb5/auto/Unreachable.java 7164518 macosx-all no PortUnreachableException on Mac
|
sun/security/krb5/auto/Unreachable.java 7164518 macosx-all
|
||||||
|
|
||||||
sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-all
|
sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-all
|
||||||
|
|
||||||
@ -284,6 +284,7 @@ sun/security/pkcs11/tls/TestPremaster.java 8077138,8023434
|
|||||||
sun/security/krb5/auto/HttpNegotiateServer.java 8038079 generic-all
|
sun/security/krb5/auto/HttpNegotiateServer.java 8038079 generic-all
|
||||||
|
|
||||||
sun/security/tools/keytool/autotest.sh 8130302 generic-all
|
sun/security/tools/keytool/autotest.sh 8130302 generic-all
|
||||||
|
sun/security/ssl/SSLSocketImpl/AsyncSSLSocketClose.java 8161232 macosx-all
|
||||||
|
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
|
102
jdk/test/java/lang/Runtime/Version/VersionProps.java
Normal file
102
jdk/test/java/lang/Runtime/Version/VersionProps.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 SAP SE. All rights reserved.
|
||||||
|
* 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 8160564
|
||||||
|
* @summary check the implementation of VersionProps.versionNumbers()
|
||||||
|
* @run main VersionProps
|
||||||
|
* @author Volker Simonis
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class VersionProps {
|
||||||
|
|
||||||
|
final static String[] validVersions = {
|
||||||
|
"1", "1.2", "1.2.3", "1.2.3.4", "1.0.0.1",
|
||||||
|
"1.10000.1", "1.0.2.0.0.3.0.0.0.4.5.0.0.6",
|
||||||
|
"1000001", "1.2.3.4.5.6.7.8.9.0.9.8.7.6.5.4.3.2.1" };
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
final static List[] validLists = {
|
||||||
|
Arrays.asList(1),
|
||||||
|
Arrays.asList(1, 2),
|
||||||
|
Arrays.asList(1, 2, 3),
|
||||||
|
Arrays.asList(1, 2, 3, 4),
|
||||||
|
Arrays.asList(1, 0, 0, 1),
|
||||||
|
Arrays.asList(1, 10000, 1),
|
||||||
|
Arrays.asList(1, 0, 2, 0, 0, 3, 0, 0, 0, 4, 5, 0, 0, 6),
|
||||||
|
Arrays.asList(1000001),
|
||||||
|
Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1) };
|
||||||
|
|
||||||
|
final static String[] invalidVersions = {
|
||||||
|
"01", "0.1.2", "1.02.3", "1.2.03.4", "1.0.0.1.0",
|
||||||
|
"1.0.1.0.0", "1.00.1", "1.0.1.00", "1.10000." };
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Class<?> versionProps = Class.forName("java.lang.VersionProps");
|
||||||
|
Method parseVersionNumbers =
|
||||||
|
versionProps.getDeclaredMethod("parseVersionNumbers", String.class);
|
||||||
|
parseVersionNumbers.setAccessible(true);
|
||||||
|
|
||||||
|
for (int i = 0; i < validVersions.length; i++) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Integer> li =
|
||||||
|
(List<Integer>)parseVersionNumbers.invoke(null, validVersions[i]);
|
||||||
|
System.out.println(li);
|
||||||
|
if (!validLists[i].equals(li))
|
||||||
|
throw new Exception(li + " != " + validLists[i]);
|
||||||
|
li = Runtime.Version.parse(validVersions[i]).version();
|
||||||
|
if (!validLists[i].equals(li))
|
||||||
|
throw new Exception(li + " != " + validLists[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < invalidVersions.length; i++) {
|
||||||
|
try {
|
||||||
|
List<Integer> li =
|
||||||
|
(List<Integer>)parseVersionNumbers.invoke(null, invalidVersions[i]);
|
||||||
|
throw new Exception(invalidVersions[i] +
|
||||||
|
" not recognized as invalid by VersionProps.parseVersionNumbers()");
|
||||||
|
} catch (InvocationTargetException ex) {
|
||||||
|
if (ex.getCause() instanceof IllegalArgumentException) {
|
||||||
|
System.out.println("OK - caught bad version string " +
|
||||||
|
invalidVersions[i]);
|
||||||
|
} else {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<Integer> li = Runtime.Version.parse(invalidVersions[i]).version();
|
||||||
|
throw new Exception(invalidVersions[i] +
|
||||||
|
" not recognized as invalid by Runtime.Version.parse()");
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -539,6 +539,7 @@ public class DefaultLoggerTest {
|
|||||||
throw new RuntimeException("identical loggers");
|
throw new RuntimeException("identical loggers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final java.util.logging.Logger sink;
|
||||||
final java.util.logging.Logger appSink;
|
final java.util.logging.Logger appSink;
|
||||||
final java.util.logging.Logger sysSink;
|
final java.util.logging.Logger sysSink;
|
||||||
final java.util.logging.Handler appHandler;
|
final java.util.logging.Handler appHandler;
|
||||||
@ -548,10 +549,9 @@ public class DefaultLoggerTest {
|
|||||||
try {
|
try {
|
||||||
appSink = java.util.logging.Logger.getLogger("foo");
|
appSink = java.util.logging.Logger.getLogger("foo");
|
||||||
sysSink = accessSystemLogger.demandSystemLogger("foo");
|
sysSink = accessSystemLogger.demandSystemLogger("foo");
|
||||||
appSink.addHandler(appHandler = new MyHandler());
|
sink = java.util.logging.Logger.getLogger("foo");
|
||||||
sysSink.addHandler(sysHandler = new MyHandler());
|
sink.addHandler(appHandler = sysHandler = new MyHandler());
|
||||||
appSink.setUseParentHandlers(false);
|
sink.setUseParentHandlers(false);
|
||||||
sysSink.setUseParentHandlers(false);
|
|
||||||
provider = LoggerFinder.getLoggerFinder();
|
provider = LoggerFinder.getLoggerFinder();
|
||||||
} finally {
|
} finally {
|
||||||
allowAll.get().set(false);
|
allowAll.get().set(false);
|
||||||
|
@ -299,10 +299,9 @@ public class DefaultLoggerFinderTest {
|
|||||||
|
|
||||||
final java.util.logging.Logger appSink = java.util.logging.Logger.getLogger("foo");
|
final java.util.logging.Logger appSink = java.util.logging.Logger.getLogger("foo");
|
||||||
final java.util.logging.Logger sysSink = accessSystemLogger.demandSystemLogger("foo");
|
final java.util.logging.Logger sysSink = accessSystemLogger.demandSystemLogger("foo");
|
||||||
appSink.addHandler(new MyHandler());
|
final java.util.logging.Logger sink = java.util.logging.Logger.getLogger("foo");
|
||||||
sysSink.addHandler(new MyHandler());
|
sink.addHandler(new MyHandler());
|
||||||
appSink.setUseParentHandlers(VERBOSE);
|
sink.setUseParentHandlers(VERBOSE);
|
||||||
sysSink.setUseParentHandlers(VERBOSE);
|
|
||||||
|
|
||||||
Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
|
Stream.of(args).map(TestCases::valueOf).forEach((testCase) -> {
|
||||||
LoggerFinder provider;
|
LoggerFinder provider;
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -390,6 +390,7 @@ public class DefaultLoggerBridgeTest {
|
|||||||
throw new RuntimeException("identical loggers");
|
throw new RuntimeException("identical loggers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final java.util.logging.Logger sink;
|
||||||
final java.util.logging.Logger appSink;
|
final java.util.logging.Logger appSink;
|
||||||
final java.util.logging.Logger sysSink;
|
final java.util.logging.Logger sysSink;
|
||||||
final MyHandler appHandler;
|
final MyHandler appHandler;
|
||||||
@ -404,10 +405,13 @@ public class DefaultLoggerBridgeTest {
|
|||||||
if (appSink == sysSink) {
|
if (appSink == sysSink) {
|
||||||
throw new RuntimeException("identical backend loggers");
|
throw new RuntimeException("identical backend loggers");
|
||||||
}
|
}
|
||||||
appSink.addHandler(appHandler = new MyHandler());
|
sink = java.util.logging.Logger.getLogger("foo");
|
||||||
sysSink.addHandler(sysHandler = new MyHandler());
|
if (appSink != sink) {
|
||||||
appSink.setUseParentHandlers(VERBOSE);
|
throw new RuntimeException("expected same application logger");
|
||||||
sysSink.setUseParentHandlers(VERBOSE);
|
}
|
||||||
|
|
||||||
|
sink.addHandler(appHandler = sysHandler = new MyHandler());
|
||||||
|
sink.setUseParentHandlers(VERBOSE);
|
||||||
} finally {
|
} finally {
|
||||||
allowAll.get().set(old);
|
allowAll.get().set(old);
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user