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

Matias Saavedra Silva matsaave at openjdk.org
Wed Jan 11 19:05:17 UTC 2023


On Thu, 22 Dec 2022 23:06:57 GMT, Ioi Lam <iklam at openjdk.org> wrote:

>> Matias Saavedra Silva has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   Improved style and cleanup
>
> I think we should change the wording of the error message. There was a reason (or maybe it's by accident) that the original message was vague. It just mentioned the name of the field without the name of the class used by the FieldRef. Consider the following example:
> 
> 
> class Base {
>   int foo, bar;
> }
> 
> class Top extends Base {
>   public static void main(String args[]) {
>     Top t = new Top();
>     t.foo = 1;
>     t.bar = 1;
>   }
> }
> 
> 
> If it's rewritten to remove the `bar` field
> 
> 
> super class Base
> 	version 63:0
> {
>   Field foo:I;
>   //Field bar:I;
> 
>   Method "<init>":"()V"
> 	stack 1 locals 1
>   {
> 		aload_0;
> 		invokespecial	Method java/lang/Object."<init>":"()V";
> 		return;
>   }
> }
> 
> super class Top extends Base
> 	version 63:0
> {
>   Method "<init>":"()V"
> 	stack 1 locals 1
>   {
> 		aload_0;
> 		invokespecial	Method Base."<init>":"()V";
> 		return;
>   }
>   public static Method main:"([Ljava/lang/String;)V"
> 	stack 2 locals 2
>   {
> 		new	class Top;
> 		dup;
> 		invokespecial	Method "<init>":"()V";
> 		astore_1;
> 		aload_1;
> 		iconst_1;
> 		putfield	Field Top.foo:"I";
> 		aload_1;
> 		iconst_1;
> 		putfield	Field Top.bar:"I";  // Javac outputs "Top" as the class, not "Base"
> 		return;
>   }
> } 
> 
> 
> The current output is:
> 
> 
> $ java -cp . Top
> Exception in thread "main" java.lang.NoSuchFieldError: bar
> 	at Top.main(top.jasm)
> 
> 
> After this PR, if we output this:
> 
> 
> $ java -cp . Top
> Exception in thread "main" java.lang.NoSuchFieldError: Class Top does not have field 'int bar'
> 	at Top.main(top.jasm)
> 
> 
> I think this would be misleading. Top.java was written with the knowledge that "bar" is a field inherited from the "Base" class (**). During execution, "Base" is replaced by an incompatible version that no longer has such a field. However, the error message blames the "Top" class, even when the problem is in the "Base" class.
> 
> It would be more correct to say this:
> 
> 
> NoSuchFieldError: field 'int bar' cannot be be found in class Top or any of its super types
> 
> 
> ** Note: javac generates the FieldRef as "Top.bar" so that the code will work as long as "bar" is declared in "Top" or any of its super types. It doesn't mandate which class must declare this field. This allows future refactoring of the class hierarchy.  For example, the "Base" class could be refactored to move all of its declared fields to a super type of "Base".

Thank you for the comments and corrections @iklam, @dholmes-ora, @coleenp, and @turbanoff !

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

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


More information about the hotspot-runtime-dev mailing list