Posted by
Bill Mohler on
Apr 30, 2009; 11:19am
URL: http://imagej.273.s1.nabble.com/Strange-ClassCastException-A-puzzle-for-Java-ImageJ-experts-to-help-me-wit-tp3692688p3692689.html
A little bit more info. I read up on class loaders, and decided to
look at their parentage.
It looks life all of the class loaders that pop up are direct
descendents of the system class loader. I don't know if this gives me
any further ability to control what's going on.
Bill
I put the class loader finding code block in 3 different places
First, in the "opener" plugin that gets a list of movies from the
user and then builds the MQTVS as an object called vstack:
From QT_M_OMM.cSTHS
vstack loader = ij.io.PluginClassLoader@4eabb
vstack loader parent= sun.misc.Launcher$AppClassLoader@a39137
mqtvs loader = ij.io.PluginClassLoader@4eabb
mqtvs loader parent = sun.misc.Launcher$AppClassLoader@a39137
Loaders equal? true/true
system loader = sun.misc.Launcher$AppClassLoader@a39137
system loader parent = sun.misc.Launcher$ExtClassLoader@858610
ImageJ loader = ij.io.PluginClassLoader@4eabb
ImageJ loader parent = sun.misc.Launcher$AppClassLoader@a39137
Then in the MQTVS class's getProcessor() method that figures out
which images to display:
From MQTVS.gP
stack loader = sun.misc.Launcher$AppClassLoader@a39137
stack loader parent= sun.misc.Launcher$ExtClassLoader@858610
mqtvs loader = ij.io.PluginClassLoader@4eabb
mqtvs loader parent = sun.misc.Launcher$AppClassLoader@a39137
Loaders equal? false/false
system loader = sun.misc.Launcher$AppClassLoader@a39137
system loader parent = sun.misc.Launcher$ExtClassLoader@858610
ImageJ loader = ij.io.PluginClassLoader@4eabb
ImageJ loader parent = sun.misc.Launcher$AppClassLoader@a39137
**Interesting note: this getProcessor() gets called once even BEFORE
the method far above gets called. Then this is also called many
times later. In both the first and then the subsequent calls, it
always reports the loaders as shown here.
Then in the PluginFrame adjustmentValueChanged() method that I've
been bashing about all afternoon:
From MAFMOD.aVC
stack loader = ij.io.PluginClassLoader@4eabb
stack loader parent= sun.misc.Launcher$AppClassLoader@a39137
mqtvs loader = ij.io.PluginClassLoader@c68b6f
mqtvs loader parent = sun.misc.Launcher$AppClassLoader@a39137
Loaders equal? false/false
system loader = sun.misc.Launcher$AppClassLoader@a39137
system loader parent = sun.misc.Launcher$ExtClassLoader@858610
ImageJ loader = ij.io.PluginClassLoader@c68b6f
ImageJ loader parent = sun.misc.Launcher$AppClassLoader@a39137
Somehow, it looks like this object gets handled first by the ImageJ
loader in the "opener", then it (or a copy/clone?) gets handed off to
the system loader in MQTVS, then it ends up in the hands of a third
loader (neither system not ImageJ) in the PluginFrame. It looks life
all of the class loaders that pop up are direct descendents of the
system class loader.
Fascinated, but more perplexed than ever.
Thanks to Dscho and Curtis,
Bill
>Hi Bill,
>
>I agree with Dscho that it must be two ClassLoaders, each with their own
>version of the class. I have never heard of this happening before, but it is
>conceivable, since ImageJ uses its own ClassLoader, and maybe QTJava does
>too (not sure).
>
>Try this code:
>
>ClassLoader stackLoader = stack.getClass().getClassLoader();
>ClassLoader mqtvsLoader = MultiQTVirtualStack.class.getClassLoader();
>IJ.log("stack loader = " + stackLoader);
>IJ.log("mqtvs loader = " + mqtvsLoader);
>IJ.log("Loaders equal? " + (stackLoader == mqtvsLoader) + "/" +
>stackLoader.equals(mqtvsLoader));
>ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
>ClassLoader ijLoader = ij.IJ.getClassLoader();
>IJ.log("system loader = " + systemLoader);
>IJ.log("ImageJ loader = " + ijLoader);
>
>Check whether the numerical codes for the stack & mqtvs loaders line up with
>the system and/or ImageJ loaders. Then you'll know which class loader is
>loading which version of the class. But ultimately, this bug may not be
>something easily fixed within your code -- it may require a change to
>ImageJ. Not sure without further messing around...
>
>-Curtis
>
>On Wed, Apr 29, 2009 at 11:06 AM, Johannes Schindelin <
>
[hidden email]> wrote:
>
>> Hi,
>>
>> On Wed, 29 Apr 2009, Bill Mohler wrote:
>>
>> > Thanks, Curtis. Here's what I get
>> >
>> > MultiQTVirtualStack1
>> > stack class = MultiQTVirtualStack
>> > MultiQTVirtualStack class = MultiQTVirtualStack
>> > Classes equal? false/false
>> > path to MultiQTVirtualStack class =
>> >
>>
>>file:/Applications/ImageJ/plugins/QuickTime_Plugins_MMRD041109/MultiQTVirtualStack.class
>> > path to stack class =
>> >
>>
>>file:/Applications/ImageJ/plugins/QuickTime_Plugins_MMRD041109/MultiQTVirtualStack.class
>> > beforetheloop imp[3-Movie Overlay #1 : see Log window for details
>> > 600x411x38961]
>> > stack[600x411x38961]
>> > intheloop j= 0 imp[3-Movie Overlay #1 : see Log window for details
>> > 600x411x38961]
>> > stack[600x411x38961]
>> > MultiQTVirtualStack2
>> > MultiQTVirtualStack3
>> >
>> >
>> > So, mysteriously to me, the code you sent reports that they are NOT equal
>> > classes. However both paths point to the same class file!
> >
>> Then I am pretty certain that two different class loaders are competing
>> for the class.
>>
>> Could you print ...getClass().getClassLoader(), too?
>>
>> Ciao,
>> Dscho
>>