Discussion:
ClassLoading problem: IllegalAccessError when loading parent interface
Horaci Macias
2004-05-13 09:04:25 UTC
Permalink
I've got two classloaders, say parent and child. They both use the default delegation model and parent is the parent classloader of child.
Now imagine the following interface and class:

package testing.java.net.url;
interface Intf
{
void a();
}

package testing.java.net.url;
public class Impl implements Intf{
void a(){}
}

They are each in a separate .java file, and the interface is in the parent classloader whereas the class is in the child classloader. I thought that trying to load the class from the child classloader shouldn't be a problem, but in fact it is. I'm getting the following exception when loading Impl:

java.lang.IllegalAccessError: class testing.java.net.url.Impl cannot access its superinterface testing.java.net.url.Intf
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

Note that the interface is not public, but it is in the same package as the implementation. If I make the interface public then everything works fine, but shouldn't it also work with the interface as is it? Am I missing something?

Thanks in advance,

Horaci



This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 09:17:50 UTC
Permalink
Hi,

One thought is that if a parent/child class loader who initiates the loading
is a custom one and if it is itself in a different package from the one were
a package private interface is defined, then it may cause a security/access
failure
Cheers, Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Horaci Macias
2004-05-13 09:48:56 UTC
Permalink
really??
but if I load both interface and class using the same classloader, the interface is still in a different package from the classloader but the loading works fine...
according to your explanation it shouldn't work, should it?

Thanks again,

Horaci

-----Original Message-----
From: Sergey Beryozkin [mailto:***@ZANDAR.COM]
Sent: 13 May 2004 10:18
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-JAVA] ClassLoading problem: IllegalAccessError
when loading parent interface


Hi,

One thought is that if a parent/child class loader who initiates the loading
is a custom one and if it is itself in a different package from the one were
a package private interface is defined, then it may cause a security/access
failure
Cheers, Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com


This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 10:10:35 UTC
Permalink
I don't know. I was thinking about it when I sent you a reply, after all, a
system class loader can load user defined classes without problems, but I
though that may be it can do so because it's a system library class and thus
has all privileges.
You're saying that it works fine if both definitions are loaded by the same
class loader but it doesn't work with two class loaders. If so, and assuming
my earlier suggestion is wrong, then I'd risk to say that there's something
wrong with your implementation of a child-parent delegation. Wait for the
other part of the world to wake up, they have a lot of expertise there in
this area !
Cheers, Sergey

really??
but if I load both interface and class using the same classloader, the
interface is still in a different package from the classloader but the
loading works fine...
according to your explanation it shouldn't work, should it?

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Eyal Katz
2004-05-14 04:11:37 UTC
Permalink
Hi all,

I managed to miraculously stumb with the following Error:
java.lang.NoClassDefError: java/lang/Object

Let me explain the scenario:
1. My company develop a Swing-based GUI application
2. Our customers (mass-audience) receive an installation CD from us.
3. The Install CD has a file called Setup.exe
4. Setup.exe is an InstallShield application which copies our product to
a specified directory
5. I'm saying "copies" because all the install does is copy a directory
with our jars and with a bundled jre into the destination folder (and
also creates a shortcut on the desktop)
6. After install, Our users click the shortcut and our app. is running
from *OUR* JRE (1.4.1), regardless of other versions of java installed
on the users' machine.

This strategy (which your comments about it would be very welocmed)
proved to work great - we had many cases where nostalgic and moderen jre
versions (from 1.0.8 to 1.5b) were installed on our clients' computers
and our application happily ignored them

Only the other day, a customer called and told us that he cant run our
app. from his Win.98 computer.
We advised him to start the app with a batch file (usually there is an
EXE launcher that our users use) - this is what he got:
java.lang.NoClassDefError: java/lang/Object
the batch file had this command:
/jre/bin/java.exe -cp <our_classpath> neetal.MainUI
(I don't have the entire stack trace - because he couldn't send it to me
- but I think that just reading the above is enough)

