hotspot/src/share/vm/classfile/defaultMethods.cpp
changeset 22232 26acfad336c0
parent 21913 0e2fd7282ac6
child 22233 f0028de67b30
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp	Fri Dec 13 09:25:44 2013 +0100
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp	Mon Dec 16 08:24:33 2013 -0500
@@ -349,6 +349,7 @@
   }
 
   Symbol* generate_no_defaults_message(TRAPS) const;
+  Symbol* generate_method_message(Symbol *klass_name, Method* method, TRAPS) const;
   Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const;
 
  public:
@@ -414,21 +415,25 @@
       }
     }
 
-    if (qualified_methods.length() == 0) {
-      _exception_message = generate_no_defaults_message(CHECK);
+    if (num_defaults == 0) {
+      if (qualified_methods.length() == 0) {
+        _exception_message = generate_no_defaults_message(CHECK);
+      } else {
+        assert(root != NULL, "Null root class");
+        _exception_message = generate_method_message(root->name(), qualified_methods.at(0), CHECK);
+      }
       _exception_name = vmSymbols::java_lang_AbstractMethodError();
     // If only one qualified method is default, select that
     } else if (num_defaults == 1) {
         _selected_target = qualified_methods.at(default_index);
     } else if (num_defaults > 1) {
-      _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
-      _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
+       _exception_message = generate_conflicts_message(&qualified_methods,CHECK);
+       _exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
       if (TraceDefaultMethods) {
         _exception_message->print_value_on(tty);
         tty->print_cr("");
       }
     }
-    // leave abstract methods alone, they will be found via normal search path
   }
 
   bool contains_signature(Symbol* query) {
@@ -486,6 +491,19 @@
   return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL);
 }
 
+Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method, TRAPS) const {
+  stringStream ss;
+  ss.print("Method ");
+  Symbol* name = method->name();
+  Symbol* signature = method->signature();
+  ss.write((const char*)klass_name->bytes(), klass_name->utf8_length());
+  ss.print(".");
+  ss.write((const char*)name->bytes(), name->utf8_length());
+  ss.write((const char*)signature->bytes(), signature->utf8_length());
+  ss.print(" is abstract");
+  return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL);
+}
+
 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
   stringStream ss;
   ss.print("Conflicting default methods:");