Interesting. That could well explain the problem. The thing is, that this
time, it's JVM code which does Class.forName() ..

An additional detail to my original post: The problem occurred when
installing the same bundle+version on top of an existing one (and that one
had an embedded jar file). So I'd rephrase my claim with this condition.

Also, meanwhile, I have worked around the issue by not re-installing a
bundle if it already exists..

Cheers,
Stefan

On 7/14/14 10:38 PM, "Carsten Ziegeler" <[email protected]> wrote:

>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/in
>>te
>> 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]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to