Recently I've faced a problem getting a runtime error java.lang.IllegalAccessError when trying to access from inner class a protected field declared in outer's parent class that was loaded by a different class loader. Briefly:
- Class 
Parenthas protected fieldp. - Class 
OuterextendsParent. - Class 
Inneris an inner class defined in classOuter. - Inside 
Innerclass there's a code:Outer.this.p. - All classes are declared in the same package.
 
Normally it's compiled and runs fine until Parent and Outer class are loaded by different class loaders. In this case we get java.lang.IllegalAccessError when trying to access Outer.this.p from Inner.
I found an old bug report (which appeared to be a feature) describing this behavior:
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6258289
But resolution sounds contradictive to me:
The key is that in the failing case the inner class isn't in the same package (and isn't a subclass of) ConcreteCommand/AbstractCommand. This is simply a violation of the Java specification for protected classes.
It sounds correct. But if we declare Parent and Outer classes in different packages but load with the single class loader (simply create sample console app without any jar loadings) we don't get any errors. So technically it's a violation of Java spec for protected classes but since we use an inner class it works.
So we have different behavior for two cases of "different packages".
- Declared in different packages, loaded by single class loader - OK.
 - Declared in single package, loaded by different class loaders - NOT OK.
 
Could someone give a clear explanation of how inner class gets access to parent's fields and why it works differently for two cases?