http://imagej.273.s1.nabble.com/Strange-ClassCastException-A-puzzle-for-Java-ImageJ-experts-to-help-me-wit-tp3692688p3692691.html
to confusion.
>pluginFrame controller first, StackOpener second => exception.
>
>Each use of Compile and Run creates a new class loader, and this can
>cause conflicts due to multiple instances of the loaded class.
>
>** Compile and Run of the StackOpener always builds a window which
>fails to be controlled by the pluginFrame, whether the pluginFrame
>was precompiled or loaded by Compile & Run.
>
>If both are precompiled and installed, the order in which they were
>instantiated does not matter. Everything works fine.
>
>FYI I have been ping-ponging between the code for both classes and
>moving methods from one to the other as I develop how they interact.
>It's for this reason that I tend to load them sequentially with C&R
>during the same ImageJ session. Maybe I should grow up and setup the
>project in an IDE.
>
>Perhaps Wayne or someone can give a better idea of why this happens
>with Compile and Run and whether it can be fixed in any way. It's
>easy enough to avoid now that I know it's a hazard. But I'm not sure
>if others might be experiencing class loader problems with Compile
>and Run but not knowing it.
>
>Bill
>
>>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
William A. Mohler
Dept. of Genetics and Developmental Biology
263 Farmington Ave.
alt. mobile: (860) 331-8514
G&DB dept. ofc.: (860) 679-8350
G&DB dept. fax : (860) 679-8345