Contains interface of imglib2-roi is gone

Dear all, (@tpietzsch @ctrueden … ?)

I just upgraded scijavas parent pom in some of my projects to 25.0.0. Since then, builds break with this error message:

[ERROR] symbol: class Contains
[ERROR] location: package net.imglib2.roi.util
[ERROR] /C:/structure/code/postprocessing-utilities/src/main/java/de/mpicbg/rhaase/spimcat/postprocessing/fijiplugins/imagemath/binaryoperators/[38,135] cannot find symbol
[ERROR] symbol: class Contains

This happens for example here:

Is there some example code somewhere showing how to deal with this now that the Contains interface is gone? Basically I just wanted to build a wrapper around imglib2-roi allowing me to combine (AND/OR/XOR/…) Img images… Nothing fancy…

Thanks for any help in advance!


Contains is now java.util.function.Predicate<RealLocalizable>, because that is just what it is.
Predicate has already and(), or(), negate() methods.
From Predicate we derive MaskPredicate( which adds xor( ) and minus() and some interval logic.
From MaskPredicate we derive RealMask and Mask which nail the T down to RealLocalizable or Localizable.
From that the mask implementations derive.

For you, it should probably be enough to just use Predicate< RealLocalizable> instead of contains.

Let me know if you need more details, and I will dig for examples (@awalter17 can you recommend any example?).


Hey @tpietzsch,

thanks for the quick reply. Would it be possible to bring Contains back and mark it as deprecated? I’m afraid quite some of my plugins distributed over many repositories broke because of that change. If this would be shipped via Java8 update site soon, we can stop a wave of breaking Fijis in our close environment.



@haesleinhuepf I would rather not do that. Let’s talk about it tomorrow.

1 Like

@haesleinhuepf Could you check whether that would actually fix your plugins? I.e., build a version of the current imglib2-roi with Contains added back in, put that in a Fiji and check. In principle you could also make a artefact which only has the single class Contains. While Fiji is still at java 8 and split packages are allowed, this could be another solution?

1 Like

@haesleinhuepf I commented on the GitHub issue you filed. In a nutshell, while I feel your pain regarding removed classes: it may be too late and/or too infeasible to restore backwards compatibility here. At minimum: I agree with @tpietzsch that it would need to be tried. Upgrading your plugins is probably the surest and least painful path.

1 Like

Ok. I see. FYI: Bringing Contains and ContainsRandomAccess back prevents plugins from breaking. I’ll ship them via my update site.

Just a bit more background info for you: Imagine you are a facility engineer building tiny workflow-plugins (100-liners, workflows in Java classes) which are distributed via email and not via update site. Years after you programmed them, they start breaking because classes were removed from core-libraries - unfortunately without prewarning. As no-longer-facility-engineer, you don’t even remember, which plugins and projects are affected… :frowning: Please consider using @ Deprecated in the future. Any other strategy improving these kinds of issues are very welcome.

Btw.: The next thing I need to fix in the same way is the removal of net.imagej.table.DoubleColumn and friends. Different construction site, exactly the same issue.

[ERROR] /C:/structure/code/BioImageAnalysisToolbox/src/main/java/de/mpicbg/scf/labelhandling/imgtools/[8,24] cannot find symbol
  symbol:   class DoubleColumn
  location: package net.imagej.table

Thanks again for your instant support!
(You know I love you even when being grumpy).


1 Like

Yes, that’s something I can imagine :slight_smile:
I fear that the only way to prevent this kind of issues is shipping everything you do via update sites you control, and never ever shipping anything by email again :worried:

To my own defense, I have to note that I chose the way of deprecating the old classes in my PRs to imagej-common and related repositories:

However, @ctrueden removed the deprecated classes shortly afterwards, for reasons explained in his commit:

Fortunately, fixing this issue should be as easy as replacing net.imagej.table by org.scijava.table in all occurrences. :smile:

Sorry for the trouble caused, and let me know if you encounter any issues with the table-related classes.

1 Like

Hi @imagejan,

thanks for your feedback. Indeed I’d have some question about the table stuff. I’m working with ‘net.imagej.table.ResultsTable’ and ResultsImg - which were apparently not moved over to org.scijava. How are they or their counterparts called in org.scijava?


Ok, I’ll try to use @Deprecated more.

Regarding other strategies: We (== @turekg) are in the process of deploying @ctrueden’s meltingpot script on our jenkins server, which then will build everything against new artefact versions and notify us of problems. However, “everything” means "everything listed in pom-scijava. But maybe we can find a way to allow third-party repositories to be included there as well via some sign-up process. That would be cool, but I’m very fuzzy on the details. No idea how feasible that would be…

1 Like

Oh that would be nice. However, the plugins I shipped via email were shipped that way, because the user didn’t want the code to be online. This may make things complicated.

In the meantime, can you tell me, where net.imglib2.type.ImagePlusImgFactory went? That one also escaped without saying bye. :wink:

Thanks again.

Ok, forget it. I replaced the code with something else…

ResultsTable and ResultsImg are unchanged. They stay in the imagej-common component, as they’re image-related.

ResultsTable now extends org.scijava.table.DoubleTable and adds a method img() to allow creating images from tables (all unchanged functionality).

I would be curious to see your code making use of ResultsImg, @haesleinhuepf. Would you mind sharing it? At the time when I was migrating the package to SciJava (so that I can use it in batch-processor without adding an imagej dependency), I was wondering if there’s any code making use of these classes…

1 Like

No problem:

Better copy it now - it will change tonight :wink:

1 Like

Written July 2016 :roll_eyes:

I agree that deprecating code before removing it, when possible, is a very good thing to do. But it is not always possible. The ImageJ2/SciJava table code was an example of that. Particularly when type hierarchies change, deprecation may not be enough to preserve binary backwards compatibility.

And deprecation alone is not enough. Eventually, if those deprecated classes are ultimately removed, the plugins in question—which presumably have still not been updated since they “weren’t broken” and no one recompiled them, and maybe the facility engineer already left years ago—will stop working at that time. By and large, ImageJ’s solution since 1997—and the solution of many Java libraries—has been to never remove any API ever. My strategy for the ImageJ2 layer has been to move deprecated classes to a dedicated imagej-deprecated library so that people still needing it can continue to use it. But keeping the deprecated functionality tested and working as the most recent code continues to progress does add to the maintenance burden.

ImageJ’s extensibility is the root of the problem here. We (the developers of various core libraries) can work very hard whenever an incompatibility is introduced to roll forward all affected downstream code across all of Fiji—and even beyond with community plugins to some extent—but there will always be things off our radar, such as non-public plugins and scripts.

We cannot keep this system 100% binary API compatible forever. These libraries have a massive public API footprint, and already some of them, including SciJava Common and ImageJ Ops, are at the point where another major design iteration is needed to support impending requirements. A lot of public API is going to break in the future. The best way I know to avoid being destroyed by the breakages is to make a tarball of Fiji that behaves the way you want/need, and save it with your analysis of the time.

I’d be very enthusiastic to discuss realistic ideas, suggestions, approaches, paradigms, etc., for improving this situation. But the pragmatic reality is tough: there is scarce funding for keeping ImageJ working in its current state without any “forward progress” from scientific and technical perspectives.


That’s here:

And honestly, I think it has always been there (at least since the split of imglib2 into subprojects).

I agree. However, a prewarning would have been nice. How many people out there have been building tools on imagej2 tables? These tables have been content of a learnathon 2 years ago.

Yes. Furthermore, I see some potential in improving documentation (release notes) and communication between core and plugin developers. We could consider having a central collection of Q&A:

  • What has been removed?
  • Why was it removed?
  • Is there a replacement?
  • What shall one do in case her/his code is affected?
  • Where are code examples of the new API?

Ultimate goal: minimize efforts on plugin-developers side.

I absolutely agree and see the point. This brings us back to an old topic: How do we manage releases? Remember the discussion on a hackathon?

If we had a proper release cycle, e.g. bi-anually:

  • users could rely on a recent lifeline version which is garanteed to not break within the next 6 months
  • plugin developers could be prewarned: “This lifleline version contains 3 deprecated classes (Contains, ContainsRandomAccessible, Table)” which will be removed with the next lifeline version in 6 months."
  • both developers and plugin developers could test their stuff on nightly builds. Risks resulting from these public tests for life scientists research is minimized.

Are you guys still on board for making this release cycle paradigm change happen?


I discussed this with @fjug recently, and certainly we want to see a more robust release cycle for Fiji. But someone at MPI (probably @turekg or @frauzufall or both) would need to lead the effort of making this plan a reality. It seems to go hand in hand with the new Updater work.

One big (and maybe necessary?) step in the right direction would be to hook up some sort of API diff detection to all components of Fiji, which report when API breakages have occurred. Maybe revapi would fit the bill. Without some tooling to automate checking of API breakages, I fear that some breakages like this Contains rename will always slip through the cracks. Humans are just not anal-retentive enough! :sweat_smile:

1 Like

That looks like a nice tool. I recently suggested japi-tracker in this issue:

… but revapi seems to be more actively developed.

1 Like