Java 21 review: correctness/security fixes plus java.time, record, and secure-cipher additions#23
Merged
Merged
Conversation
…n tests Address review findings across core utilities while preserving backward compatibility. Behavior- and format-changing items (e.g. cipher default mode, UUID format, equals/hashCode contracts) are intentionally deferred. collection: - ArrayMap.clone() rebuilds buckets instead of truncating the hash table - LruHashSet/CaseInsensitiveSet implement writeObject/readObject - CaseInsensitiveMap handles null keys and lowercases with Locale.ROOT misc/lang: - DynamicProperties: fix reload throttle, delegate Map default methods, create parent directories with mkdirs() - SystemUtil/LocaleUtil use volatile suppliers; ClassUtil.newInstance uses getDeclaredConstructor(); StringUtil.replace guards empty search text io/nio/net: - FileUtil.readBytes reads until the buffer is filled or EOF - ChannelUtil loops transferTo until the whole source is copied - SerializeUtil default filter enforces depth/refs/bytes/array-length limits - Preserve a literal '+' when decoding URL/resource/jar/zip paths crypto/convert/beans/timer/xml/log/security: - CachedCipher re-initializes pooled ciphers per key; clears pool on config change - TimestampConversionUtil honors the locale; DecimalFormatSymbolsUtil returns a clone - BeanDescImpl no longer mutates caller args during method resolution; BeanDescFactory deregisters its cache disposable on clear() - TimeoutManager fixes the thread-clear race; TimeoutTask fields are volatile - SchemaFactoryUtil enables secure processing; Logger is null-safe Adds regression tests for the high-severity fixes.
…ure APIs Additive enhancements that do not change any existing behavior or defaults. - convert: new TemporalConversionUtil converts Date/Calendar/epoch-millis/ISO strings and java.time values to LocalDate/LocalDateTime/LocalTime/Instant/ OffsetDateTime/ZonedDateTime (system-default zone, or an explicit ZoneId) - beans: BeanDescImpl detects record components as read-only properties and instantiates records through their canonical constructor - crypto: CachedCipher.encryptWithIv/decryptWithIv provide AES/GCM authenticated encryption with a fresh random IV per call; the default Blowfish/ECB pool is left unchanged - io: CloseableUtil.closeAndRethrow propagates close failures (for output streams); FileUtil.isRealPathSafe resolves symbolic links via toRealPath - exception: add InvalidAlgorithmParameterRuntimeException (message ECL0117) Adds regression tests for all new APIs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Java 21 review of the core utilities. Two commits:
fix(core)— correctness, thread-safety, and security bug fixes (backward-compatible only), with regression tests.feat(core)— additive enhancements:java.timeconversions, record support, and opt-in secure APIs. No existing behavior or defaults change.mvn clean test→ 707 tests, 0 failures.Fixes (backward-compatible)
collection
ArrayMap.clone()rebuilds the hash table instead of truncating it to the element count (corruptedget/remove, could throwArrayIndexOutOfBoundsExceptionon a laterput).LruHashSet/CaseInsensitiveSetimplementwriteObject/readObject(were unserializable / restored to anullmap).CaseInsensitiveMapacceptsnullkeys and lowercases withLocale.ROOT.misc / lang
DynamicProperties: fixed a reload-throttle bug that disabled change detection under frequent access; delegated theMapdefault methods to the backing store; usedmkdirs().SystemUtil/LocaleUtilusevolatilesuppliers;ClassUtil.newInstanceusesgetDeclaredConstructor();StringUtil.replaceguards an empty search string; plus small modernizations.io / nio / net
FileUtil.readBytesreads until the buffer is filled or EOF (a shortFileChannel.readreturned zero-padded data); added a 2 GB guard.ChannelUtilloopstransferTountil the whole source is copied.SerializeUtil's default deserialization filter enforces depth / reference / stream-byte / array-length limits.+when decoding URL / resource / jar / zip paths.crypto / convert / beans / timer / xml / log / security
CachedCipherre-initializes a pooled cipher with the current key on every operation and clears the pool on config change.TimestampConversionUtilhonors theLocale;DecimalFormatSymbolsUtilreturns a clone.BeanDescImplno longer mutates the caller's args during overload resolution;BeanDescFactoryderegisters its cache disposable onclear().TimeoutManagerfixes a thread-clear race;TimeoutTaskfields arevolatile;SchemaFactoryUtilenables secure processing;Loggeris null-safe.Enhancements (additive — no behavior change)
convert: newTemporalConversionUtilconvertsDate/Calendar/ epoch-millis / ISO-8601 strings andjava.timevalues toLocalDate/LocalDateTime/LocalTime/Instant/OffsetDateTime/ZonedDateTime(system-default zone, or an explicitZoneId).beans:BeanDescImpldetects record components as read-only properties and instantiates records through their canonical constructor. Non-record beans are unchanged.crypto:CachedCipher.encryptWithIv/decryptWithIvprovide AES/GCM authenticated encryption with a fresh random IV per call, as an opt-in alternative to the pooled Blowfish/ECB methods (which are unchanged). The caller supplies the AESKey.io:CloseableUtil.closeAndRethrowpropagates close failures (for output streams, where a swallowed close = data loss);FileUtil.isRealPathSaferesolves symbolic links viatoRealPath. Existingclose/closeQuietlyandisPathSafeare unchanged.exception:InvalidAlgorithmParameterRuntimeException(messageECL0117).Deferred (not in this PR — would change observable behavior or public API)
Left out to preserve backward compatibility; each needs a deliberate decision, ideally under a major version bump:
StringUtil.appendHex(int)zero-padding — an existing test andUuidUtildepend on the current output.UuidUtiluniqueness — the generated random part is effectively 32 bits; strengthening it changes the string format.LoggerSLF4J backend,ArrayMapequals/hashCodecontract,URLUtilnew URL(...)→URI.toURL(),SLinkedList.remove(int)return type,CloseableUtil.closesemantics — behavior/API changes for follow-up.Testing
Regression tests were added for the high-severity fixes and for every new API.
mvn clean testpasses with 707 tests.