From 3d5f95f636e19a501c16163b2c22559733f56e93 Mon Sep 17 00:00:00 2001 From: Stefan Hahmann Date: Thu, 7 May 2026 13:43:05 +0200 Subject: [PATCH 1/5] Make logging of unknown fields in OME metadata less severe This warning fired e.g. when reading https://livingobjects.ebi.ac.uk/idr/zarr/v0.5/idr0033A/BR00109990_C2.zarr/0 Since, this log can actually be ignored, I propose to lower the severity of the log. --- .../zarr/zarrjava/experimental/ome/OmeObjectMappers.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java index 9f1c7c3f..977fda7f 100644 --- a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java +++ b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java @@ -32,7 +32,7 @@ static ObjectMapper makeV3Mapper() { private static final class UnknownOmePropertyWarningHandler extends DeserializationProblemHandler { private static final Logger LOGGER = Logger.getLogger(UnknownOmePropertyWarningHandler.class.getName()); - private static final Set WARNED_FIELDS = ConcurrentHashMap.newKeySet(); + private static final Set UNKNOWN_FIELDS = ConcurrentHashMap.newKeySet(); @Override public boolean handleUnknownProperty( @@ -46,8 +46,8 @@ public boolean handleUnknownProperty( ? ((Class) beanOrClass).getName() : beanOrClass.getClass().getName(); String key = target + "#" + propertyName; - if (WARNED_FIELDS.add(key)) { - LOGGER.warning( + if (UNKNOWN_FIELDS.add(key)) { + LOGGER.fine( "Ignoring unknown OME metadata field '" + propertyName + "' for " + target); } p.skipChildren(); From 252b9d9ceb601d8da1355aaa3bca8115e8a2cf29 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 8 Sep 2026 12:06:34 +0200 Subject: [PATCH 2/5] Apply suggestion from @normanrz --- .../dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java index 977fda7f..32792947 100644 --- a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java +++ b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java @@ -47,7 +47,7 @@ public boolean handleUnknownProperty( : beanOrClass.getClass().getName(); String key = target + "#" + propertyName; if (UNKNOWN_FIELDS.add(key)) { - LOGGER.fine( + LOGGER.info( "Ignoring unknown OME metadata field '" + propertyName + "' for " + target); } p.skipChildren(); From 577c63ade8ca364352e14dd94670dfdaad5952d2 Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 8 Sep 2026 12:06:59 +0200 Subject: [PATCH 3/5] Apply suggestion from @normanrz --- .../dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java index 32792947..977fda7f 100644 --- a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java +++ b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java @@ -47,7 +47,7 @@ public boolean handleUnknownProperty( : beanOrClass.getClass().getName(); String key = target + "#" + propertyName; if (UNKNOWN_FIELDS.add(key)) { - LOGGER.info( + LOGGER.fine( "Ignoring unknown OME metadata field '" + propertyName + "' for " + target); } p.skipChildren(); From ecf63f58415a95a60c903cfcc01e32ca9f6fde3c Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 8 Sep 2026 12:23:42 +0200 Subject: [PATCH 4/5] Log unknown OME fields at INFO instead of FINE Follow-up to the PR discussion: FINE hides the message entirely, while WARNING pops up the FIJI console in red. INFO keeps the notice visible without signalling an error. Also renames the handler (no longer warning-level) and updates the tests to capture INFO records, which fixes the failing build. Co-Authored-By: Claude Opus 5 --- .../experimental/ome/OmeObjectMappers.java | 10 +++--- .../ome/OmeObjectMappersTest.java | 36 +++++++++++-------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java index 977fda7f..7a9739b6 100644 --- a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java +++ b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java @@ -19,19 +19,19 @@ private OmeObjectMappers() { static ObjectMapper makeV2Mapper() { ObjectMapper mapper = dev.zarr.zarrjava.v2.Node.makeObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); - mapper.addHandler(new UnknownOmePropertyWarningHandler()); + mapper.addHandler(new UnknownOmePropertyLoggingHandler()); return mapper; } static ObjectMapper makeV3Mapper() { ObjectMapper mapper = dev.zarr.zarrjava.v3.Node.makeObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); - mapper.addHandler(new UnknownOmePropertyWarningHandler()); + mapper.addHandler(new UnknownOmePropertyLoggingHandler()); return mapper; } - private static final class UnknownOmePropertyWarningHandler extends DeserializationProblemHandler { - private static final Logger LOGGER = Logger.getLogger(UnknownOmePropertyWarningHandler.class.getName()); + private static final class UnknownOmePropertyLoggingHandler extends DeserializationProblemHandler { + private static final Logger LOGGER = Logger.getLogger(UnknownOmePropertyLoggingHandler.class.getName()); private static final Set UNKNOWN_FIELDS = ConcurrentHashMap.newKeySet(); @Override @@ -47,7 +47,7 @@ public boolean handleUnknownProperty( : beanOrClass.getClass().getName(); String key = target + "#" + propertyName; if (UNKNOWN_FIELDS.add(key)) { - LOGGER.fine( + LOGGER.info( "Ignoring unknown OME metadata field '" + propertyName + "' for " + target); } p.skipChildren(); diff --git a/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java b/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java index 29959965..504360ed 100644 --- a/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java +++ b/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java @@ -24,11 +24,11 @@ class OmeObjectMappersTest { - private static final String WARNING_LOGGER_NAME = - "dev.zarr.zarrjava.experimental.ome.OmeObjectMappers$UnknownOmePropertyWarningHandler"; + private static final String HANDLER_LOGGER_NAME = + "dev.zarr.zarrjava.experimental.ome.OmeObjectMappers$UnknownOmePropertyLoggingHandler"; @Test - void v3MapperWarnsAndContinuesOnUnknownOmeFields() { + void v3MapperLogsAndContinuesOnUnknownOmeFields() { String unknownTop = "unknown_top_" + UUID.randomUUID(); String unknownAxis = "unknown_axis_" + UUID.randomUUID(); @@ -54,9 +54,11 @@ void v3MapperWarnsAndContinuesOnUnknownOmeFields() { omeRaw.put("multiscales", Arrays.asList(multiscale)); omeRaw.put(unknownTop, "surprise"); - Logger logger = Logger.getLogger(WARNING_LOGGER_NAME); + Logger logger = Logger.getLogger(HANDLER_LOGGER_NAME); CapturingHandler handler = new CapturingHandler(); + Level previousLevel = logger.getLevel(); logger.addHandler(handler); + logger.setLevel(Level.INFO); try { ObjectMapper mapper = OmeObjectMappers.makeV3Mapper(); OmeMetadata parsed = mapper.convertValue(omeRaw, OmeMetadata.class); @@ -66,15 +68,16 @@ void v3MapperWarnsAndContinuesOnUnknownOmeFields() { assertNotNull(parsed.multiscales); assertEquals(1, parsed.multiscales.size()); assertEquals("x", parsed.multiscales.get(0).axes.get(0).name); - assertTrue(handler.containsWarningWith(unknownTop)); - assertTrue(handler.containsWarningWith(unknownAxis)); + assertTrue(handler.containsMessageWith(unknownTop)); + assertTrue(handler.containsMessageWith(unknownAxis)); } finally { logger.removeHandler(handler); + logger.setLevel(previousLevel); } } @Test - void v2MapperWarnsAndContinuesOnUnknownFields() { + void v2MapperLogsAndContinuesOnUnknownFields() { String unknownEntryField = "unknown_entry_" + UUID.randomUUID(); Map axis = new HashMap<>(); @@ -94,9 +97,11 @@ void v2MapperWarnsAndContinuesOnUnknownFields() { entryRaw.put("datasets", Arrays.asList(dataset)); entryRaw.put(unknownEntryField, 123); - Logger logger = Logger.getLogger(WARNING_LOGGER_NAME); + Logger logger = Logger.getLogger(HANDLER_LOGGER_NAME); CapturingHandler handler = new CapturingHandler(); + Level previousLevel = logger.getLevel(); logger.addHandler(handler); + logger.setLevel(Level.INFO); try { ObjectMapper mapper = OmeObjectMappers.makeV2Mapper(); MultiscalesEntry entry = mapper.convertValue(entryRaw, MultiscalesEntry.class); @@ -105,9 +110,10 @@ void v2MapperWarnsAndContinuesOnUnknownFields() { assertEquals(1, entry.axes.size()); assertEquals(1, entry.datasets.size()); assertFalse(entry.datasets.get(0).coordinateTransformations.isEmpty()); - assertTrue(handler.containsWarningWith(unknownEntryField)); + assertTrue(handler.containsMessageWith(unknownEntryField)); } finally { logger.removeHandler(handler); + logger.setLevel(previousLevel); } } @@ -346,12 +352,12 @@ void v3MapperParsesV06SceneMetadataRefsAndNestedTransforms() { } private static final class CapturingHandler extends Handler { - private final List warnings = new ArrayList<>(); + private final List messages = new ArrayList<>(); @Override public void publish(LogRecord record) { - if (record.getLevel().intValue() >= Level.WARNING.intValue()) { - warnings.add(record.getMessage()); + if (record.getLevel().intValue() >= Level.INFO.intValue()) { + messages.add(record.getMessage()); } } @@ -363,9 +369,9 @@ public void flush() { public void close() { } - boolean containsWarningWith(String token) { - for (String warning : warnings) { - if (warning != null && warning.contains(token)) { + boolean containsMessageWith(String token) { + for (String message : messages) { + if (message != null && message.contains(token)) { return true; } } From bc1314eb11a67d39b77d002b75992b5b70bc48da Mon Sep 17 00:00:00 2001 From: Norman Rzepka Date: Tue, 8 Sep 2026 12:25:12 +0200 Subject: [PATCH 5/5] Keep unknown OME field logging at FINE Reverts the level back to FINE as originally proposed; the test now sets the logger level explicitly so the FINE records are still captured. Co-Authored-By: Claude Opus 5 --- .../zarr/zarrjava/experimental/ome/OmeObjectMappers.java | 2 +- .../zarrjava/experimental/ome/OmeObjectMappersTest.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java index 7a9739b6..1ea5a3ba 100644 --- a/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java +++ b/src/main/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappers.java @@ -47,7 +47,7 @@ public boolean handleUnknownProperty( : beanOrClass.getClass().getName(); String key = target + "#" + propertyName; if (UNKNOWN_FIELDS.add(key)) { - LOGGER.info( + LOGGER.fine( "Ignoring unknown OME metadata field '" + propertyName + "' for " + target); } p.skipChildren(); diff --git a/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java b/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java index 504360ed..23f35f9f 100644 --- a/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java +++ b/src/test/java/dev/zarr/zarrjava/experimental/ome/OmeObjectMappersTest.java @@ -58,7 +58,7 @@ void v3MapperLogsAndContinuesOnUnknownOmeFields() { CapturingHandler handler = new CapturingHandler(); Level previousLevel = logger.getLevel(); logger.addHandler(handler); - logger.setLevel(Level.INFO); + logger.setLevel(Level.FINE); try { ObjectMapper mapper = OmeObjectMappers.makeV3Mapper(); OmeMetadata parsed = mapper.convertValue(omeRaw, OmeMetadata.class); @@ -101,7 +101,7 @@ void v2MapperLogsAndContinuesOnUnknownFields() { CapturingHandler handler = new CapturingHandler(); Level previousLevel = logger.getLevel(); logger.addHandler(handler); - logger.setLevel(Level.INFO); + logger.setLevel(Level.FINE); try { ObjectMapper mapper = OmeObjectMappers.makeV2Mapper(); MultiscalesEntry entry = mapper.convertValue(entryRaw, MultiscalesEntry.class); @@ -356,7 +356,7 @@ private static final class CapturingHandler extends Handler { @Override public void publish(LogRecord record) { - if (record.getLevel().intValue() >= Level.INFO.intValue()) { + if (record.getLevel().intValue() >= Level.FINE.intValue()) { messages.add(record.getMessage()); } }