Re: Compilation Time | More questions ClassLoader

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2007/5/4, Tom Tromey <tromey@xxxxxxxxxx>:
Yup.  I'd suggest that instead of thinking of the solution in terms of
writing a class loader, think about it in terms of writing some code
that simply returns a byte[] that is the class contents.

This is already done. Although this downloading code is called from
loadClass. The byte[] array is then transformed to a Class object
thanks to defineClass methods.



Then call this downloading code from VMClassLoader.loadClass.

How you implement the downloading is up to you, but it turns out to be
pretty simple to re-use URLClassLoader for this... just treat the
.class file at the URL as a resource, not a class, and don't use the
loadClass family of calls on your delegate URLClassLoader at all.

Basically when a new() is performed and the class not already loaded,
doesn't the VM calls loadClass() family of calls? How to avoid
loadClass() from ClassLoader, download our byte[] (as explained above)
and create a Class object out of it without calling defineClass() ?


Martin> We have done some basic tests and this seemed to work. However, when
Martin> trying with a more complete program, it appears that it throws
Martin> IllegalAccessException making me think that some security is added
Martin> when using the defineClass() on core API.

For this sort of a thing more details are needed.  At least a full
stack trace.  But if you follow the above this may be moot.


I think we got more on this one and every problem seems to be related.
Whether the class code is loaded from bootstrap (thanks to native code
VMClassLoader.loadClass() ) or thanks to a Java ClassLoader, the Class
object is finally created with native function defineClass() -called
directly from native loadClass in the first case (bootstrap) or called
with VMClassLoader.defineClass() in the second case (Java ClassLoader)
but it is finally the same function.

There are two differences when calling native defineClass() in the two cases:
- Protection Domain, which we could easely set to null without any difference
- The classloader itself

Our debbuging shows that the VM is actually able to find a Class from
the ClassLoader without calling loadClass() but just using the
reference we give on this classLoader when calling defineClass(). This
is done when the VM has to load a class on which depends the class we
wanted to load. This results in a compromised situation:

- If forcing ClassLoader to null when calling defineClass from our
ClassLoader (to have a similar call as if we were the real bootstrap)
the VM is unable to find the classes which should be automatically
loaded (since it can't be loaded from bootstrap and a null pointer to
ClassLoader means bootstrap). ClassNotFoundException.

- If giving the right reference to our ClassLoader,
IllegalAccessException are thrown, when constructor (and thus calls to
super() ) is executed.

java.lang.IllegalAccessException: method is not accessible
  at java.awt.Frame.<init>(Frame.java:246)
  at java.awt.Frame.<init>(Frame.java:234)
  at test2.Test1.<init>(Test1.java:9)
  at test2.Test.<init>(Test.java:8)
  at test2.Test.main(Test.java:11)


It seems that whether the ClassLoader is set to null or not is the
discriminating security parameter. And we can't set it to null because
of the problem explained above, about dependencies. I think we have to
find where this security is managed -at runtime and not when loading
class- and modify its behavior...

thanks for any help and sorry if I didn't understand your first
solution, I'm all ears for more details.

martin

Tom



[Index of Archives]     [Linux Kernel]     [Linux Cryptography]     [Fedora]     [Fedora Directory]     [Red Hat Development]

  Powered by Linux