Skip to content

fix: Ensure async clients use a thread factory that SLF4J-logs on uncaught Errors#82

Merged
jeremylong merged 5 commits intojeremylong:mainfrom
chadlwilson:fix-io-thread-death-logging
Jan 12, 2026
Merged

fix: Ensure async clients use a thread factory that SLF4J-logs on uncaught Errors#82
jeremylong merged 5 commits intojeremylong:mainfrom
chadlwilson:fix-io-thread-death-logging

Conversation

@chadlwilson
Copy link
Copy Markdown
Contributor

@chadlwilson chadlwilson commented Jan 2, 2026

Per dependency-check/DependencyCheck#8178 currently if the async http client threads die due to a JVM Error[1], the errors can be swallowed, depending on what your application does with System.err.

That can make the root cause of the later failures difficult to determine without enabling debug logging (or impossible if an application complete swallows System.err rather than redirecting it somewhere you can see).

This change alters the default Apache HTTPClient thread factory to define an uncaught exception handler which uses SLF4J like the rest of the library.

I've left the logs at ERROR level, but arguably they are fatal, as they potentially leave the cached http clients in a broken state.

[1] The HTTP Client Async IO workers catch and report Exceptions, but not Errors:

    public void execute() {
        if (this.status.compareAndSet(IOReactorStatus.INACTIVE, IOReactorStatus.ACTIVE)) {
            try {
                doExecute();
            } catch (final ClosedSelectorException ignore) {
                // ignore
            } catch (final Exception ex) {
                logException(ex);
            } finally {
                try {
                    doTerminate();
                } catch (final Exception ex) {
                    logException(ex);
                } finally {
                    close(CloseMode.IMMEDIATE);
                }
            }
        }
    }

Copilot AI review requested due to automatic review settings January 2, 2026 17:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #8178 by ensuring that uncaught exceptions in Apache HTTP async client threads are logged via SLF4J instead of being potentially swallowed when written to System.err. This improves debuggability when HTTP client threads fail due to JVM errors.

Key Changes:

  • Introduced a new LoggingThreadFactory that wraps Apache's DefaultThreadFactory and sets an uncaught exception handler on all created threads
  • Updated both cached and non-cached HTTP client configurations in RateLimitedClient to use the new thread factory
  • Added a public getDefaultThreadFactory() method to HttpAsyncClientSupplier for reusability

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
src/main/java/io/github/jeremylong/openvulnerability/client/HttpAsyncClientSupplier.java Adds LoggingThreadFactory class with SLF4J-based uncaught exception handler and exposes it via getDefaultThreadFactory() method
src/main/java/io/github/jeremylong/openvulnerability/client/nvd/RateLimitedClient.java Integrates the new thread factory into HTTP client builders for both cached and non-cached configurations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chadlwilson chadlwilson changed the title fix: Ensure async clients use a thread factory/threadgroup that SLF4J-logs on uncaught exceptions fix: Ensure async clients use a thread factory that SLF4J-logs on uncaught Errors Jan 2, 2026
jeremylong
jeremylong previously approved these changes Jan 12, 2026
Copy link
Copy Markdown
Owner

@jeremylong jeremylong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jeremylong jeremylong merged commit 65e1aa2 into jeremylong:main Jan 12, 2026
1 check passed
@chadlwilson
Copy link
Copy Markdown
Contributor Author

I ran CoPilot several times already (as you can see above) and it keeps on generating new low value suggestions on every iteration that it didn't mention earlier.

IMHO a bit of a waste of time after a while.

@chadlwilson chadlwilson deleted the fix-io-thread-death-logging branch January 12, 2026 12:23
@chadlwilson
Copy link
Copy Markdown
Contributor Author

Any chance of cutting a patch release with this in it, so can update within ODC?

@jeremylong
Copy link
Copy Markdown
Owner

absolutely.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants