Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onCompleteFailure called multiple times #9476

Closed
forfreeday opened this issue Mar 8, 2023 · 19 comments · Fixed by #9935
Closed

onCompleteFailure called multiple times #9476

forfreeday opened this issue Mar 8, 2023 · 19 comments · Fixed by #9935
Assignees
Labels
Bug For general bugs on Jetty side End-of-Life release

Comments

@forfreeday
Copy link

Jetty version(s)
Jetty 9.4.51

Java version/vendor (use: java -version)
java version 1.8.0_161

OS type/version
CentOS

Description

When I upgrade to Jetty 9.4.51, this exception will appear in the log every day.
What caused this anomaly?

04:04:21.744 WARN  [qtp903644315-163107] [o.e.j.i.AbstractConnection](AbstractConnection.java:96)
java.lang.NullPointerException: null
        at org.eclipse.jetty.io.AbstractConnection.lambda$failedCallback$0(AbstractConnection.java:92)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
        at java.lang.Thread.run(Thread.java:748)
@forfreeday forfreeday added the Bug For general bugs on Jetty side label Mar 8, 2023
@joakime
Copy link
Contributor

joakime commented Mar 8, 2023

Jetty 9.x is now at End of Community Support.

See

You should be upgrading to Jetty 10 or Jetty 11 at this point.

@forfreeday
Copy link
Author

Our system is JDK8, can not upgrade to a higher version, can only use jetty9

@olamy
Copy link
Member

olamy commented Mar 15, 2023

Our system is JDK8, can not upgrade to a higher version, can only use jetty9

You should definitely read #7958 and how to get Jetty 9.x support.

@JoergHeinicke5005
Copy link

I do understand that you can't support multiple major versions in parallel, but you have to end support at some point. Where I'm not following, is, that a NullPointerException had recently been introduced (with v9.4.51, which means it got broken by an actively performed change, i.e. while in EOL) and nonetheless you don't want to take care of it.
If I understand correctly, this new patch version v9.4.51 is for professional support of Jetty. So, there is the slight chance that the NPE gets silently fixed the same way it got introduced. Then again, it would be easy to provide tracking of such an issue in a public ticket like this one.
Btw., if running Spring Boot 2 with Jetty, v9 is still the default version (even though it can be switched to v10). I doubt these will be the last occurrences you'll see this issue being reported.

@schrotti74
Copy link

I agree. Also recently upgraded to 9.4.51 in pre-prod (e.g. loadtest) where we have seen the NPE. If this is some sort of regression recently introduced, it should be fixed in another 9.4.x based release.

@gregw gregw reopened this May 25, 2023
@gregw
Copy link
Contributor

gregw commented May 25, 2023

Since we must have introduced in recent release, we will look at fixing it as well.

@gregw gregw self-assigned this May 25, 2023
@AN3Orik
Copy link

AN3Orik commented Jun 5, 2023

Any news?

@joakime
Copy link
Contributor

joakime commented Jun 5, 2023

@AN3Orik since Jetty 9.x is End of Community Support, this is extremely low priority.

Our overwhelming focus is on Jetty 12, with support for Jetty 10 and Jetty 11 right now.

@joakime
Copy link
Contributor

joakime commented Jun 5, 2023

This is reported against AbstractConnection which has had no code changes since Aug 22, 2018

https://github.com/eclipse/jetty.project/commits/jetty-9.4.x/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractConnection.java

Which was around the release of Jetty 9.4.12.

@AN3Orik
Copy link

AN3Orik commented Jun 5, 2023

It's start happening after changes in this commit i think
add some fixes to SizeLimitHandler

Failed callback added and this callback is null when AbstractConnection.failedCallback() method reached

AN3Orik referenced this issue Jun 9, 2023
@lachlan-roberts
Copy link
Contributor

@AN3Orik SizeLimitHandler was only added in 9.4.50 and is not added to the server by default.

You must manually add it for it to ever be used, so unless you have started using this handler in 9.4.50 it is not related.

@lachlan-roberts
Copy link
Contributor

I reviewed the 9.4.50 -> 9.4.51 diff and this almost certainly comes from this change #9062.

The failedCallback() method is only called from onCompleteFailure, and #9062 changes how this can be called.
@gregw @sbordet

sid-evolphin added a commit to sid-evolphin/jetty.project that referenced this issue Jun 20, 2023
Added a null check for the Callback parameter in o.e.j.iAbstractConnection.failedCallback(Callback, Throwable) so that the subsequent code-flow is not aborted; while the root cause may be ascertained in case debug logging is enabled.

