From e175625d1a7458b44b32db3bde64ef34cc85a6c1 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Fri, 10 Jun 2022 09:53:59 +0200 Subject: [PATCH] use an exception with suppressed exceptions disabled in static variables. Signed-off-by: Ludovic Orban --- .../jetty/server/AsyncContentProducer.java | 7 +++-- .../eclipse/jetty/util/StaticException.java | 29 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 jetty-util/src/main/java/org/eclipse/jetty/util/StaticException.java diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContentProducer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContentProducer.java index 0f854124a100..89dcea25e83d 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContentProducer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContentProducer.java @@ -19,6 +19,7 @@ import org.eclipse.jetty.http.BadMessageException; import org.eclipse.jetty.http.HttpStatus; +import org.eclipse.jetty.util.StaticException; import org.eclipse.jetty.util.component.Destroyable; import org.eclipse.jetty.util.thread.AutoLock; import org.slf4j.Logger; @@ -31,8 +32,8 @@ class AsyncContentProducer implements ContentProducer { private static final Logger LOG = LoggerFactory.getLogger(AsyncContentProducer.class); - private static final HttpInput.ErrorContent RECYCLED_ERROR_CONTENT = new HttpInput.ErrorContent(new IllegalStateException("ContentProducer has been recycled")); - private static final Throwable UNCONSUMED_CONTENT_EXCEPTION = new IOException("Unconsumed content") + private static final HttpInput.ErrorContent RECYCLED_ERROR_CONTENT = new HttpInput.ErrorContent(new StaticException("ContentProducer has been recycled")); + private static final Throwable UNCONSUMED_CONTENT_EXCEPTION = new StaticException("Unconsumed content") { @Override public Throwable fillInStackTrace() @@ -190,7 +191,7 @@ public boolean consumeAll() Throwable x = UNCONSUMED_CONTENT_EXCEPTION; if (LOG.isDebugEnabled()) { - x = new IOException("Unconsumed content"); + x = new StaticException("Unconsumed content"); LOG.debug("consumeAll {}", this, x); } failCurrentContent(x); diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/StaticException.java b/jetty-util/src/main/java/org/eclipse/jetty/util/StaticException.java new file mode 100644 index 000000000000..9445f749a2b0 --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/StaticException.java @@ -0,0 +1,29 @@ +// +// ======================================================================== +// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others. +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License v. 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// ======================================================================== +// + +package org.eclipse.jetty.util; + +/** + * This exception can safely be stored in a static variable as suppressed exceptions are disabled, + * meaning calling {@link #addSuppressed(Throwable)} has no effect. + * This prevents potential memory leaks where a statically-stored exception would accumulate + * suppressed exceptions added to them. + */ +public class StaticException extends Exception +{ + public StaticException(String message) + { + // Make sure to call the super constructor that disables suppressed exception. + super(message, null, false, true); + } +}