From 0c88c7481d6c622ecdc0c0ddac0aaf5d8f09c4f7 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Mon, 7 Apr 2025 09:52:33 -0700 Subject: [PATCH] Fixes #5063: generate distinct names (type ids) if `Version` has no artifact id --- release-notes/VERSION-2.x | 2 ++ .../jackson/databind/module/SimpleModule.java | 26 +++++++++++++++---- .../databind/module/SimpleModuleTest.java | 24 +++++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/release-notes/VERSION-2.x b/release-notes/VERSION-2.x index 903d912d76..f80c0aa013 100644 --- a/release-notes/VERSION-2.x +++ b/release-notes/VERSION-2.x @@ -83,6 +83,8 @@ Project: jackson-databind (contributed by @pjfanning) #5052: Minor bug in `FirstCharBasedValidator.forFirstNameRule()`: returns `null` in non-default case +#5063: `SimpleModule` not registered due to `getTypeId()` returning an empty string + (reported by @seadbrane) #5069: Add copy-constructor for `MappingIterator` (contributed by @wrongwrong) diff --git a/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java b/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java index 262f618c2a..e5d9551a5b 100644 --- a/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java +++ b/src/main/java/com/fasterxml/jackson/databind/module/SimpleModule.java @@ -130,14 +130,19 @@ public SimpleModule() { // note: generate different name for direct instantiation, sub-classing; // this to avoid collision in former case while still addressing // [databind#3110] - _name = (getClass() == SimpleModule.class) - ? "SimpleModule-"+MODULE_ID_SEQ.getAndIncrement() - : getClass().getName(); + _name = _generateName(getClass()); _version = Version.unknownVersion(); // 07-Jun-2021, tatu: [databind#3110] Not passed explicitly so... _hasExplicitName = false; } + // @since 2.19 + private static String _generateName(Class cls) { + return (cls == SimpleModule.class) + ? "SimpleModule-"+MODULE_ID_SEQ.getAndIncrement() + : cls.getName(); + } + /** * Convenience constructor that will default version to * {@link Version#unknownVersion()}. @@ -148,10 +153,21 @@ public SimpleModule(String name) { /** * Convenience constructor that will use specified Version, - * including name from {@link Version#getArtifactId()}. + * including name from {@link Version#getArtifactId()} + * (if available -- if not, will generate). */ public SimpleModule(Version version) { - this(version.getArtifactId(), version); + // 07-Apr-2025, tatu: [databind#5063]: check that we actually have a name; + // if not, generate it + String maybeName = version.getArtifactId(); + // Only considered explicit if name is non-null and not empty (i.e. not generated) + _hasExplicitName = (maybeName != null) && !maybeName.isEmpty(); + if (_hasExplicitName) { + _name = maybeName; + } else { + _name = _generateName(getClass()); + } + _version = Version.unknownVersion(); } /** diff --git a/src/test/java/com/fasterxml/jackson/databind/module/SimpleModuleTest.java b/src/test/java/com/fasterxml/jackson/databind/module/SimpleModuleTest.java index 58cd7418a6..5198c232d9 100644 --- a/src/test/java/com/fasterxml/jackson/databind/module/SimpleModuleTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/module/SimpleModuleTest.java @@ -235,6 +235,19 @@ public void serialize(Test3787Bean value, JsonGenerator gen, SerializerProvider } } + // For [databind#5063] + static class Module5063A extends SimpleModule { + public Module5063A() { + super(Version.unknownVersion()); + } + } + + static class Module5063B extends SimpleModule { + public Module5063B() { + super(Version.unknownVersion()); + } + } + /* /********************************************************** /* Unit tests; first, verifying need for custom handlers @@ -624,4 +637,15 @@ public void testAddModuleWithDeserializerTwiceThenOnlyLatestIsKept_reverseOrder( assertEquals("I am A", result.value); } + + // For [databind#5063] + @Test + public void testDuplicateModules5063() { + ObjectMapper mapper = JsonMapper.builder() + .addModule(new Module5063A()) + .addModule(new Module5063B()) + .build(); + Set modules = mapper.getRegisteredModuleIds(); + assertEquals(2, modules.size()); + } }