We then advised the customer to download the latest JRE from Sun and
after doing so, the app. DID start and everything went normal.

Does anyone has a idea what was the problem?
How could java not find java.lang.Object? We are not using any special
class loaders...
Does the 'bundled-jre' startegy for deploying desktop applications is
good?


Thanks in advance,

Eyal Katz


Eyal Katz
R&D Manager
email to: ***@neetal.com
visit our website at: www.neetal.com

===================================
This list is hosted by DevelopMentor� http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 10:19:51 UTC
Permalink
Completely different thing (may be wrong too :-)):
If there's a code which refers *explicitly* to Itf during the loading
process and it resides in a different package then it may cause an error,
which is probably has nothing to do with the class loading in itself.
Because Itf is part of the contract and if it's not public then you can't
access it outside of the package
Just my 2c
Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Horaci Macias
2004-05-13 10:38:33 UTC
Permalink
?? I don't think any code can refer explicitly to a package-level interface unless the code itself is in the same package as the interface. That's (I think) the whole point of the interface being package-level.
By the way, I'm using URLClassLoaders.
Can it be something to do with the ProtectionDomains being different?

Thanks again,

Horaci



-----Original Message-----
From: Sergey Beryozkin [mailto:***@ZANDAR.COM]
Sent: 13 May 2004 11:20
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-JAVA] ClassLoading problem: IllegalAccessError
when loading parent interface


Completely different thing (may be wrong too :-)):
If there's a code which refers *explicitly* to Itf during the loading
process and it resides in a different package then it may cause an error,
which is probably has nothing to do with the class loading in itself.
Because Itf is part of the contract and if it's not public then you can't
access it outside of the package
Just my 2c
Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com


This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 11:06:32 UTC
Permalink
?? I don't think any code can refer explicitly to a package-level interface
unless the code itself is in the same package as the interface

Oh yes, my mistake, this wouldn't even compile. One last thing I'd like to
speculate about is this ( please be patient) : you might've changed an
interface visibility from public to package private only after the code
which works has been compiled and then you recompiled only the interface
definition. I'm showing my ignorance here, but it might be that the
definition of a class implementing the interface contains the info saying
that that interface is public, so when that interface (now package private)
is being loaded, a problem occurs, as binary compatibility between any
potential clients of this interface and the class implementing this
interface has been violated as a result of this change
Sorry if this sounds absurd
Cheers, Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Horaci Macias
2004-05-13 11:21:27 UTC
Permalink
thanks again. I don't think it sounds absurd... but sadly is not the case :'(
I'm not too sure about the class file format but I don't think that classes implementing an interface store the visibility of that interface in its class definition. If Impl implements Intf, Impl won't have any information about Intf being public, protected or package-level. Impl will only have the name of the interface it implements, Intf.
Anyway, even if what I just said is wrong, I didn't recompile the interface so that now is package-level and before it was public. It must be something else...

thanks,

Horaci

-----Original Message-----
From: Sergey Beryozkin [mailto:***@ZANDAR.COM]
Sent: 13 May 2004 12:07
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-JAVA] ClassLoading problem: IllegalAccessError
when loading parent interface


?? I don't think any code can refer explicitly to a package-level interface
unless the code itself is in the same package as the interface

Oh yes, my mistake, this wouldn't even compile. One last thing I'd like to
speculate about is this ( please be patient) : you might've changed an
interface visibility from public to package private only after the code
which works has been compiled and then you recompiled only the interface
definition. I'm showing my ignorance here, but it might be that the
definition of a class implementing the interface contains the info saying
that that interface is public, so when that interface (now package private)
is being loaded, a problem occurs, as binary compatibility between any
potential clients of this interface and the class implementing this
interface has been violated as a result of this change
Sorry if this sounds absurd
Cheers, Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com


