Repository navigation
feat: adopt Java 21–25 language features (closes #160) - #161
Conversation
- Replace unused catch variables with unnamed _ (Java 22) across 13 sites - Remove ThreadLocal<MessageDigest> from ETagUtils; create per-call instance to avoid ThreadLocal pitfalls under virtual threads (Java 21) - Declare middlewareStack as List and funcQueue as SequencedCollection to use SequencedCollection abstraction (Java 21) - Apply text block to UndertowComponent.toString() (Java 15) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR modernizes Enkan’s Java codebase to better align with Java 21–25 language/library features, with a focus on clearer intent (unnamed catch variables), safer behavior under virtual threads, and use of newer collection abstractions.
Changes:
- Replaced unused catch-block exception variables with Java 22’s unnamed variable (
_) across multiple modules. - Updated
ETagUtilsto avoidThreadLocal<MessageDigest>by creating a newMessageDigestper call (virtual-thread-friendly). - Adopted Java 21 collection abstractions (
List/SequencedCollection) and convertedUndertowComponent.toString()to a text block.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| enkan-web/src/main/java/enkan/web/util/HttpRequestUtils.java | Uses unnamed catch variable for ignored NumberFormatException. |
| enkan-web/src/main/java/enkan/web/util/ETagUtils.java | Removes ThreadLocal<MessageDigest>; creates SHA-256 digest per call and updates Javadoc. |
| enkan-web/src/main/java/enkan/web/util/CodecUtils.java | Uses unnamed catch variables where exceptions are intentionally ignored. |
| enkan-web/src/main/java/enkan/web/middleware/negotiation/AcceptHeaderNegotiator.java | Uses unnamed catch variables for ignored UnsupportedCharsetException. |
| enkan-web/src/main/java/enkan/web/middleware/multipart/TempfilePart.java | Uses unnamed catch variable for ignored IOException on close. |
| enkan-web/src/main/java/enkan/web/middleware/IdleSessionTimeoutMiddleware.java | Uses unnamed catch variable for ignored NumberFormatException. |
| enkan-web/src/main/java/enkan/web/application/WebApplication.java | Declares middlewareStack using List (Java 21+ sequenced APIs). |
| enkan-system/src/main/java/enkan/system/command/StartCommand.java | Uses unnamed catch variable for ignored IOException. |
| enkan-devel/src/main/java/enkan/system/devel/ClassWatcher.java | Uses unnamed catch variable for InterruptedException in watcher loop. |
| enkan-core/src/main/java/enkan/util/ThreadingUtils.java | Uses SequencedCollection for ordered queue behavior. |
| enkan-core/src/main/java/enkan/exception/MisconfigurationException.java | Uses unnamed catch variables for ignored IOException during resource loading. |
| enkan-core/src/main/java/enkan/collection/Parameters.java | Uses unnamed catch variables for ignored NumberFormatException. |
| enkan-component-undertow/src/main/java/enkan/component/undertow/UndertowComponent.java | Converts toString() to a text block with formatted(...). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| key = watchService.poll(10, TimeUnit.SECONDS); | ||
| if (key == null) continue; | ||
| } catch (InterruptedException ex) { | ||
| } catch (InterruptedException _) { |
There was a problem hiding this comment.
The InterruptedException catch exits without restoring the thread's interrupted status. Since poll(...) clears the interrupt flag when throwing, returning here can cause callers/shutdown logic to miss the interruption signal. Set the interrupt status again (Thread.currentThread().interrupt()) before returning (or break and let the outer loop observe it).
| } catch (InterruptedException _) { | |
| } catch (InterruptedException _) { | |
| Thread.currentThread().interrupt(); |
| return """ | ||
| #UndertowComponent { | ||
| "host": "%s", | ||
| "port": "%s", | ||
| "dependencies": "%s" | ||
| }""".formatted(getHost(), getPort(), dependenciesToString()); |
There was a problem hiding this comment.
This text block will include a leading newline (because the opening """ is followed by a line break). That changes UndertowComponent.toString() to start with whitespace/newline, which can be surprising in logs/debug output. Consider placing the first character immediately after the opening delimiter (or otherwise trimming/stripIndent-ing) to preserve the previous single-line start.
- ClassWatcher: restore interrupted flag after catching InterruptedException - UndertowComponent: strip leading newline from text block via stripLeading() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
_(Java 22 unnamed variables) acrossenkan-core,enkan-web,enkan-system, andenkan-develThreadLocal<MessageDigest>fromETagUtils; create a newMessageDigestper call — avoids ThreadLocal pitfalls under virtual threads (Java 21)middlewareStackinWebApplicationasListandfuncQueueinThreadingUtilsasSequencedCollectionto use the Java 21 abstractionUndertowComponent.toString()(Java 15)Test plan
mvn test -B -DexcludedGroups=integration— BUILD SUCCESS, 0 failuresCloses #160
🤖 Generated with Claude Code