A good read on Class.forName:

http://blog.meschberger.ch/2010/12/classforname-probably-not.html

Regards
Carsten


2014-07-14 6:42 GMT-07:00 Stefan Egli <[email protected]>:

> Hi,
>
> TL;DR:
> It looks like uninstalling a bundle that embeds another jar ­ does not
> uninstall those embedded classes and reinstalling the bundle afresh and
> resolving a class via Class.forName(embeddedClassName, false,
> newBundleClassLoader) returns the old, already uninstalled bundle's
> Classloader.
>
> The long story:
> I'm encountering an odd behavior in sling-remote-testing which I suspect
> could be an issue in the underlying felix layer, that's why I'd like to
> see if anyone from the felix-user list can help.
>
> Here's a description of what I'm doing:
>
> * I'm installing a test bundle (with my test class annotated with
> @org.junit.runner.RunWith) and a bunch of sling-remote-testing bundles (eg
> sling.junit.core, sling.junit.remote, sling.testing.tools). I then start
> the first incarnation of these remote tests:
>      * all works fine
>           * now I note down the bundle ID of sling.junit.core as ID=501
>           * PS: sling.junit.core embeds junit-4.8.2.jar !
> * Without restarting the server, I run the integration tests again, this
> again installs all above mentioned bundles and re-runs the junit remote
> tests
>      * On this second run though, junit cannot find any tests ("No
> runnable methods") and fails
>           * I again note down the bundle ID of sling.junit.core as ID=512
>
> I traced the problem down to the fact that junit's AnnotatedBuilder cannot
> resolve the @RunWith annotation at [0] (getAnnotation() returns null):
>     RunWith annotation = testClass.getAnnotation(RunWith.class);
> The reason getAnnotation() returns null is because the testClass contains
> the @RunWith annotation loaded by the bundle Classloader of bundle 501
> (the first installation of sling.junit.core) - whereas the class that runs
> above line (ie Junit itself) is loaded with the bundle ClassLoader of
> bundle 512: The result is that the HashMap lookup fails since the two
> Classes are not equal.
>
> Somewhere deep in JVM's annotation resolution code (ie in
> sun.reflect.generics.Reifier / sun.reflect.generics.CoreReflectionFactory)
> the following line is executed:
>     Class.forName(name /*org.junit.runner.RunWith*/, false,
> getDeclsLoader());whereas getDeclsLoader()==bundle Classloader ID 512 (the
> new, correct one) - and interesting enough: the resulting Class has
> getClassloader()==bundle Classloader ID 501 (the deleted one)
>
> So either the class loading mechanism is correct (in that it can return
> the class loaded with the old, 501, classloader) and JVM's annotation
> lookup mechanism is broken - or the class loading mechanism is indeed
> broken here
>
> Cheers,
> Stefan
> --
> [0] -
> https://github.com/junit-team/junit/blob/r4.11/src/main/java/org/junit/inte
> rnal/builders/AnnotatedBuilder.java#L19
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>


-- 
Carsten Ziegeler
Adobe Research Switzerland
[email protected]

Reply via email to