This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 11:39:06 UTC
Permalink
Hi,
Just checked my copy of "Inside the Java 2 VM". There's a method_info table,
and it contains all the method definitions this class declares, and as it
implements Itf, then it also contains the method definitions of that
interface too. Among other things, a method definition contains access_flags
flag.
My theory is that the problem you encounter is something to do with the fact
that the accessibility change of the interface is not synchronized somehow
with a definition of the class implementing it
Let's wait for more opinions
Thanks,
Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Horaci Macias
2004-05-13 12:12:05 UTC
Permalink
"Among other things, a method definition contains access_flags flag."

... which refers to the access modifier of the method, not the access modifier of the class/interface where this method is defined.
This is exactly what I'm doing:


public class PublicInterfaceProblem
{

public static void main(String[] args) throws Exception
{
if(args.length != 3)
{
System.err.println("Usage: PublicInterfaceProblem <interface_jar> <impl_jar> <classname>");
System.exit(1);
}
File interfaces = new File(args[0]);
System.out.println("Interfaces: " + interfaces.getAbsolutePath());
File impl = new File(args[1]);
System.out.println("Impl: " + impl.getAbsolutePath());

URLClassLoader parent = new URLClassLoader(new URL[]{interfaces.toURL()}, null);
URLClassLoader child = new URLClassLoader(new URL[]{impl.toURL()}, parent);

System.out.println(child.loadClass(args[2]));

}
}

then I've got interfaces.jar, which only contains the following interface:

package blah;
interface Intf
{

}

and impl.jar, which only contains the following class:

package blah;
public class Impl implements Intf
{

}

if I then run "java PublicInterfaceProblem interfaces.jar impl.jar blah.Impl" I get the exception I mentioned before.
No recompilation, no methods, nothing. That's why I think the problem doesn't come from synchronization between .class files.

Thanks,

Horaci

-----Original Message-----
From: Sergey Beryozkin [mailto:***@ZANDAR.COM]
Sent: 13 May 2004 12:39
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-JAVA] ClassLoading problem: IllegalAccessError
when loading parent interface


Hi,
Just checked my copy of "Inside the Java 2 VM". There's a method_info table,
and it contains all the method definitions this class declares, and as it
implements Itf, then it also contains the method definitions of that
interface too. Among other things, a method definition contains access_flags
flag.
My theory is that the problem you encounter is something to do with the fact
that the accessibility change of the interface is not synchronized somehow
with a definition of the class implementing it
Let's wait for more opinions
Thanks,
Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com


This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 13:15:23 UTC
Permalink
Hi,
I was actually going to ask you to post the code.
It still looks like a binary incompatibility or visibility problem to me, I
just can't explain what exactly is causing the problem. May be
PublicInterfaceProblem class is in a different package, and even though you
don't refer explicitly to Impl, it's still an illegal access error as far as
security is concerned, because there's some potential ambiguity here : from
one side you can access public methods declared on a public class, but on
the other side these public methods are implementaions of a package private
interface. Again, this reasoning assumes PublicInterfaceProblem is in a
different package.
You said earlier that it works fine if a single URLClassLoader is used ? If
so, and assuming what I said above is not correct, then I'm really lost
Thanks
Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Greg Vaughn
2004-05-13 14:30:08 UTC
Permalink
I don't have any bright ideas this early, but I wonder if the jar files
could be accessible on the classpath and that's causing some problems.

Also, I recommend you turn on verbose classloading to help diagnose the
problem. With the 1.4.2 java I've got handy, it looks like the syntax is
java -verbose:class
but it might be different if you're running a different version. java -?
should get it listed for you.

Greg Vaughn
STS, Sr. in CSSD S3-Architecture
***@countrywide.com
External: (972)526-1423
Internal: 92-596-1423



===================================
This list is hosted by DevelopMentor� http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Horaci Macias
2004-05-13 14:45:15 UTC
Permalink
The parent classloader has "null" as parent classloader, so even if the jars are in the classpath the only classes that the parent classloader will "see" are the rt.jar classes.
I did the -verbose:class. If I load both classes using the same classloader, using this code:

