• Post Reply Bookmark Topic Watch Topic
  • New Topic

Static methods & inheritance – java.lang.IllegalAccessError not found at compile-time  RSS feed

 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have file structure and code like this:

../inside/A.java



../inside/B.java



../inside/C.java



../Z.java



At line with comment there is no error at compile-time but at runtime there is IllegalAccesError.

What is the true reason for this behavior?

I have found a topic at StackOverflow.com – http://stackoverflow.com/questions/32422923/why-does-java-bind-variables-at-compile-time – where in the first answer there is maybe mentioned the reason but I am definitely not sure it is.
 
Peter Muster
Ranch Hand
Posts: 74
5
Eclipse IDE Python Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Static methods are not inherited and I don't see any relation to the stackoverflow link you posted.


I declared A, B and C the same as you, B extends A and C extends B. I do not get the error when I execute the code with Java7 or Java8 (using Eclipse IDE on Windows). I assume the error is related to some external circumstances (your Java version, your IDE, any other relevant factors). Can't say what the problem is though but in my opinion the code should work fine according to Java Language Specification.

If you can continuously reproduce the error, try to modify your code and see if the problem persists. I'm curious if your code still raises the error if you remove the inheritance (extends clause).
 
Dave Tolls
Ranch Foreman
Posts: 3056
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I get the same error in 1.7.0_79.
My initial thought is that for some reason the compiler can't spot that C.someStaticMethod() is not actually allowed, possibly because it thinks it might be referring to the one in B, and only when its executed is it clear that the one in C is the one that should be run, but can't?
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Christian Pflugradt wrote:Static methods are not inherited . . .
Let's see what the Java® Language Specification (=JLS) says.
that JLS sectiomn wrote:A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:
What yu said earlier would appear to be mistaken, I am afraid.
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Christian Pflugradt

As others said the error definitely does exists. Maybe you have just do not keep the file/directory structure as I posted.
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Dave Tolls

I am thinking something as you do. If you will be using Eclipse the error will be marked – http://stackoverflow.com/questions/36676772/static-methods-inheritance-java-lang-illegalaccesserror-not-found-at-compile; I compile at cmd with just javac.exe.

But I am wondering what JLS feature is causing this.

 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Go through the details for protected access. That may not be a problem if all those classes are in the same package (or all in the unnamed package).
Also look up the details of IllegalAccessError.
That API link wrote: Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.
Have you been compiling C after B in such a way as to introduce some incompatibility? Or using hex editors?
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Campbell Ritchie

I have compiled class' in order A, B, C, Z. That JLS precept I already know. Also I did not use any hex editor.
 
Dave Tolls
Ranch Foreman
Posts: 3056
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I can stick those classes into IntelliJ as is, and I'll get that error.
Can't see how it could compile C after Z in that case as Z wouldn't compile at all without C.
 
Peter Muster
Ranch Hand
Posts: 74
5
Eclipse IDE Python Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Christian Pflugradt wrote:Static methods are not inherited . . .
Let's see what the Java® Language Specification (=JLS) says.
that JLS sectiomn wrote:A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:
What yu said earlier would appear to be mistaken, I am afraid.

My bad! Learnt something new.

I understand now what the problem is. I could not reproduce it because I didn't keep Z in a separate package.

I changed my code so that Z is in the default package (Eclipse notation) and A, B and C are in the same sub package. With that structure the I cannot compile the code at all however. That's how it should be I guess. I used Eclipse with jdk1.7.0_79 and jdk1.8.0_66 and with both compilers Eclipse marks the errornous line and states "The method someStaticMethod() from the type C is not visible". So I guess Eclipse compiles the files in such order that the situation is not reproducible there.

Invoking javac directly though...

C:\test>"c:\Program Files\Java\jdk1.7.0_79\bin\javac.exe" test2\A.java
C:\test>"c:\Program Files\Java\jdk1.7.0_79\bin\javac.exe" test2\B.java
C:\test>"c:\Program Files\Java\jdk1.7.0_79\bin\javac.exe" test2\C.java
C:\test>"c:\Program Files\Java\jdk1.7.0_79\bin\javac.exe" Z.java

