dependabot[bot] opened a new pull request, #21836: URL: https://github.com/apache/camel/pull/21836
Bumps [com.cedarsoftware:java-util](https://github.com/jdereg/java-util) from 4.94.0 to 4.98.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/jdereg/java-util/releases">com.cedarsoftware:java-util's releases</a>.</em></p> <blockquote> <h2>4.98.0</h2> <h2>Changes</h2> <ul> <li><strong>PERFORMANCE</strong>: <code>CaseInsensitiveMap.get()</code>, <code>containsKey()</code>, and <code>remove()</code> now use a <code>ThreadLocal<LookupKey></code> for String key lookups on hash-based backings (HashMap, LinkedHashMap, ConcurrentHashMap), eliminating per-call <code>CaseInsensitiveString</code> allocation. This removes the single largest remaining allocation cost center (403 JFR samples). <code>LookupKey</code> is a lightweight mutable object reused via ThreadLocal, with bidirectional equals support for both HashMap and ConcurrentHashMap lookup directions. SortedMap backings continue to use <code>CaseInsensitiveString</code> since they require <code>Comparable</code> keys.</li> <li><strong>PERFORMANCE</strong>: <code>CaseInsensitiveMap</code> now overrides <code>size()</code> and <code>isEmpty()</code> to delegate directly to the backing map, bypassing the <code>AbstractMap.size()</code> → <code>entrySet().size()</code> indirection chain (168 JFR samples eliminated).</li> <li><strong>PERFORMANCE</strong>: <code>CaseInsensitiveMap</code> internal fields changed from <code>private</code> to package-private to eliminate JVM synthetic accessor methods generated for anonymous inner class access (40 JFR samples eliminated).</li> <li><strong>PERFORMANCE</strong>: <code>StringUtilities.hashCodeIgnoreCase()</code> now inlines the case-fold logic directly into the hash loop, ensuring C2 JIT compiles the entire loop as a single compilation unit.</li> <li><strong>PERFORMANCE</strong>: <code>StringUtilities.foldCaseForHash()</code> branch ordering optimized to check <code>c <= 'Z'</code> first, partitioning ASCII so uppercase and lowercase each take only two comparisons.</li> <li><strong>BUG FIX</strong>: <code>ConverterDurationToOffsetDateTimeTest</code> used the current system timezone offset to compute expected values, but the conversion target is the epoch (1970). Fixed to compute the offset at the actual target instant.</li> <li><strong>TESTING</strong>: Added <code>ToonRoundTripTest</code> — 46 parameterized tests verifying all <code>Converter</code>-supported types round-trip through TOON format.</li> <li><strong>TESTING</strong>: Added <code>ConverterDurationToOffsetDateTimeTest</code> — verifies Duration → OffsetDateTime conversion across multiple scenarios.</li> </ul> <p><strong>Maven:</strong></p> <pre lang="xml"><code><dependency> <groupId>com.cedarsoftware</groupId> <artifactId>java-util</artifactId> <version>4.98.0</version> </dependency> </code></pre> <h2>4.97.0</h2> <h2>Changes</h2> <ul> <li><strong>PERFORMANCE</strong>: <code>FastReader.readUntil()</code> now splits the inner loop into a read-only delimiter scan followed by a bulk <code>System.arraycopy</code>, allowing the JIT to optimize the tight scan loop independently from memory writes.</li> <li><strong>PERFORMANCE</strong>: <code>FastReader.readUntil()</code> scan loop now uses a <code>do-while</code> with a single array access per iteration and hoists position assignment above the delimiter check to eliminate a duplicate write.</li> </ul> <p><strong>Maven:</strong></p> <pre lang="xml"><code><dependency> <groupId>com.cedarsoftware</groupId> <artifactId>java-util</artifactId> <version>4.97.0</version> </dependency> </code></pre> <h2>4.96.0</h2> <h3>Bug Fix</h3> <ul> <li><strong><code>ClassUtilities.trySetAccessible()</code></strong> no longer caches successful <code>setAccessible(true)</code> results. The <code>WeakHashMap</code>-based cache uses <code>equals()</code> for lookup, but <code>Field.equals()</code> matches by declaring class, name, and type — not identity. When <code>getDeclaredFields()</code> was called with different predicates, the JVM returned different <code>Field</code> instances for the same logical field; the cache returned <code>TRUE</code> for the second instance without ever calling <code>setAccessible(true)</code> on it, leaving it inaccessible. This caused <code>Traverser</code> to silently skip inaccessible fields, breaking <code>GraphComparator.applyDelta()</code>. Only failures (<code>FALSE</code>) are now cached to avoid expensive repeated exceptions on JPMS-sealed modules.</li> </ul> <h3>Install</h3> <p><strong>Maven</strong></p> <pre lang="xml"><code><dependency> <groupId>com.cedarsoftware</groupId> <artifactId>java-util</artifactId> <version>4.96.0</version> </dependency> </tr></table> </code></pre> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/jdereg/java-util/blob/master/changelog.md">com.cedarsoftware:java-util's changelog</a>.</em></p> <blockquote> <h4>4.98.0 (Unreleased)</h4> <h4>4.97.0 - 2026-03-03</h4> <ul> <li><strong>PERFORMANCE</strong>: <code>FastReader.readUntil()</code> now splits the inner loop into a read-only delimiter scan followed by a bulk <code>System.arraycopy</code>, allowing the JIT to optimize the tight scan loop independently from memory writes.</li> <li><strong>PERFORMANCE</strong>: <code>FastReader.readUntil()</code> scan loop now uses a <code>do-while</code> with a single array access per iteration and hoists position assignment above the delimiter check to eliminate a duplicate write.</li> </ul> <h4>4.96.0 - 2026-02-28</h4> <ul> <li><strong>BUG FIX</strong>: <code>ClassUtilities.trySetAccessible()</code> no longer caches successful <code>setAccessible(true)</code> results. The <code>WeakHashMap</code>-based cache uses <code>equals()</code> for lookup, but <code>Field.equals()</code> matches by declaring class, name, and type — not identity. When <code>getDeclaredFields()</code> was called with different predicates, the JVM returned different <code>Field</code> instances for the same logical field; the cache returned <code>TRUE</code> for the second instance without ever calling <code>setAccessible(true)</code> on it, leaving it inaccessible. This caused <code>Traverser</code> to silently skip inaccessible fields, breaking <code>GraphComparator.applyDelta()</code>. Only failures (<code>FALSE</code>) are now cached to avoid expensive repeated exceptions on JPMS-sealed modules.</li> </ul> <h4>4.95.0 - 2026-02-28</h4> <ul> <li><strong>BUG FIX</strong>: <code>ArrayUtilities.setPrimitiveElement(char[], ...)</code> now throws <code>IllegalArgumentException</code> for incompatible non-char inputs instead of silently coercing values to <code>'\0'</code>.</li> <li><strong>BUG FIX</strong>: <code>ArrayUtilities</code> type-mismatch errors from <code>setElement(...)</code> / <code>setPrimitiveElement(...)</code> now report stable <code>IllegalArgumentException</code> messages without invoking arbitrary <code>element.toString()</code> during error construction.</li> <li><strong>BUG FIX</strong>: <code>ArrayUtilities</code> dangerous-class validation now honors <code>arrayutilities.dangerous.classes.validation.enabled</code> as an independent runtime toggle (default enabled for backward compatibility).</li> <li><strong>PERFORMANCE</strong>: <code>ArrayUtilities</code> now caches parsed security properties (<code>security</code>, <code>component validation</code>, <code>dangerous validation</code>, <code>max array size</code>, and dangerous-pattern list) with source-based invalidation; <code>toArray()</code> now captures collection size once.</li> <li><strong>BUG FIX</strong>: <code>ByteUtilities</code> now uses a trusted internal hex-decode path for embedded framework constants (for example <code>CompactMap</code> template bytecode), so restrictive user hex-length limits no longer break <code>CompactMap.builder()</code> initialization.</li> <li><strong>PERFORMANCE</strong>: <code>ByteUtilities</code> security configuration now uses a single snapshot cache with property-source invalidation, and multi-byte <code>indexOf</code>/<code>lastIndexOf</code> scans now fast-reject on first/last-byte mismatches before inner comparison.</li> <li><strong>BUG FIX</strong>: <code>CaseInsensitiveMap.CaseInsensitiveEntry.setValue()</code> now updates both the backing map and the entry view value so <code>entry.getValue()</code> reflects the new value immediately.</li> <li><strong>BUG FIX</strong>: <code>CaseInsensitiveMap.equals()</code> now rejects false-positive equality when compared maps contain duplicate case-equivalent keys (for example, both <code>"ID"</code> and <code>"id"</code>), preventing collapsed-key matches from being treated as equal.</li> <li><strong>BUG FIX</strong>: <code>CaseInsensitiveMap</code> key normalization for <code>MultiKeyMap</code> with <code>flattenDimensions=false</code> now preserves <code>Set</code> semantics during recursive conversion, so set-based keys remain order-insensitive.</li> <li><strong>BUG FIX</strong>: <code>CaseInsensitiveMap</code> mutable view operations now correctly mutate <code>MultiKeyMap</code> backings: <code>keySet()/entrySet()/values()</code> iterator removals and <code>retainAll()</code> now remove backing entries instead of mutating snapshot views.</li> <li><strong>BUG FIX</strong>: <code>CaseInsensitiveMap</code> with <code>MultiKeyMap</code> backing now normalizes keys consistently for <code>ConcurrentMap</code> APIs (<code>compute*</code>, <code>merge</code>, <code>putIfAbsent</code>, <code>remove(k,v)</code>, <code>replace*</code>) and when copying from source maps into a <code>MultiKeyMap</code> destination.</li> <li><strong>PERFORMANCE</strong>: <code>CaseInsensitiveMap</code> caches <code>MultiKeyMap.flattenDimensions</code> at construction time to avoid repeated backing-map casts/lookups in hot multi-key normalization paths.</li> <li><strong>PERFORMANCE</strong>: <code>CaseInsensitiveMap</code> concurrent-aware iterators now receive backing concurrency mode directly, removing per-iterator class-name introspection overhead; recursive multi-key normalization now skips unnecessary recursion for scalar elements.</li> <li><strong>BUG FIX</strong>: <code>CaseInsensitiveSet.equals()</code> now enforces bidirectional set containment checks, removing asymmetric equality outcomes against other <code>Set</code> implementations.</li> <li><strong>BUG FIX</strong>: <code>ClassUtilities.loadResourceAsBytes()</code> now correctly falls back to the <code>ClassUtilities</code> class loader when the thread context loader is present but does not contain the requested resource.</li> <li><strong>BUG FIX</strong>: <code>ClassUtilities</code> named-parameter varargs construction now treats an omitted varargs parameter as an empty array instead of creating a single null/default element.</li> <li><strong>PERFORMANCE</strong>: <code>ClassUtilities.findInheritanceMatches()</code> now avoids per-call hierarchy-cache map allocation for single-value candidate sets.</li> <li><strong>PERFORMANCE</strong>: <code>ClassUtilities.getConstructorPlanCache()</code> now uses <code>computeIfAbsent()</code> to avoid redundant concurrent cache-map allocations.</li> <li><strong>PERFORMANCE</strong>: <code>ClassUtilities.loadResourceAsBytes()</code> now reuses resolved class loaders during leading-slash retry, avoiding repeated loader lookups and duplicate probes.</li> <li><strong>BUG FIX</strong>: <code>ClassValueMap.clear()</code> now atomically replaces the <code>ClassValue</code> cache after clearing backing storage, preventing quiescent stale <code>get()</code> reads after concurrent <code>put()/get()/clear()</code> interleavings.</li> <li><strong>BUG FIX</strong>: <code>ClassValueMap.putIfAbsent()</code> now treats null-mapped entries as absent (for both <code>Class</code> keys and <code>null</code> key), matching <code>Map</code> semantics and fixing downstream <code>merge()</code> behavior on null-mapped entries.</li> <li><strong>BUG FIX</strong>: <code>ClassValueMap</code> mutable views now support removal as expected for mutable maps: <code>entrySet().iterator().remove()</code>, <code>entrySet().remove(entry)</code>, <code>keySet().remove(key)</code>, and <code>values().remove(value)</code> all remove backing entries and invalidate per-class cache entries correctly.</li> <li><strong>PERFORMANCE</strong>: <code>ClassValueMap.clear()</code> now invalidates cached class lookups with a single cache-instance swap instead of key snapshot + per-key invalidation.</li> <li><strong>PERFORMANCE</strong>: <code>ClassValueMap.computeIfAbsent()</code> now probes backing storage first for non-null hits, avoiding miss-path <code>ClassValue</code> sentinel churn before atomic compute.</li> <li><strong>PERFORMANCE</strong>: <code>ClassValueMap.unmodifiableView()</code> now returns a cached wrapper instance instead of allocating a new unmodifiable view on each call.</li> <li><strong>BUG FIX</strong>: <code>ClassValueSet.clear()</code> now atomically invalidates the entire <code>ClassValue</code> membership cache by replacing the cache instance, preventing stale <code>contains()</code> positives after concurrent <code>clear()</code> interleavings.</li> <li><strong>PERFORMANCE</strong>: <code>ClassValueSet.retainAll()</code> now removes via a single iterator pass (no intermediate identity set allocation), and iterator-based removals now remove directly from the backing iterator while invalidating only the affected cache entry.</li> <li><strong>PERFORMANCE</strong>: <code>ClassValueSet</code> now includes fast paths for <code>retainAll(this)</code>, <code>retainAll(empty)</code>, <code>removeAll(this)</code>, and optimized removal when <code>removeAll()</code> is passed another <code>ClassValueSet</code>; <code>unmodifiableView()</code> now reuses a cached wrapper instance.</li> <li><strong>PERFORMANCE</strong>: <code>CollectionHandling</code> — collection factory cache (<code>FACTORY_CACHE</code>) now uses <code>ClassValueMap</code> instead of <code>ConcurrentHashMap</code> for faster O(1) per-class lookups during collection type resolution.</li> <li><strong>BUG FIX</strong>: <code>CompactMap.CompactMapComparator.compare()</code> — returned 0 for distinct non-<code>Comparable</code> keys of the same class, causing sorted/reverse <code>CompactMap</code> instances to overwrite entries. Added <code>System.identityHashCode()</code> tiebreaker so distinct same-class objects are never treated as equal.</li> <li><strong>BUG FIX</strong>: <code>CompactMap.entrySet().remove()</code> and <code>removeAll()</code> — removed entries by key only, ignoring the entry's value. Per the <code>Set.remove()</code> contract, <code>entrySet().remove(entry)</code> must only remove when both key and value match. Now delegates to <code>contains(entry)</code> before removing.</li> <li><strong>BUG FIX</strong>: <code>CompactMap.equals()</code> compact-array path now rejects duplicate case-insensitive equivalent keys in compared maps, preventing false-positive equality matches.</li> <li><strong>BUG FIX</strong>: <code>CompactMap</code> constructor — <code>getNewMap()</code> returning a <code>CompactMap</code> (or subclass like <code>CompactCIHashMap</code>) is now rejected with <code>IllegalStateException</code>. Using a <code>CompactMap</code> as a backing map creates recursive nested state machines and is never correct — use <code>HashMap</code>, <code>LinkedHashMap</code>, <code>TreeMap</code>, or <code>CaseInsensitiveMap</code> instead.</li> <li><strong>BUG FIX</strong>: <code>CompactMap</code> constructor — legacy subclasses that override <code>isCaseInsensitive()</code> to return <code>true</code> without returning a <code>CaseInsensitiveMap</code> from <code>getNewMap()</code> now throw <code>IllegalStateException</code> at construction time. Previously, case-insensitive lookups silently stopped working after the map transitioned from compact array state to MAP state.</li> <li><strong>BUG FIX</strong>: <code>CompactMap</code> now correctly restores empty-state invariants after map-backed removals (<code>isEmpty()==true</code> when <code>size()==0</code>), including map-to-empty transitions through iterator removal.</li> <li><strong>PERFORMANCE</strong>: <code>CompactMap.equals()</code> compact-array path now uses keyed lookups (and a normalized case-insensitive lookup map when needed) instead of nested scans; non-legacy sorted/reverse iterators skip redundant array re-sort checks.</li> <li><strong>PERFORMANCE</strong>: <code>CompactMap.putAll()</code> now avoids eager map-state transitions when incoming entries only overwrite existing keys; compact-array maps stay compact when unique key count remains within threshold.</li> <li><strong>BUG FIX</strong>: <code>CompactSet.withConfig()</code> now preserves the source set's backing <code>mapType</code> when ordering is unchanged, preventing silent downgrades (for example, losing <code>ConcurrentHashMap</code> backing on reconfiguration).</li> <li><strong>BUG FIX</strong>: <code>CompactSet</code> — case-insensitive equality and hash code now use case-insensitive canonical semantics, restoring contract consistency (equal case-insensitive sets now produce equal hash codes and avoid asymmetric equality against standard case-sensitive sets).</li> <li><strong>BUG FIX</strong>: <code>ConcurrentHashMapNullSafe.putIfAbsent()</code> now treats null-mapped keys as absent, allowing null-to-non-null replacement for both null and non-null keys.</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/jdereg/java-util/commit/8484f0a7813f030109c41706af6360ab1e734de9"><code>8484f0a</code></a> Fix flaky MultiKeyMap timing test, suppress expected Executor test logging, u...</li> <li><a href="https://github.com/jdereg/java-util/commit/e5d8147d2b89ac633e3d01ec4f3bf77bfb570ca3"><code>e5d8147</code></a> Release 4.98.0</li> <li><a href="https://github.com/jdereg/java-util/commit/d910489d2ae2e0b3c160116cb9b2f4b75db46cb7"><code>d910489</code></a> Remove stale JDK1.8 Javadoc comment from MapUtilities.mapOf()</li> <li><a href="https://github.com/jdereg/java-util/commit/f78385c9df3989cfe724758cd022c3b980b28282"><code>f78385c</code></a> Add dedicated ToonRoundTripTest, remove TOON tests from ConverterEverythingTest</li> <li><a href="https://github.com/jdereg/java-util/commit/d926fcba51ba795d6afa55b17bbdc0f00a6cf7d8"><code>d926fcb</code></a> Fix DST-sensitive test failures in ConverterDurationToOffsetDateTimeTest</li> <li><a href="https://github.com/jdereg/java-util/commit/bc25b5bfed7b12c48953a4f37a72420078056b9b"><code>bc25b5b</code></a> Add TOON round-trip testing to ConverterEverythingTest</li> <li><a href="https://github.com/jdereg/java-util/commit/bf38e739f1af02f9e9bfd6262d2348db7e3d23ff"><code>bf38e73</code></a> Performance: eliminate CaseInsensitiveString allocation on read-path lookups</li> <li><a href="https://github.com/jdereg/java-util/commit/8c328413a12047657a2545adc7858613b75ee6b1"><code>8c32841</code></a> Performance: optimize CaseInsensitiveMap size()/isEmpty() and StringUtilities...</li> <li><a href="https://github.com/jdereg/java-util/commit/ba6db1b035381caebc77d79667d595799dd4412c"><code>ba6db1b</code></a> Bump version to 4.98.0, update json-io test dependency to 4.97.0</li> <li><a href="https://github.com/jdereg/java-util/commit/9fd05a65746f616eb2a06584f796ea679d728459"><code>9fd05a6</code></a> Move Jackson version to property for consistency</li> <li>Additional commits viewable in <a href="https://github.com/jdereg/java-util/compare/4.94.0...4.98.0">compare view</a></li> </ul> </details> <br /> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