File interfaces = new File(args[0]);
System.out.println("Interfaces: " + interfaces.getAbsolutePath());
File impl = new File(args[1]);
System.out.println("Impl: " + impl.getAbsolutePath());

URLClassLoader loader = new URLClassLoader(new URL[]{interfaces.toURL(), impl.toURL()}, null);
System.out.println(loader.loadClass(args[2]));

then I get the output:
...
[Loaded testing.java.net.url.Intf]
[Loaded testing.java.net.url.Impl]
class testing.java.net.url.Impl
[Loaded java.lang.Shutdown from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
...

"class testing.java.net.url.Impl" is there because of the System.out. This proves that the classes are not loaded by the system classloader, otherwise I would see [Loaded testing.java.net.url.Impl from c:\........\xxx.jar].
If I load the classes using parent/child classloaders, I get this:

[Loaded testing.java.net.url.Intf]
[Loaded java.lang.IllegalAccessError from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
[Loaded java.lang.ClassFormatError from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
[Loaded java.io.IOException from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
java.lang.IllegalAccessError: class testing.java.net.url.Impl cannot access its superinterface testing.java.net.url.Intf
[Loaded java.lang.StackTraceElement from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at testing.java.net.url.PublicInterfaceProblem.main(PublicInterfaceProblem.java:36)
[Loaded java.lang.Shutdown from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\j2re1.4.2_03\lib\rt.jar]
Exception in thread "main"
From the output we can see that it is loading the interface with no problems, but not the class.
Thanks for your help,

Horaci


-----Original Message-----
From: Greg Vaughn [mailto:***@LANDSAFE.COM]
Sent: 13 May 2004 15:30
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-JAVA] ClassLoading problem: IllegalAccessError
when loading parent interface


I don't have any bright ideas this early, but I wonder if the jar files
could be accessible on the classpath and that's causing some problems.

Also, I recommend you turn on verbose classloading to help diagnose the
problem. With the 1.4.2 java I've got handy, it looks like the syntax is
java -verbose:class
but it might be different if you're running a different version. java -?
should get it listed for you.

Greg Vaughn
STS, Sr. in CSSD S3-Architecture
***@countrywide.com
External: (972)526-1423
Internal: 92-596-1423



===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com


This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Greg Vaughn
2004-05-13 15:24:11 UTC
Permalink
"Moderated discussion of advanced Java topics."
Post by Horaci Macias
[Loaded testing.java.net.url.Intf]
[Loaded java.lang.IllegalAccessError from C:\Program
Files\Java\j2re1.4.2_03\lib\rt.jar]
[Loaded java.lang.ClassFormatError from C:\Program Files\Java\j2re1.
4.2_03\lib\rt.jar]
[Loaded java.io.IOException from C:\Program Files\Java\j2re1.4.
2_03\lib\rt.jar]
java.lang.IllegalAccessError: class testing.java.net.url.Impl cannot
access its superinterface testing.java.net.url.Intf
[Loaded java.lang.StackTraceElement from C:\Program
Files\Java\j2re1.4.2_03\lib\rt.jar]
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at testing.java.net.url.PublicInterfaceProblem.
main(PublicInterfaceProblem.java:36)
[Loaded java.lang.Shutdown from C:\Program
Files\Java\j2re1.4.2_03\lib\rt.jar]
Post by Horaci Macias
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\j2re1.4.
2_03\lib\rt.jar]
Exception in thread "main"
From the output we can see that it is loading the interface with no
problems, but not the class.
Still no definite solution, but I do find it interesting that
ClassFormatError and IOException are being loaded. It makes me wonder if
IllegalAccessError is wrapping those. It makes me think it's not able to
read the jar file itself. But that doesn't explain why it works when you
use 1 classloader.

The next thing I would do is either subclass URLClassLoader and put some
print statements in there, or walk through it with a debugger.

-Greg

===================================
This list is hosted by DevelopMentor� http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Joel Kamentz
2004-05-13 19:08:03 UTC
Permalink
Packages (as in package access) are scoped per ClassLoader.

You state that the parent ClassLoader loads the interface and the child ClassLoader loads the implementation. This won't work because of the ClassLoader-specific nature of package scoping. The interface isn't visible to the implementation class because, even though it's the same package name, they're in different ClassLoaders.

I only skimmed the posts in this thread, but I think you've already discovered that this will work if you declare the interface to be public. It would also work to have both interface and implementation loaded by the same ClassLoader.

Really, if you expect arbitrary folks to implement the interface (which you apparently do if the implementation is being loaded by a different ClassLoader), then you should make the interface public.

The ClassLoader-scoping of package scope (which applies to accessing package methods, variables, etc.) is similar to the general ClassLoader-scoping of class names. For example, I can define two classes, both named com.foo.Bar, with entirely different implementation code if I define them in separate ClassLoaders.

Joel

-----Original Message-----
From: Moderated discussion of advanced Java topics. [mailto:ADVANCED-***@DISCUSS.DEVELOP.COM] On Behalf Of Horaci Macias
Sent: Thursday, May 13, 2004 5:04 AM
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: ClassLoading problem: IllegalAccessError when loading parent interface


I've got two classloaders, say parent and child. They both use the default delegation model and parent is the parent classloader of child. Now imagine the following interface and class:

package testing.java.net.url;
interface Intf
{
void a();
}

package testing.java.net.url;
public class Impl implements Intf{
void a(){}
}

They are each in a separate .java file, and the interface is in the parent classloader whereas the class is in the child classloader. I thought that trying to load the class from the child classloader shouldn't be a problem, but in fact it is. I'm getting the following exception when loading Impl:

java.lang.IllegalAccessError: class testing.java.net.url.Impl cannot access its superinterface testing.java.net.url.Intf
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

Note that the interface is not public, but it is in the same package as the implementation. If I make the interface public then everything works fine, but shouldn't it also work with the interface as is it? Am I missing something?

Thanks in advance,

Horaci



This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor(r) http://www.develop.com You may be interested in our new J2EE Web Tier course: May 17 2004, in Torrance, CA June 21 2004, in Boston, MA http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentor� http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 20:43:32 UTC
Permalink
Hello Joel,

Can you provide some link, if possible, to the information which describes
what you've explained in more detail ?
I've never heard about it, which obviously shows my ignorance here. I know
that there're ClassLoader specific namespaces which scope class names, but I
thought it only applies to class loaders not bound by any relationships, and
I didn't realize there's an additional restriction with respect to a package
access which applies to loaders being in a parent-child relationship too.
It's just a little bit unexpected (ok, I probably the only one here at the
list who is surprised, may be Horaci is surprised too :-) )
What if a class in one package extends a package private class in the same
package which has only protected methods : this does not leak those methods
into a public contruct of a subclass, Additionally, a package private class
happens to be residing in a different source tree. Now I know that a single
URLClassLoader will load both classes, but I'm still somewhat puzzled (event
though your explanation is very good and clear) as to why two loaders in a
parent-child relationships will fail

