From b586c543cdf9338e112ab8a6668262ab350742e4 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 4 Dec 2020 04:17:05 +0100 Subject: [PATCH] [pr #2637] recent versions of ecj double-close the classfile stream, causing corrupt classfiles Would crash with java.lang.ClassFormatError: Extra bytes at the end of class file de/lomboktest/Application Fixes https://github.com/mplushnikov/lombok-intellij-plugin/issues/969 figuring out the problem was the hard work - credits to @Rawi01 for discovering this --- src/core/lombok/core/PostCompiler.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/lombok/core/PostCompiler.java b/src/core/lombok/core/PostCompiler.java index 72f4b3a239..122bb26894 100644 --- a/src/core/lombok/core/PostCompiler.java +++ b/src/core/lombok/core/PostCompiler.java @@ -28,6 +28,7 @@ import java.io.StringWriter; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; public final class PostCompiler { private PostCompiler() {/* prevent instantiation*/}; @@ -67,8 +68,17 @@ private static synchronized void init(DiagnosticsReceiver diagnostics) { public static OutputStream wrapOutputStream(final OutputStream originalStream, final String fileName, final DiagnosticsReceiver diagnostics) throws IOException { if (System.getProperty("lombok.disablePostCompiler", null) != null) return originalStream; + + // close() can be called more than once and should be idempotent, therefore, ensure we never transform more than once. + final AtomicBoolean closed = new AtomicBoolean(); + return new ByteArrayOutputStream() { @Override public void close() throws IOException { + if (closed.getAndSet(true)) { + originalStream.close(); + return; + } + // no need to call super byte[] original = toByteArray(); byte[] copy = null;