From 2e762ff776f368c5f9a2fd44c20b1e0712b86d57 Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Thu, 17 Jul 2025 16:16:48 -0500 Subject: [PATCH 1/8] MMCoreJ: Switch to SWIG 4 with compatibility tweak SWIG 4 replaced the `std::vector` and `std::map` wrappers with versions that fit better into Java by extending `java.util.List` and `java.util.Map`. This results in the generated Java API from being incompatible with that generated by SWIG 2-3, in the following ways (based on japicmp output): - `*Vector`, with `*` = `Boolean`, `Char`, `Double`, `Long`, `Str`, `Unsigned` - The constructor taking Java `long` (and producing that many empty/zero elements) was removed - Parameter type for `add()` and `set()` was changed from primitive to boxed (for all but `StrVector`); these methods also newly have a return value - `get()` now returns boxed, rather than primitive, type - `size()` and `capacity()` now return `int` rather than `long` - `reserve()` now takes `int` rather than `long` - `StrMap` - `get()` takes `Object` instead of `String` (source-compatible but not binary-compatible) - `set()` is replaced by `put()` - `del()` is removed (in favor of `remove()`) - `has_key()` is replaced by `containsKey()` - `empty()` is replaced by `isEmpty()` - `size()` now returns `int` rather than `long` (I'm ignoring backward-compatible changes, and incompatible changes to generated classes that should not be considered part of the API, such as `MMCoreJJNI`.) This PR explicitly adds back the `*Vector` constructors taking `long`. This was enough to get all of our Java modules in `micro-manager` to compile (as of this writing). For the remaining incompatibilities, I suggest that we leave them alone: - The changes from unboxed to boxed types and from `long` to `int` may cause compile errors under certain usage, but they do not cause any silent change in semantics. And they are hopefully even less likely to cause errors in BeanShell scripts. - I'm inclined leave `StrMap` alone, since `StrMap` is not actually used as a parameter or return value to any API methods (currently, at least). Even if there is code that uses it, it will at most get a compile error that should be easy to fix. --- MMCoreJ_wrap/MMCoreJ.i | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index 35137b03e..099a0d948 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -24,8 +24,9 @@ // CVS: $Id: MMCoreJ.i 16466 2017-08-23 21:46:52Z nico $ // -#if SWIG_VERSION < 0x020000 || SWIG_VERSION >= 0x040000 -#error SWIG 2.x or 3.x is currently required to build MMCoreJ +// Different SWIG major versions can produce incompatible Java APIs. +#if SWIG_VERSION < 0x040000 || SWIG_VERSION >= 0x050000 +#error "SWIG 4.x is required to build MMCoreJ" #endif %module (directors="1") MMCoreJ @@ -937,6 +938,19 @@ // instantiate STL mappings +// SWIG 4 changed the std::vector wrappers and (among other things) removed +// the constructor overload taking (Java) long, which creates a vector of the +// requested number of empty/default elements. Since all of the element types +// that we wrap vector for are default-constructible, we can add back this +// overload. +// See the 2019-02-28 entry in https://www.swig.org/Release/CHANGES. +%extend std::vector { + vector(size_type count) { return new std::vector(count); } +} +%extend std::vector { + vector(size_type count) { return new std::vector(count); } +} + namespace std { %typemap(javaimports) vector %{ import java.lang.Iterable; From 52e4cf2a9366c583432f33228a124527971062b4 Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:04:40 -0600 Subject: [PATCH 2/8] MMCoreJ: Remove unnecessary overrides Java 8 added a default implementation for Iterator#remove(). --- MMCoreJ_wrap/MMCoreJ.i | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index 099a0d948..adf68d875 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -979,10 +979,6 @@ namespace std { throw new NoSuchElementException(); } } - - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } }; } @@ -1030,10 +1026,6 @@ namespace std { throw new NoSuchElementException(); } } - - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } }; } @@ -1076,10 +1068,6 @@ namespace std { throw new NoSuchElementException(); } } - - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } }; } @@ -1124,10 +1112,6 @@ namespace std { throw new NoSuchElementException(); } } - - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } }; } @@ -1174,10 +1158,6 @@ namespace std { throw new NoSuchElementException(); } } - - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } }; } @@ -1222,10 +1202,6 @@ namespace std { throw new NoSuchElementException(); } } - - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } }; } From 7a086e8a2c7323232b448f22598c8db6e2f99d59 Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:07:04 -0600 Subject: [PATCH 3/8] MMCoreJ: remove mystery directive Did not seem to be generating any Java code. No use spotted either. --- MMCoreJ_wrap/MMCoreJ.i | 1 - 1 file changed, 1 deletion(-) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index adf68d875..5f997a6a8 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -604,7 +604,6 @@ // Map all exception objects coming from C++ level // generic Java Exception // -%rename(eql) operator=; // CMMError used by MMCore %typemap(throws, throws="java.lang.Exception") CMMError { From 7dbe5d32fe22ae26e60a092ea1a70f2798b6fb2c Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:08:45 -0600 Subject: [PATCH 4/8] MMCoreJ: hide MetadataError Like its already-hidden subclasses, it is not thrown by MMCoreJ. --- MMCoreJ_wrap/MMCoreJ.i | 1 + 1 file changed, 1 insertion(+) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index 5f997a6a8..600d3fa54 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -632,6 +632,7 @@ // We've translated exceptions to java.lang.Exception, so don't wrap the unused // C++ exception classes. %ignore CMMError; +%ignore MetadataError; %ignore MetadataKeyError; %ignore MetadataIndexError; From c3ace4cf3df4d4f579eab7ed0d51cc6b861203a5 Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:14:29 -0600 Subject: [PATCH 5/8] MMCoreJ: hide methods taking istringstream --- MMCoreJ_wrap/MMCoreJ.i | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index 600d3fa54..092d8bf50 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -636,6 +636,13 @@ %ignore MetadataKeyError; %ignore MetadataIndexError; +// Hide methods that take istringstream, which is not usable from Java +%ignore Metadata::readLine; +%ignore MetadataTag::ReadLine; +%ignore MetadataTag::Restore; +%ignore MetadataArrayTag::Restore; +%ignore MetadataSingleTag::Restore; + %typemap(javaimports) CMMCore %{ import mmcorej.org.json.JSONObject; From 772dbcf7bd6518e55f366c257056aa3370667251 Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:17:14 -0600 Subject: [PATCH 6/8] MMCoreJ: remove BooleanVector Not used anywhere in MMCore API; we don't need it, so remove while we're already making minor breaking changes. --- MMCoreJ_wrap/MMCoreJ.i | 51 ------------------------------------------ 1 file changed, 51 deletions(-) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index 092d8bf50..ace16fc47 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -954,9 +954,6 @@ %extend std::vector { vector(size_type count) { return new std::vector(count); } } -%extend std::vector { - vector(size_type count) { return new std::vector(count); } -} namespace std { %typemap(javaimports) vector %{ @@ -1134,53 +1131,6 @@ namespace std { } %} - - - - %typemap(javaimports) vector %{ - import java.lang.Iterable; - import java.util.Iterator; - import java.util.NoSuchElementException; - import java.lang.UnsupportedOperationException; - %} - - %typemap(javainterfaces) vector %{ Iterable%} - - %typemap(javacode) vector %{ - - public Iterator iterator() { - return new Iterator() { - - private int i_=0; - - public boolean hasNext() { - return (i_ %{ import java.lang.Iterable; @@ -1231,7 +1181,6 @@ namespace std { %template(LongVector) vector; %template(DoubleVector) vector; %template(StrVector) vector; - %template(BooleanVector) vector; %template(UnsignedVector) vector; %template(pair_ss) pair; %template(StrMap) map; From 940f6cba94f36c38cfff25a6fe3f17fd6182a4ef Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:19:43 -0600 Subject: [PATCH 7/8] MMCoreJ: remove StrMap and pair_ss Not used in MMCore API. --- MMCoreJ_wrap/MMCoreJ.i | 6 ------ 1 file changed, 6 deletions(-) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index ace16fc47..3449e28b2 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -1182,12 +1182,6 @@ namespace std { %template(DoubleVector) vector; %template(StrVector) vector; %template(UnsignedVector) vector; - %template(pair_ss) pair; - %template(StrMap) map; - - - - } From 9f9d7c8a996629972250a365c8b55bdc31d616be Mon Sep 17 00:00:00 2001 From: "Mark A. Tsuchida" Date: Mon, 8 Dec 2025 18:23:23 -0600 Subject: [PATCH 8/8] MMCoreJ: fix local variable names Copy-paste... --- MMCoreJ_wrap/MMCoreJ.i | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/MMCoreJ_wrap/MMCoreJ.i b/MMCoreJ_wrap/MMCoreJ.i index 3449e28b2..a20314bd0 100644 --- a/MMCoreJ_wrap/MMCoreJ.i +++ b/MMCoreJ_wrap/MMCoreJ.i @@ -990,11 +990,11 @@ namespace std { if (0==size()) return new Character[0]; - Character ints[] = new Character[(int) size()]; + Character cs[] = new Character[(int) size()]; for (int i=0; i