Further, in the case of a RejectedExecutionException when submitting the failCallback, the Runnable is run instead of directly invoking the Callback, so that exceptions in the Callback do not abort the synchronous code-flow.
@sid-evolphin
Copy link

Since we must have introduced in recent release, we will look at fixing it as well.

@gregw Please review the PR #9932 I have submitted to avoid a null Callback from derailing the synchronous flow subsequent to the invocation of o.e.j.i.AbstractConnection.failedCallback(Callback, Throwable). Also if debug logging is enabled, then the root cause may be ascertained for the NPE.

Thank you very much.

@gregw gregw linked a pull request Jun 20, 2023 that will close this issue
sid-evolphin added a commit to sid-evolphin/jetty.project that referenced this issue Jun 20, 2023
…lback

1. Fixed the usages of `Callback` returned by `o.e.j.s.HttpConnection.SendCallback.release()` to check for `null` before invoking the `failedCallback(Callback, Throwable)` or `succeeded()` methods.

2. Also, added a try-finally block around the Callback invocations in order to ensure that shutdownOutput will get performed irrespective of whether they end up throwing any exception.
sid-evolphin added a commit to sid-evolphin/jetty.project that referenced this issue Jun 20, 2023
…w feedback

Partially reverted `o.e.j.i.AbstractConnection.failedCallback(Callback, Throwable)` to not have a null check for the `Callback` parameter, based on review feedback from @gregw.

This avoids changing the contract of the method parameter (from `@NonNull` to `@Nullable`).
@gregw
Copy link
Contributor

gregw commented Jun 20, 2023

@sbordet @lachlan-roberts I think this is actually a real bug in IteratingCallback in all our releases. I think we are able to call onCompleteFailure multiple times for the same failure.

@gregw
Copy link
Contributor

gregw commented Jun 20, 2023

@sbordet @lachlan-roberts @lorban The following "test" is passing when it should not. It shows that we can call onCompleteFailure multiple times. We can also call process after a failure!

    @Test
    public void testMultipleFailures() throws Exception
    {
        AtomicInteger process = new AtomicInteger();
        AtomicInteger failure = new AtomicInteger();
        IteratingCallback icb = new IteratingCallback()
        {
            @Override
            protected Action process() throws Throwable
            {
                process.incrementAndGet();
                return Action.SCHEDULED;
            }

            @Override
            protected void onCompleteFailure(Throwable cause)
            {
                super.onCompleteFailure(cause);
                failure.incrementAndGet();
            }
        };

        icb.iterate();
        assertEquals(1, process.get());
        assertEquals(0, failure.get());

        icb.failed(new Throwable("test1"));

        assertEquals(1, process.get());
        assertEquals(1, failure.get());

        icb.succeeded();
        assertEquals(2, process.get());
        assertEquals(1, failure.get());

        icb.failed(new Throwable("test1"));
        assertEquals(2, process.get());
        assertEquals(2, failure.get());

gregw added a commit that referenced this issue Jun 20, 2023
Change state to FAILED from PENDING state
@gregw gregw linked a pull request Jun 20, 2023 that will close this issue
@gregw gregw changed the title Jetty 9.4.51 NullPointerException Jetty 9.4.51 onCompleteFailure called multiple times Jun 20, 2023
@sid-evolphin
Copy link

Thanks a lot @gregw!

gregw added a commit that referenced this issue Jun 21, 2023
Change state to FAILED from PENDING state
gregw added a commit that referenced this issue Jun 21, 2023
Change state to FAILED from PENDING state
@gregw gregw closed this as completed in 9041527 Jun 21, 2023
@gregw
Copy link
Contributor

gregw commented Jun 21, 2023

merged through to 12.0.x

@forfreeday We are 99% sure this will fix your problem, but we did not have an exact reproducer of your exact case. Any chance you can test this out before we do a release?

@markkolich
Copy link

@gregw are you still looking for someone to try this out pre-release?

I can reproduce this NPE on 9.4.51.v20230217 pretty much at will, so I'm happy to try a snapshot with a fix and see if that resolves the bug.

If you need a guinea pig let me know what 9.x snapshot I should try.

@gregw
Copy link
Contributor

gregw commented Aug 8, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For general bugs on Jetty side End-of-Life release
Projects
None yet
10 participants