C:\test>"c:\Program Files\Java\jdk1.7.0_79\bin\java.exe" Z.class
Error: Could not find or load main class Z.class

C:\test>"c:\Program Files\Java\jdk1.7.0_79\bin\java.exe" Z
Exception in thread "main" java.lang.IllegalAccessError: tried to access method
test2.C.someStaticMethod()V from class Z

I don't an explanation for this behaviour but I can confirm that error is reproducible!
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have already asked at Oracle Community (https://community.oracle.com/thread/3920224) but till now I have no answer.
 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

First, please do not mix using packages and the default package. The compiler doesn't seem very good at this -- and sometimes messes up.


Anyway, the rule is section 6.2.2 ... https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.

In my opinion, the reason for the rule was probably more for non-static methods, but it should work for static methods as well. Basically, the rule is this... if a class wants to access a protected method of another class, and this another class is in a different package, then the class must be "responsible for the implementation".

To be "responsible", the code in the class must use a reference that IS-A that another class in order to access code of that another class. In this example, the Z class IS-A A class, and IS-A B class, but is not IS-A C class. Hence, the Z class cannot access protected methods of the C class.

Henry
 
Dave Tolls
Ranch Foreman
Posts: 3056
37
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think the question is "why is this an error".
The question is "why does the compiler not pick this up".
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
@Henry Wong

As Dave Tolls said I would like to know why IllegalAccessError is no found at compile-time but only at run-time.

 
Steffe Wilson
Ranch Hand
Posts: 165
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interesting thread. I tried a few things myself. First I moved class Z to its own named package and moved the three method calls into an instance method of Z.

This didn't make any difference; javac still allowed it all to compile and the JVM threw IllegalAccessError on the third call.

If I removed the "extends B" clause from Z then javac correctly flagged that the three methods were not visible for Z to call.

Then I tried removing the definition of someStaticMethod() from class C and, as expected, the call to C.someStaticMethod() from Z succeeded because java invokes the class B definition of the method (because class C extends B, the B version of the method is accessible to Z and it is no longer hidden).

I then moved from command line over to eclipse and, as others have said, under eclipse the same code generated a warning as soon as I typed in the offending line (it reported someStaticMethod() in C was not visible for the call). This puzzled me and I wondered if more warnings were enabled when eclipse invoked javac, but not so: what I hadn't previously appreciated is that eclipse has its own built-in compiler (ECJ) which is completely independent of javac.

So after all that, and a lot of head scratching, I have come to the same conclusion as Dave Tolls in an earlier post, that it seems likely that the observed behaviour is a consequence of a javac compiler deficiency.
 
Campbell Ritchie
Marshal
Posts: 56525
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steffe Wilson wrote:. . . a consequence of a javac compiler deficiency.
If you are worried about compilers, then there is only one things to do: run Eclipse. It has a different compiler.

It ran without warning error or exception. Except that I had to write /** Class which should never have been written */ or similar to avoid lack of documentation warnings.
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So as @Steffe Wilson said this is probably bug in javac and it is probably not it's feature.
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Petr Omáčka wrote:

At line with comment there is no error at compile-time but at runtime there is IllegalAccesError.

What is the true reason for this behavior?


Correct me if I'm wrong, but Z is NOT a subclass of C, whether directly or indirectly; so inside.C.someStaticMethod() is not inherited.
Furthermore, Z is in a different package (in your case the default package) than C, and inside.C.someStaticMethod() is declared protected.
That's why inside.C.someStaticMethod() is simply not accessible.
 
Petr Omáčka
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:
Petr Omáčka wrote:

At line with comment there is no error at compile-time but at runtime there is IllegalAccesError.

What is the true reason for this behavior?


Correct me if I'm wrong, but Z is NOT a subclass of C, whether directly or indirectly; so inside.C.someStaticMethod() is not inherited.
Furthermore, Z is in a different package (in your case the default package) than C, and inside.C.someStaticMethod() is declared protected.
That's why inside.C.someStaticMethod() is simply not accessible.


I know why C.someStaticMethod() is not accessible but I was wondering why the exception occurs at run-time not at compile-time.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!