Greetings Michael,

I think I figured out the classloader problem: In code I neglected to
post, I saved the zoomMap as a IJ.(s|g)etProperty; so that its settings
are retained over reruns/complies of the Fuzzy_C_Means plugin. I assume
that the definition changed between iterations. Restarting ImageJ seems to
have solved the issue.

The reason that I had to restart ImageJ is that starting a
NonBlockingGenericDialog from a callback from within a
NonBlockingGenericdialog causes ImageJ to lock up solid. An empty window
is display and then all of ImageJ locks up, requiring killing the ImageJ
process and restarting ImageJ. Starting a blocking GenericDialog in this
manor works fine (almost). I would assume that a NonBlockingGenericDialog
should work fine in this scenario. Although, if for some Java reason this
can not be implemented, I would assume the preferred reaction is to throw
an exception, and not block.

The reason for the 'almost' claim is that the Window.toFront does not seem
to work when invoked within a callback from a blocking GenericDialog, even
after the callback has returned; Probably similar to one of my previous
posts.

Question: from Java, how can an Roi be deleted from the RoiManager without
the Roi being attached to an ImagePlus? A delete method would be nice, as
select(ing) the Roi in this case is a side-effect headache and is
superfluous.

Thanks again, and in advance,

Fred

On Mon, January 12, 2026 10:45 am, Michael Schmid wrote:
> Hi Fred,
>
> having a common class used by different plugins is a very common thing
> for me. I have never experienced problems like this.
>
> I am not using an IDE like Eclipse but simply the "Compile&Run" of ImageJ.
>
> Causes of problems like yours that I can imagine:
>
> - There is a .jar (or .zip) file with a class of the same name somewhere
> in the plugins directory or a subdirectory thereof.
>
> - With "Compile&Run", ImageJ checks only for java files directly called
> in your plugins. E.g., if you have a plugin A that calls class B (which
> is in a separate java file), and class B makes use of class C (in a
> separate java file again), "Compile&Run A.java" won't compile class C.
> In such a case, you might end up with a wrong version of C.class, which
> could be inconsistent with how the class is called by B, without any
> compiler warning.
>
> Michael
> ________________________________________________________________
> On 09.01.26 00:27, Fred Damen wrote:
>> Greetings,
>>
>> I am trying to create a data object (what C++ would call a struct) that
>> is
>> passed between one plugin (Copy_N_Paste) to another plugin
>> (Fuzzy_C_Means). Copy_N_Paste uses it without issue, but Fuzzy_C_Means
>> has
>> a class load runtime issue. Is there something that I need to do special
>> since ij is using its own class loader?
>>
>> I am getting this runtime error that is perplexing me:
>>
>> zoomData=ZoomData@160483c5
>> Target class loader: ij.io.PluginClassLoader@18a36070
>> ImageJ 1.54p; Java 21.0.3 [64-bit]; Linux 6.8.9-100.fc38.x86_64; 1665MB
>> of
>> 4096MB (40%)
>> java.lang.ClassCastException: class ZoomData cannot be cast to class
>> ZoomData (ZoomData is in unnamed module of loader
>> ij.io.PluginClassLoader
>> @289dbc6; ZoomData is in unnamed module of loader
>> ij.io.PluginClassLoader
>> @18a36070)
>>      at Fuzzy_C_Means.goBackHome(Fuzzy_C_Means.java:1426)
>>
>> ZoomData is a defined in the file ZoomData.jave in plugins directory
>> (see
>> below).
>>
>> Line Fuzzy_C_Means.java:1426 contains "Object class loader: ":
>> =====
>> IJ.log("zoomData="+zoomMap.get(title));
>> //IJ.log("mag="+zoomMap.get(title).mag);
>> if (zoomMap.get(title) != null) {
>>     IJ.log("Target class loader: " + ZoomData.class.getClassLoader());
>>     IJ.log("Object class loader: " +
>> zoomMap.get(title).getClass().getClassLoader());
>>     }
>>        if (zoomMap.containsKey(title))
>> Copy_N_Paste.setZoom(imp,zoomMap.get(title));
>> =====
>> The last line is what originally raised the issue. The 'if' statement
>> was
>> added due to google suggesting that this is due to more than one class
>> loader and/or class definitions:
>> ====
>> The java.lang.ClassCastException with the same class name but different
>> PluginClassLoader instances indicates that you have duplicate copies of
>> the ZoomData class in your application's classpath, and an object
>> created
>> by one classloader is being cast to the type loaded by the other. In
>> Java,
>> classes loaded by different classloaders are considered different types,
>> even if they have the same name and bytecode.
>> This scenario is common in environments that use modular classloaders,
>> such as plugin systems like those found in ImageJ (implied by
>> ij.io.PluginClassLoader)
>> ====
>>
>> There does not seem to be any runtime issue for Fuzzy_C_Means when
>> placing
>> instances of ZoomData into the TreeMap:
>> ====
>> TreeMap<String,ZoomData> zoomMap  = new TreeMap<String,ZoomData>();
>> zoomMap.put(imp.getTitle(), new ZoomData(imp));
>> ====
>>
>> ==== ZoomData.java ====
>> import ij.*;
>> import ij.process.*;
>> import ij.gui.*;
>> import java.awt.*;
>> import ij.plugin.*;
>> import ij.plugin.frame.*;
>>
>>
>>     public class ZoomData {
>>        public Rectangle srcRect = null;
>>        public Insets insets = null;
>>        public int sliderHeight = 0;
>>        public double mag = Double.NaN;
>>
>>        private ZoomData() {}
>>        public ZoomData(Rectangle sr, Insets i, int sh, double m) {
>>           srcRect = sr;
>>           insets = i;
>>           sliderHeight = sh;
>>           mag = m;
>>           }
>>        public ZoomData(ImagePlus imp) {
>>           insets  = imp.getWindow().getInsets();
>>           srcRect = imp.getCanvas().getSrcRect();
>>           mag     = imp.getCanvas().getMagnification();
>>           sliderHeight = imp.getWindow().getSliderHeight();
>>           }
>>        }
>> ====
>>
>> Thanks in advance,
>>
>> Fred
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

Reply via email to