Thanks, Sergey



Packages (as in package access) are scoped per ClassLoader.

You state that the parent ClassLoader loads the interface and the child
ClassLoader loads the implementation. This won't work because of the
ClassLoader-specific nature of package scoping. The interface isn't visible
to the implementation class because, even though it's the same package name,
they're in different ClassLoaders.

I only skimmed the posts in this thread, but I think you've already
discovered that this will work if you declare the interface to be public.
It would also work to have both interface and implementation loaded by the
same ClassLoader.

Really, if you expect arbitrary folks to implement the interface (which you
apparently do if the implementation is being loaded by a different
ClassLoader), then you should make the interface public.

The ClassLoader-scoping of package scope (which applies to accessing package
methods, variables, etc.) is similar to the general ClassLoader-scoping of
class names. For example, I can define two classes, both named com.foo.Bar,
with entirely different implementation code if I define them in separate
ClassLoaders.

Joel

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Joel Kamentz
2004-05-13 21:50:44 UTC
Permalink
Hmm. I know it works this way, but I don't remember why I know.

Looking....

The second paragraph of page 132 of the JLS (ftp://ftp.javasoft.com/docs/specs/langspec-2.0.pdf) hints at this by saying that ClassLoaders can be used (in part) to separate package naming conflicts.

The javadoc for java.lang.Package includes this sentence: "Within each ClassLoader instance all classes from the same java package have the same Package object."

The answer appears to be in the VM spec. 5.4.4 Access Control says class/interface C is accessible to class/interface D if C is public or C and D are members of the same runtime package. In 5.3 we find the following: "At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface."

Thus, regardless of matching names, the "runtime package" of anything defined by ClassLoader A is never the same as anything defined by ClassLoader B -- package scope is per-ClassLoader.

Joel

-----Original Message-----
From: Moderated discussion of advanced Java topics. [mailto:ADVANCED-***@DISCUSS.DEVELOP.COM] On Behalf Of Sergey Beryozkin
Sent: Thursday, May 13, 2004 4:44 PM
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: ClassLoading problem: IllegalAccessError when loading parent interface


Hello Joel,

Can you provide some link, if possible, to the information which describes what you've explained in more detail ? I've never heard about it, which obviously shows my ignorance here. I know that there're ClassLoader specific namespaces which scope class names, but I thought it only applies to class loaders not bound by any relationships, and I didn't realize there's an additional restriction with respect to a package access which applies to loaders being in a parent-child relationship too. It's just a little bit unexpected (ok, I probably the only one here at the list who is surprised, may be Horaci is surprised too :-) ) What if a class in one package extends a package private class in the same package which has only protected methods : this does not leak those methods into a public contruct of a subclass, Additionally, a package private class happens to be residing in a different source tree. Now I know that a single URLClassLoader will load both classes, but I'm still
somewhat puzzled (event though your explanation is very good and clear) as to why two loaders in a parent-child relationships will fail

