RFR: 8298065: Provide more information in message of NoSuchFieldError [v5]

Ioi Lam iklam at openjdk.org
Tue Jan 3 19:51:54 UTC 2023


On Fri, 23 Dec 2022 21:38:21 GMT, Matias Saavedra Silva <matsaave at openjdk.org> wrote:

>> A java.lang.NoSuchFieldError is typically thrown when you remove a field but do not recompile the client code that calls the field. However, the message does not indicate in which class the field was not found. 
>> 
>> Additionally, java.lang.NoSuchFieldError is thrown if the field is still present but the types are incompatible. For example, if a field is first defined as int, and later changed to long without recompiling the client. The error text has been expanded to include the class name and field type. Verified with tier 1-4 tests.
>> 
>> Old output:
>> `Exception in thread "main" java.lang.NoSuchFieldError: x
>>         at NoSuchFieldMain.main(NoSuchFieldMain.java:3)`
>> Example output:
>> `Exception in thread "main" java.lang.NoSuchFieldError: Class Other does not have field 'int x'
>>         at NoSuchFieldMain.main(NoSuchFieldMain.java:3)`
>> 
>> The added test considers different types of fields like primitives, arrays, and references.
>
> Matias Saavedra Silva has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Ioi and David comments

Changes requested by iklam (Reviewer).

src/hotspot/share/oops/symbol.cpp line 308:

> 306:   }
> 307: }
> 308: 

The SignatureStream for field refs should have exactly one element, and must not be a return type, so this function should be tightened (so it will assert on inputs such as `(I)V` or  `()L/java/lang.Object;`, 
 

assert(!Signature::is_method(this), "must be a field signature");
SignatureStream ss(this, false); 
assert(!ss.is_done(), "must have at least one element in field ref");
assert(!at_return_type(), "field ref can not be a return type");

if (ss.is_array()) {
  print_array(os, ss);
} else if (ss.is_reference()) {
  print_class(os, ss);
} else {
  os->print("%s", type2name(ss.type()));
}

#ifdef ASSERT
ss.next();
assert(ss.is_done(), "must have at most one element in field ref");
#endif

test/hotspot/jtreg/runtime/linkResolver/NoSuchFieldPrimitive.jasm line 61:

> 59:   public static final InnerClass Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles;
> 60: 
> 61: } // end Class NoSuchFieldPrimitive

These jasm test cases are too complicated and contain a lot of details unrelated to what you're testing. They should be simplified as:


/*
public class NoSuchFieldPrimitive {
    // static int x;
    public NoSuchFieldPrimitive() {
       x = 123;
    }
}
*/

super public class NoSuchFieldPrimitive
	version 65:0
{
  // REMOVED static Field x:I;

  public Method "<init>":"()V"
	stack 2 locals 2
  {
		aload_0;
		invokespecial	Method java/lang/Object."<init>":"()V";
		bipush	123;
		putstatic	Field x:"I";
		return;
  }

-------------

PR: https://git.openjdk.org/jdk/pull/11745


More information about the hotspot-runtime-dev mailing list