Mon, 05 May 2014 19:53:00 -0400
8023697: failed class resolution reports different class name in detail message for the first and subsequent times
Summary: Cache detail message when we cache exception for constant pool resolution.
Reviewed-by: acorn, twisti, jrose
1.1 --- a/src/share/vm/classfile/resolutionErrors.cpp Mon Mar 23 17:57:13 2020 +0000 1.2 +++ b/src/share/vm/classfile/resolutionErrors.cpp Mon May 05 19:53:00 2014 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -32,12 +32,13 @@ 1.11 1.12 // add new entry to the table 1.13 void ResolutionErrorTable::add_entry(int index, unsigned int hash, 1.14 - constantPoolHandle pool, int cp_index, Symbol* error) 1.15 + constantPoolHandle pool, int cp_index, 1.16 + Symbol* error, Symbol* message) 1.17 { 1.18 assert_locked_or_safepoint(SystemDictionary_lock); 1.19 assert(!pool.is_null() && error != NULL, "adding NULL obj"); 1.20 1.21 - ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error); 1.22 + ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error, message); 1.23 add_entry(index, entry); 1.24 } 1.25 1.26 @@ -58,19 +59,26 @@ 1.27 } 1.28 1.29 void ResolutionErrorEntry::set_error(Symbol* e) { 1.30 - assert(e == NULL || _error == NULL, "cannot reset error"); 1.31 + assert(e != NULL, "must set a value"); 1.32 _error = e; 1.33 - if (_error != NULL) _error->increment_refcount(); 1.34 + _error->increment_refcount(); 1.35 +} 1.36 + 1.37 +void ResolutionErrorEntry::set_message(Symbol* c) { 1.38 + assert(c != NULL, "must set a value"); 1.39 + _message = c; 1.40 + _message->increment_refcount(); 1.41 } 1.42 1.43 // create new error entry 1.44 ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool, 1.45 - int cp_index, Symbol* error) 1.46 + int cp_index, Symbol* error, 1.47 + Symbol* message) 1.48 { 1.49 ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool); 1.50 entry->set_cp_index(cp_index); 1.51 - NOT_PRODUCT(entry->set_error(NULL);) 1.52 entry->set_error(error); 1.53 + entry->set_message(message); 1.54 1.55 return entry; 1.56 } 1.57 @@ -79,6 +87,7 @@ 1.58 // decrement error refcount 1.59 assert(entry->error() != NULL, "error should be set"); 1.60 entry->error()->decrement_refcount(); 1.61 + entry->message()->decrement_refcount(); 1.62 Hashtable<ConstantPool*, mtClass>::free_entry(entry); 1.63 } 1.64
2.1 --- a/src/share/vm/classfile/resolutionErrors.hpp Mon Mar 23 17:57:13 2020 +0000 2.2 +++ b/src/share/vm/classfile/resolutionErrors.hpp Mon May 05 19:53:00 2014 -0400 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -38,7 +38,8 @@ 2.11 public: 2.12 ResolutionErrorTable(int table_size); 2.13 2.14 - ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error); 2.15 + ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, 2.16 + Symbol* error, Symbol* message); 2.17 void free_entry(ResolutionErrorEntry *entry); 2.18 2.19 ResolutionErrorEntry* bucket(int i) { 2.20 @@ -55,7 +56,7 @@ 2.21 } 2.22 2.23 void add_entry(int index, unsigned int hash, 2.24 - constantPoolHandle pool, int which, Symbol* error); 2.25 + constantPoolHandle pool, int which, Symbol* error, Symbol* message); 2.26 2.27 2.28 // find error given the constant pool and constant pool index 2.29 @@ -79,10 +80,10 @@ 2.30 private: 2.31 int _cp_index; 2.32 Symbol* _error; 2.33 + Symbol* _message; 2.34 2.35 public: 2.36 - ConstantPool* pool() const { return (ConstantPool*)literal(); } 2.37 - ConstantPool** pool_addr() { return (ConstantPool**)literal_addr(); } 2.38 + ConstantPool* pool() const { return literal(); } 2.39 2.40 int cp_index() const { return _cp_index; } 2.41 void set_cp_index(int cp_index) { _cp_index = cp_index; } 2.42 @@ -90,6 +91,9 @@ 2.43 Symbol* error() const { return _error; } 2.44 void set_error(Symbol* e); 2.45 2.46 + Symbol* message() const { return _message; } 2.47 + void set_message(Symbol* c); 2.48 + 2.49 ResolutionErrorEntry* next() const { 2.50 return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next(); 2.51 }
3.1 --- a/src/share/vm/classfile/systemDictionary.cpp Mon Mar 23 17:57:13 2020 +0000 3.2 +++ b/src/share/vm/classfile/systemDictionary.cpp Mon May 05 19:53:00 2014 -0400 3.3 @@ -185,12 +185,14 @@ 3.4 if (HAS_PENDING_EXCEPTION || klass == NULL) { 3.5 KlassHandle k_h(THREAD, klass); 3.6 // can return a null klass 3.7 - klass = handle_resolution_exception(class_name, class_loader, protection_domain, throw_error, k_h, THREAD); 3.8 + klass = handle_resolution_exception(class_name, throw_error, k_h, THREAD); 3.9 } 3.10 return klass; 3.11 } 3.12 3.13 -Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS) { 3.14 +Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, 3.15 + bool throw_error, 3.16 + KlassHandle klass_h, TRAPS) { 3.17 if (HAS_PENDING_EXCEPTION) { 3.18 // If we have a pending exception we forward it to the caller, unless throw_error is true, 3.19 // in which case we have to check whether the pending exception is a ClassNotFoundException, 3.20 @@ -398,7 +400,7 @@ 3.21 } 3.22 if (HAS_PENDING_EXCEPTION || superk_h() == NULL) { 3.23 // can null superk 3.24 - superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, class_loader, protection_domain, true, superk_h, THREAD)); 3.25 + superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, true, superk_h, THREAD)); 3.26 } 3.27 3.28 return superk_h(); 3.29 @@ -2246,12 +2248,13 @@ 3.30 3.31 // Add entry to resolution error table to record the error when the first 3.32 // attempt to resolve a reference to a class has failed. 3.33 -void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) { 3.34 +void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, 3.35 + Symbol* error, Symbol* message) { 3.36 unsigned int hash = resolution_errors()->compute_hash(pool, which); 3.37 int index = resolution_errors()->hash_to_index(hash); 3.38 { 3.39 MutexLocker ml(SystemDictionary_lock, Thread::current()); 3.40 - resolution_errors()->add_entry(index, hash, pool, which, error); 3.41 + resolution_errors()->add_entry(index, hash, pool, which, error, message); 3.42 } 3.43 } 3.44 3.45 @@ -2261,13 +2264,19 @@ 3.46 } 3.47 3.48 // Lookup resolution error table. Returns error if found, otherwise NULL. 3.49 -Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) { 3.50 +Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which, 3.51 + Symbol** message) { 3.52 unsigned int hash = resolution_errors()->compute_hash(pool, which); 3.53 int index = resolution_errors()->hash_to_index(hash); 3.54 { 3.55 MutexLocker ml(SystemDictionary_lock, Thread::current()); 3.56 ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which); 3.57 - return (entry != NULL) ? entry->error() : (Symbol*)NULL; 3.58 + if (entry != NULL) { 3.59 + *message = entry->message(); 3.60 + return entry->error(); 3.61 + } else { 3.62 + return NULL; 3.63 + } 3.64 } 3.65 } 3.66
4.1 --- a/src/share/vm/classfile/systemDictionary.hpp Mon Mar 23 17:57:13 2020 +0000 4.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon May 05 19:53:00 2014 -0400 4.3 @@ -241,7 +241,7 @@ 4.4 static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS); 4.5 protected: 4.6 // handle error translation for resolve_or_null results 4.7 - static Klass* handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS); 4.8 + static Klass* handle_resolution_exception(Symbol* class_name, bool throw_error, KlassHandle klass_h, TRAPS); 4.9 4.10 public: 4.11 4.12 @@ -549,9 +549,11 @@ 4.13 4.14 // Record the error when the first attempt to resolve a reference from a constant 4.15 // pool entry to a class fails. 4.16 - static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error); 4.17 + static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error, 4.18 + Symbol* message); 4.19 static void delete_resolution_error(ConstantPool* pool); 4.20 - static Symbol* find_resolution_error(constantPoolHandle pool, int which); 4.21 + static Symbol* find_resolution_error(constantPoolHandle pool, int which, 4.22 + Symbol** message); 4.23 4.24 protected: 4.25
5.1 --- a/src/share/vm/oops/constantPool.cpp Mon Mar 23 17:57:13 2020 +0000 5.2 +++ b/src/share/vm/oops/constantPool.cpp Mon May 05 19:53:00 2014 -0400 5.3 @@ -235,14 +235,14 @@ 5.4 5.5 5.6 // The original attempt to resolve this constant pool entry failed so find the 5.7 - // original error and throw it again (JVMS 5.4.3). 5.8 + // class of the original error and throw another error of the same class (JVMS 5.4.3). 5.9 + // If there is a detail message, pass that detail message to the error constructor. 5.10 + // The JVMS does not strictly require us to duplicate the same detail message, 5.11 + // or any internal exception fields such as cause or stacktrace. But since the 5.12 + // detail message is often a class name or other literal string, we will repeat it if 5.13 + // we can find it in the symbol table. 5.14 if (in_error) { 5.15 - Symbol* error = SystemDictionary::find_resolution_error(this_oop, which); 5.16 - guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); 5.17 - ResourceMark rm; 5.18 - // exception text will be the class name 5.19 - const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 5.20 - THROW_MSG_0(error, className); 5.21 + throw_resolution_error(this_oop, which, CHECK_0); 5.22 } 5.23 5.24 if (do_resolve) { 5.25 @@ -262,11 +262,6 @@ 5.26 // Failed to resolve class. We must record the errors so that subsequent attempts 5.27 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). 5.28 if (HAS_PENDING_EXCEPTION) { 5.29 - ResourceMark rm; 5.30 - Symbol* error = PENDING_EXCEPTION->klass()->name(); 5.31 - 5.32 - bool throw_orig_error = false; 5.33 - { 5.34 MonitorLockerEx ml(this_oop->lock()); 5.35 5.36 // some other thread has beaten us and has resolved the class. 5.37 @@ -276,32 +271,9 @@ 5.38 return entry.get_klass(); 5.39 } 5.40 5.41 - if (!PENDING_EXCEPTION-> 5.42 - is_a(SystemDictionary::LinkageError_klass())) { 5.43 - // Just throw the exception and don't prevent these classes from 5.44 - // being loaded due to virtual machine errors like StackOverflow 5.45 - // and OutOfMemoryError, etc, or if the thread was hit by stop() 5.46 - // Needs clarification to section 5.4.3 of the VM spec (see 6308271) 5.47 - } 5.48 - else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) { 5.49 - SystemDictionary::add_resolution_error(this_oop, which, error); 5.50 - this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); 5.51 - } else { 5.52 - // some other thread has put the class in error state. 5.53 - error = SystemDictionary::find_resolution_error(this_oop, which); 5.54 - assert(error != NULL, "checking"); 5.55 - throw_orig_error = true; 5.56 - } 5.57 - } // unlocked 5.58 - 5.59 - if (throw_orig_error) { 5.60 - CLEAR_PENDING_EXCEPTION; 5.61 - ResourceMark rm; 5.62 - const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 5.63 - THROW_MSG_0(error, className); 5.64 - } 5.65 - 5.66 - return 0; 5.67 + // The tag could have changed to in-error before the lock but we have to 5.68 + // handle that here for the class case. 5.69 + save_and_throw_exception(this_oop, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0); 5.70 } 5.71 5.72 if (TraceClassResolution && !k()->oop_is_array()) { 5.73 @@ -597,16 +569,55 @@ 5.74 return true; 5.75 } 5.76 5.77 -// If resolution for MethodHandle or MethodType fails, save the exception 5.78 +Symbol* ConstantPool::exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception) { 5.79 + // Dig out the detailed message to reuse if possible 5.80 + Symbol* message = NULL; 5.81 + oop detailed_message = java_lang_Throwable::message(pending_exception); 5.82 + if (detailed_message != NULL) { 5.83 + message = java_lang_String::as_symbol_or_null(detailed_message); 5.84 + if (message != NULL) { 5.85 + return message; 5.86 + } 5.87 + } 5.88 + 5.89 + // Return specific message for the tag 5.90 + switch (tag.value()) { 5.91 + case JVM_CONSTANT_UnresolvedClass: 5.92 + // return the class name in the error message 5.93 + message = this_oop->unresolved_klass_at(which); 5.94 + break; 5.95 + case JVM_CONSTANT_MethodHandle: 5.96 + // return the method handle name in the error message 5.97 + message = this_oop->method_handle_name_ref_at(which); 5.98 + break; 5.99 + case JVM_CONSTANT_MethodType: 5.100 + // return the method type signature in the error message 5.101 + message = this_oop->method_type_signature_at(which); 5.102 + break; 5.103 + default: 5.104 + ShouldNotReachHere(); 5.105 + } 5.106 + 5.107 + return message; 5.108 +} 5.109 + 5.110 +void ConstantPool::throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS) { 5.111 + Symbol* message = NULL; 5.112 + Symbol* error = SystemDictionary::find_resolution_error(this_oop, which, &message); 5.113 + assert(error != NULL && message != NULL, "checking"); 5.114 + CLEAR_PENDING_EXCEPTION; 5.115 + ResourceMark rm; 5.116 + THROW_MSG(error, message->as_C_string()); 5.117 +} 5.118 + 5.119 +// If resolution for Class, MethodHandle or MethodType fails, save the exception 5.120 // in the resolution error table, so that the same exception is thrown again. 5.121 void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which, 5.122 - int tag, TRAPS) { 5.123 - ResourceMark rm; 5.124 + constantTag tag, TRAPS) { 5.125 + assert(this_oop->lock()->is_locked(), "constant pool lock should be held"); 5.126 Symbol* error = PENDING_EXCEPTION->klass()->name(); 5.127 - MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. 5.128 5.129 - int error_tag = (tag == JVM_CONSTANT_MethodHandle) ? 5.130 - JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError; 5.131 + int error_tag = tag.error_value(); 5.132 5.133 if (!PENDING_EXCEPTION-> 5.134 is_a(SystemDictionary::LinkageError_klass())) { 5.135 @@ -614,20 +625,21 @@ 5.136 // being loaded due to virtual machine errors like StackOverflow 5.137 // and OutOfMemoryError, etc, or if the thread was hit by stop() 5.138 // Needs clarification to section 5.4.3 of the VM spec (see 6308271) 5.139 - 5.140 } else if (this_oop->tag_at(which).value() != error_tag) { 5.141 - SystemDictionary::add_resolution_error(this_oop, which, error); 5.142 + Symbol* message = exception_message(this_oop, which, tag, PENDING_EXCEPTION); 5.143 + SystemDictionary::add_resolution_error(this_oop, which, error, message); 5.144 this_oop->tag_at_put(which, error_tag); 5.145 } else { 5.146 - // some other thread has put the class in error state. 5.147 - error = SystemDictionary::find_resolution_error(this_oop, which); 5.148 - assert(error != NULL, "checking"); 5.149 - CLEAR_PENDING_EXCEPTION; 5.150 - THROW_MSG(error, ""); 5.151 + // some other thread put this in error state 5.152 + throw_resolution_error(this_oop, which, CHECK); 5.153 } 5.154 + 5.155 + // This exits with some pending exception 5.156 + assert(HAS_PENDING_EXCEPTION, "should not be cleared"); 5.157 } 5.158 5.159 5.160 + 5.161 // Called to resolve constants in the constant pool and return an oop. 5.162 // Some constant pool entries cache their resolved oop. This is also 5.163 // called to create oops from constants to use in arguments for invokedynamic 5.164 @@ -655,9 +667,9 @@ 5.165 5.166 jvalue prim_value; // temp used only in a few cases below 5.167 5.168 - int tag_value = this_oop->tag_at(index).value(); 5.169 + constantTag tag = this_oop->tag_at(index); 5.170 5.171 - switch (tag_value) { 5.172 + switch (tag.value()) { 5.173 5.174 case JVM_CONSTANT_UnresolvedClass: 5.175 case JVM_CONSTANT_UnresolvedClassInError: 5.176 @@ -682,10 +694,7 @@ 5.177 case JVM_CONSTANT_MethodHandleInError: 5.178 case JVM_CONSTANT_MethodTypeInError: 5.179 { 5.180 - Symbol* error = SystemDictionary::find_resolution_error(this_oop, index); 5.181 - guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table"); 5.182 - ResourceMark rm; 5.183 - THROW_MSG_0(error, ""); 5.184 + throw_resolution_error(this_oop, index, CHECK_NULL); 5.185 break; 5.186 } 5.187 5.188 @@ -709,7 +718,8 @@ 5.189 THREAD); 5.190 result_oop = value(); 5.191 if (HAS_PENDING_EXCEPTION) { 5.192 - save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); 5.193 + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. 5.194 + save_and_throw_exception(this_oop, index, tag, CHECK_NULL); 5.195 } 5.196 break; 5.197 } 5.198 @@ -725,7 +735,8 @@ 5.199 Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD); 5.200 result_oop = value(); 5.201 if (HAS_PENDING_EXCEPTION) { 5.202 - save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL); 5.203 + MonitorLockerEx ml(this_oop->lock()); // lock cpool to change tag. 5.204 + save_and_throw_exception(this_oop, index, tag, CHECK_NULL); 5.205 } 5.206 break; 5.207 } 5.208 @@ -756,7 +767,7 @@ 5.209 5.210 default: 5.211 DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", 5.212 - this_oop(), index, cache_index, tag_value) ); 5.213 + this_oop(), index, cache_index, tag.value())); 5.214 assert(false, "unexpected constant tag"); 5.215 break; 5.216 }
6.1 --- a/src/share/vm/oops/constantPool.hpp Mon Mar 23 17:57:13 2020 +0000 6.2 +++ b/src/share/vm/oops/constantPool.hpp Mon May 05 19:53:00 2014 -0400 6.3 @@ -823,9 +823,13 @@ 6.4 static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS); 6.5 6.6 static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS); 6.7 - static void save_and_throw_exception(constantPoolHandle this_oop, int which, int tag_value, TRAPS); 6.8 static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS); 6.9 6.10 + // Exception handling 6.11 + static void throw_resolution_error(constantPoolHandle this_oop, int which, TRAPS); 6.12 + static Symbol* exception_message(constantPoolHandle this_oop, int which, constantTag tag, oop pending_exception); 6.13 + static void save_and_throw_exception(constantPoolHandle this_oop, int which, constantTag tag, TRAPS); 6.14 + 6.15 public: 6.16 // Merging ConstantPool* support: 6.17 bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
7.1 --- a/src/share/vm/utilities/constantTag.cpp Mon Mar 23 17:57:13 2020 +0000 7.2 +++ b/src/share/vm/utilities/constantTag.cpp Mon May 05 19:53:00 2014 -0400 7.3 @@ -76,6 +76,20 @@ 7.4 } 7.5 7.6 7.7 +jbyte constantTag::error_value() const { 7.8 + switch (_tag) { 7.9 + case JVM_CONSTANT_UnresolvedClass: 7.10 + return JVM_CONSTANT_UnresolvedClassInError; 7.11 + case JVM_CONSTANT_MethodHandle: 7.12 + return JVM_CONSTANT_MethodHandleInError; 7.13 + case JVM_CONSTANT_MethodType: 7.14 + return JVM_CONSTANT_MethodTypeInError; 7.15 + default: 7.16 + ShouldNotReachHere(); 7.17 + return JVM_CONSTANT_Invalid; 7.18 + } 7.19 +} 7.20 + 7.21 const char* constantTag::internal_name() const { 7.22 switch (_tag) { 7.23 case JVM_CONSTANT_Invalid :
8.1 --- a/src/share/vm/utilities/constantTag.hpp Mon Mar 23 17:57:13 2020 +0000 8.2 +++ b/src/share/vm/utilities/constantTag.hpp Mon May 05 19:53:00 2014 -0400 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -109,6 +109,7 @@ 8.11 } 8.12 8.13 jbyte value() const { return _tag; } 8.14 + jbyte error_value() const; 8.15 jbyte non_error_value() const; 8.16 8.17 BasicType basic_type() const; // if used with ldc, what kind of value gets pushed?
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/runtime/ClassResolutionFail/Property.java Mon May 05 19:53:00 2014 -0400 9.3 @@ -0,0 +1,27 @@ 9.4 +/* 9.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. 9.11 + * 9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.15 + * version 2 for more details (a copy is included in the LICENSE file that 9.16 + * accompanied this code). 9.17 + * 9.18 + * You should have received a copy of the GNU General Public License version 9.19 + * 2 along with this work; if not, write to the Free Software Foundation, 9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.21 + * 9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 9.23 + * or visit www.oracle.com if you need additional information or have any 9.24 + * questions. 9.25 + */ 9.26 + 9.27 +// Class PropertySuper is not found. 9.28 + 9.29 +public class Property extends PropertySuper { 9.30 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/runtime/ClassResolutionFail/PropertySuper.java Mon May 05 19:53:00 2014 -0400 10.3 @@ -0,0 +1,28 @@ 10.4 +/* 10.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 + * 10.8 + * This code is free software; you can redistribute it and/or modify it 10.9 + * under the terms of the GNU General Public License version 2 only, as 10.10 + * published by the Free Software Foundation. 10.11 + * 10.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.15 + * version 2 for more details (a copy is included in the LICENSE file that 10.16 + * accompanied this code). 10.17 + * 10.18 + * You should have received a copy of the GNU General Public License version 10.19 + * 2 along with this work; if not, write to the Free Software Foundation, 10.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.21 + * 10.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 10.23 + * or visit www.oracle.com if you need additional information or have any 10.24 + * questions. 10.25 + */ 10.26 + 10.27 +// Class PropertySuper should be removed. 10.28 + 10.29 +public class PropertySuper { 10.30 + PropertySuper() { System.out.println("remove me for NoClassDefFoundError"); } 10.31 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/test/runtime/ClassResolutionFail/TestClassResolutionFail.java Mon May 05 19:53:00 2014 -0400 11.3 @@ -0,0 +1,57 @@ 11.4 +/* 11.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + */ 11.26 + 11.27 +/* 11.28 + * @test TestClassResolutionFail 11.29 + * @bug 8023697 11.30 + * @summary This tests that failed class resolution doesn't report different class name in detail message for the first and subsequent times 11.31 + */ 11.32 + 11.33 +import java.io.File; 11.34 + 11.35 +public class TestClassResolutionFail { 11.36 + static String message; 11.37 + public static void test1() throws RuntimeException { 11.38 + try { 11.39 + Property p = new Property(); 11.40 + } catch (LinkageError e) { 11.41 + message = e.getMessage(); 11.42 + } 11.43 + try { 11.44 + Property p = new Property(); 11.45 + } catch (LinkageError e) { 11.46 + System.out.println(e.getMessage()); 11.47 + if (!e.getMessage().equals(message)) { 11.48 + throw new RuntimeException("Wrong message: " + message + " != " + e.getMessage()); 11.49 + } 11.50 + } 11.51 + } 11.52 + public static void main(java.lang.String[] unused) throws Exception { 11.53 + // Remove PropertySuper class 11.54 + String testClasses = System.getProperty("test.classes", "."); 11.55 + File f = new File(testClasses + File.separator + "PropertySuper.class"); 11.56 + f.delete(); 11.57 + test1(); 11.58 + } 11.59 +} 11.60 +