Thanks, Sergey



Packages (as in package access) are scoped per ClassLoader.

You state that the parent ClassLoader loads the interface and the child ClassLoader loads the implementation. This won't work because of the ClassLoader-specific nature of package scoping. The interface isn't visible to the implementation class because, even though it's the same package name, they're in different ClassLoaders.

I only skimmed the posts in this thread, but I think you've already discovered that this will work if you declare the interface to be public. It would also work to have both interface and implementation loaded by the same ClassLoader.

Really, if you expect arbitrary folks to implement the interface (which you apparently do if the implementation is being loaded by a different ClassLoader), then you should make the interface public.

The ClassLoader-scoping of package scope (which applies to accessing package methods, variables, etc.) is similar to the general ClassLoader-scoping of class names. For example, I can define two classes, both named com.foo.Bar, with entirely different implementation code if I define them in separate ClassLoaders.

Joel

===================================
This list is hosted by DevelopMentor(r) http://www.develop.com You may be interested in our new J2EE Web Tier course: May 17 2004, in Torrance, CA June 21 2004, in Boston, MA http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentor� http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-13 22:13:52 UTC
Permalink
Hi Joel, it's very helpful, I'll try to digest it all tomorrow, it's been a
long day for me

thanks for your time
Sergey

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Sergey Beryozkin
2004-05-14 20:29:24 UTC
Permalink
Hello,

It's the subtle detail that public C is visible to D even though C and D are
members of different runtime packages, while C is not visible to D if C is
not public which escaped me completely;
What are practical security concerns here ? Oh, I actually remember reading
something about it... Imagine a custom loader loading a malicious
java.lang.SomeClass and if there were no such a restriction then this
malicious java.lang.SomeClass would be able to access java.lang-private
classes, etc. At the same time I find it difficult to imagine a practical
situation when loading two different classes, one of them package-private,
with my own two custom loaders can present a security problem.

