IllegalAccessError:
This java.lang.illegalAccessError is thrown when we try to access a private field,class or method.Usually this error is caught by compiler.If this error is thrown at run-rime then the class must be incompatibly changed.This is the reason why this error is a direct subclass of IncomaptibleClassChangeError.
This error commonly occurs when we use third-party libraries (external packages) in our application. Normally using an external library in your application does not cause any error if it is compatible with the existing classes (more precisely existing binaries of those classes).
If it is incompatible with the existing binaries then an instance of sub class of IncompatibleClassChange Error will be thrown and specifically an instance of illegalAccessError will be thrown when we try to access a private field,method,class or interface.
See the following examples to have an idea about this error.
Program:
class C
{
static int c=20;
public void display(String a)
{
System.out.println(a);
}
}
{
static int c=20;
public void display(String a)
{
System.out.println(a);
}
}
class D extends C
{
public static void main(String args[])
{
c=45;
System.out.println(c);
C cobj=new C();
System.out.println(cobj.c);
cobj.display("Hello");
}
}
{
public static void main(String args[])
{
c=45;
System.out.println(c);
C cobj=new C();
System.out.println(cobj.c);
cobj.display("Hello");
}
}
Let us analyze this program in detail to understand when this error will be thrown.If you compile and execute this program it will work fine.But if you change any field or method in class C to private and "recompile the class C alone" without recompiling all the classes at one shot then you will be left in a awkward situation.
Note:
One thing i forgot to mention before is that this error will also occur when we try to modify the value of the field which is declared to be final.
So, it seems obvious that after all this error is thrown because of not recompiling the class files as a whole.Now,in order to find this error at compile-time you have to recompile all the class files at one shot.But at some occasions this error will not be identified even if you recompile all the classes and the reason is due to the availability of two-different version of the package in the system.
Before explaining further i would like to tell you one thing that some peoples tends to place their external packages(third-party libraries-usually an archive file) in the extension libraries and also in bootstrap libraries to avoid class path settings.
The remaining of this post is meant for those peoples Who may "accidentally" do like as follows?
The remaining of this post is meant for those peoples Who may "accidentally" do like as follows?
Have a look at what am i going to do here? Here i have created three different version(1 original version as described above and two new Versions) of the class C as follows;
Version 1:
class C
{
private static int c=20;
private void display(String a)
{
System.out.println(a);
}
}
Here i have changed the access modifier of field c (static int c=20) and method display() into private.
Version2:
class C
{
final static int c=20;
public void display(String a)
{
System.out.println(a);
}
}
Here i have changed the type of field c into final.
Now i am going to pack these three different versions into three different jar files like pack1(original version),pack2(version 1),pack3 (version 2).
C:\blog>jar -cvf Pack1.jar C.class
added manifest
adding: C.class(in = 448) (out= 301)(deflated 32%)
C:\blog>jar -cvf Pack2.jar C.class
added manifest
adding: C.class(in = 448) (out= 300)(deflated 33%)
C:\blog>jar -cvf Pack3.jar C.class
added manifest
adding: C.class(in = 412) (out= 291)(deflated 29%)
added manifest
adding: C.class(in = 448) (out= 301)(deflated 32%)
C:\blog>jar -cvf Pack2.jar C.class
added manifest
adding: C.class(in = 448) (out= 300)(deflated 33%)
C:\blog>jar -cvf Pack3.jar C.class
added manifest
adding: C.class(in = 412) (out= 291)(deflated 29%)
Now if i place the Pack1.jar in jre/lib/ext and the Pack2.jar file in class path then while compiling the source file compiler will resolve the references using Pack1.jar since it is available in the extension library itself and as soon as the class file is found compiler will stop searching for classes further in class path.
So in this case JVM has no choice and it has to make use of the available reference (class C) in the Version 1 of the package that is pointed by class path.This is the reason why compiler does not show any error and the JVM shows this error during run-time.
Output:
C:\>cd blog
C:\blog>set classpath=c:\blog\Pack2.jar;c:\blog\Pack3.jar;
C:\blog>javac D.java
C:\blog>java D
Exception in thread "main" java.lang.IllegalAccessError: tried to access field C
.c from class D
at D.main(D.java:5)
So to avoid this kind of error, i suggest you to remove the older version of the package from the bootstrap library or extension library and use only the class path to point to the third-party libraries.
1 comments:
Thanks, this is generally helpful.
Still, I followed step-by-step your method in this Java online training
Java training
Post a Comment