NoSuchFieldError:
I guess you may all be familiar with this error,"which is thrown when we try to access a field which does not exist in the class,interface or enum".You may think if we try to access a unavailable field then at the compile-time itself you would be alerted of this error then how come this error is thrown at run-time.
In most of the cases this error is thrown when we use third-party libraries in our application and i will explain you how in this post.
This error is thrown because of binary incompatibility,which arises when we modify a class in such a way that the class is ended up in an inconsistent state.
The main reason for this error to be thrown at run-time is "that you may have accidentally (indeed purposefully) deleted a field(public or protected) from the class, or interface and recompiled the edited class or interface alone."
As a result,pre-existing classes that has symbolic reference to this field will have no idea about the deletion of the field.So if you execute the class without recompiling it then at the run-time only you will be shown this error message.
Have a look at the following program to understand.
Class C
class C
{
static int c=20;
}
Class D
class D extends C
{
public static void main(String args[])
{
System.out.println(c);
}
}
This program will run without showing any error. Now If i delete the field c from class C(static int c=20) and recompile it alone then class D would not be aware of the changes made in the class C. This is the reason why java.lang.NoSuchFieldError is thrown when i execute the class D.
This error also applies to enumerated types,because if you delete the enum constant and if you try to access the constant without recompiling the class to be executed,you will get this error.See how
class D extends C
{
public static void main(String args[])
{
System.out.println(c);
}
}
Program:
import java.util.*;
public class Nosuch
{public static void main(String[] args)
{
Level l=Level.LOW;
System.out.println(l.toString());
}
}
enum Level
{LOW,MEDIUM,HIGH;
}
If i delete the enum constant "LOW " from the enum declaration and recompile the Level.java file alone and execute the class Nosuch then you will get this error.
Exception in thread "main" java.lang.NoSuchFieldError: LOW
at Nosuch.main(Nosuch.java:7)
Thus it is obvious that if we compile the classes as a whole then at the compile-time itself you would get this error.So you can make the necessary changes to correct those errors.
An important thing to be noted here is that we people mostly would not do like this and you may ask me then when will this error be thrown?
As i have said before mostly this kind of error is thrown when we use third-party libraries (packages) in our application. Because we have no idea about the changes made in those libraries and if you use those library classes without recompiling the application as a whole then this error would be thrown.
When re-compilation also becomes ineffective?
There are certain situations at which this exception will not be identified by the compiler even if you Re-compile it as a whole.If this is the case for you then you should have to check your classpath settings and most importantly extension libraries (jre/lib/ext) and bootstrap libraries which is the default location,where the compiler will look for classes when resolving references.
"If you have older version of the third-party packages in the extension libraries or in bootstrap libraries and newer version of the package in the class path then compiler will not show this error because while resolving references older version would be used since it is available in the system libraries itself (where class files are first searched)and during execution newer version might be used".
So ensure that two different versions of the same package does not exist in your class path and in the extension libraries.It is advisable to remove the older version completely from the system.
0 comments:
Post a Comment