Anyway, I start thinking that it's really worth reading the VM spec.
There're many minor details there which are not available in a mainstream
literature but which are very important at the same time. I've recentrly
made a heroic :-) attempt and read most of JLS, now it's JVM spec's turn !
Thanks, Sergey



The answer appears to be in the VM spec. 5.4.4 Access Control says
class/interface C is accessible to class/interface D if C is public or C and
D are members of the same runtime package. In 5.3 we find the following:
"At run time, a class or interface is determined not by its name alone, but
by a pair: its fully qualified name and its defining class loader. Each such
class or interface belongs to a single runtime package. The runtime package
of a class or interface is determined by the package name and defining class
loader of the class or interface."

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Horaci Macias
2004-05-14 08:25:12 UTC
Permalink
thanks a lot, this really explains it. I started thinking that this could be the case; the same way classes are not only identified by its name, maybe packages follow the same rules.

thanks to all replies. Things start to make sense again ;D

Horaci

-----Original Message-----
From: Joel Kamentz [mailto:***@SAS.COM]
Sent: 13 May 2004 20:08
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: Re: [ADVANCED-JAVA] ClassLoading problem: IllegalAccessError
when loading parent interface


Packages (as in package access) are scoped per ClassLoader.

You state that the parent ClassLoader loads the interface and the child ClassLoader loads the implementation. This won't work because of the ClassLoader-specific nature of package scoping. The interface isn't visible to the implementation class because, even though it's the same package name, they're in different ClassLoaders.

I only skimmed the posts in this thread, but I think you've already discovered that this will work if you declare the interface to be public. It would also work to have both interface and implementation loaded by the same ClassLoader.

Really, if you expect arbitrary folks to implement the interface (which you apparently do if the implementation is being loaded by a different ClassLoader), then you should make the interface public.

The ClassLoader-scoping of package scope (which applies to accessing package methods, variables, etc.) is similar to the general ClassLoader-scoping of class names. For example, I can define two classes, both named com.foo.Bar, with entirely different implementation code if I define them in separate ClassLoaders.

Joel

-----Original Message-----
From: Moderated discussion of advanced Java topics. [mailto:ADVANCED-***@DISCUSS.DEVELOP.COM] On Behalf Of Horaci Macias
Sent: Thursday, May 13, 2004 5:04 AM
To: ADVANCED-***@DISCUSS.DEVELOP.COM
Subject: ClassLoading problem: IllegalAccessError when loading parent interface


I've got two classloaders, say parent and child. They both use the default delegation model and parent is the parent classloader of child. Now imagine the following interface and class:

package testing.java.net.url;
interface Intf
{
void a();
}

package testing.java.net.url;
public class Impl implements Intf{
void a(){}
}

They are each in a separate .java file, and the interface is in the parent classloader whereas the class is in the child classloader. I thought that trying to load the class from the child classloader shouldn't be a problem, but in fact it is. I'm getting the following exception when loading Impl:

java.lang.IllegalAccessError: class testing.java.net.url.Impl cannot access its superinterface testing.java.net.url.Intf
at java.lang.ClassLoader.defineClass0(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

Note that the interface is not public, but it is in the same package as the implementation. If I make the interface public then everything works fine, but shouldn't it also work with the interface as is it? Am I missing something?

Thanks in advance,

Horaci



This message has been scanned for viruses by MailControl - www.mailcontrol.com

===================================
This list is hosted by DevelopMentor(r) http://www.develop.com You may be interested in our new J2EE Web Tier course: May 17 2004, in Torrance, CA June 21 2004, in Boston, MA http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentor® http://www.develop.com
You may be interested in our new J2EE Web Tier course:
May 17 2004, in Torrance, CA
June 21 2004, in Boston, MA
http://www.develop.com/courses/javawebtierls

View archives and manage your subscription(s) at http://discuss.develop.com
Loading...