From 4de0356d62f4d9614a4a44b3ca772844331768a3 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 24 Nov 2021 15:45:51 -0800
Subject: [PATCH] Fix JarManifests util

---
 ...mation-to-version-command-on-startup.patch | 107 ++++--------------
 1 file changed, 23 insertions(+), 84 deletions(-)

diff --git a/patches/api/Add-Git-information-to-version-command-on-startup.patch b/patches/api/Add-Git-information-to-version-command-on-startup.patch
index 0fd1de54ec..466e59152b 100644
--- a/patches/api/Add-Git-information-to-version-command-on-startup.patch
+++ b/patches/api/Add-Git-information-to-version-command-on-startup.patch
@@ -10,97 +10,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- /dev/null
 +++ b/src/main/java/io/papermc/paper/util/JarManifests.java
 @@ -0,0 +0,0 @@
-+/*
-+Copyright (c) 2012-2017, jcabi.com
-+All rights reserved.
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met: 1) Redistributions of source code must retain the above
-+copyright notice, this list of conditions and the following
-+disclaimer. 2) Redistributions in binary form must reproduce the above
-+copyright notice, this list of conditions and the following
-+disclaimer in the documentation and/or other materials provided
-+with the distribution. 3) Neither the name of the jcabi.com nor
-+the names of its contributors may be used to endorse or promote
-+products derived from this software without specific prior written
-+permission.
-+
-+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
-+NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-+THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+OF THE POSSIBILITY OF SUCH DAMAGE.
-+*/
 +package io.papermc.paper.util;
 +
 +import java.io.IOException;
 +import java.io.InputStream;
-+import java.net.URL;
-+import java.util.*;
++import java.util.Collections;
++import java.util.Map;
++import java.util.WeakHashMap;
 +import java.util.jar.Manifest;
-+import org.jetbrains.annotations.NotNull;
++import org.checkerframework.checker.nullness.qual.Nullable;
++import org.jetbrains.annotations.ApiStatus;
 +
-+/**
-+ * Modified version of jcabi-manifests
-+ *
-+ */
++@ApiStatus.Internal
 +public final class JarManifests {
-+
-+    public static final JarManifests JAR_MANIFESTS = new JarManifests();
-+    public static final Map<String, String> MANIFEST_MAP;
-+
-+    static {
-+        try {
-+            MANIFEST_MAP = Collections.unmodifiableMap(JAR_MANIFESTS.getManifestMap());
-+        } catch (final IOException ex) {
-+            throw new RuntimeException(ex);
-+        }
++    private JarManifests() {
 +    }
 +
-+    private JarManifests() {}
++    private static final Map<ClassLoader, Manifest> MANIFESTS = Collections.synchronizedMap(new WeakHashMap<>());
 +
-+    // Based on:
-+    // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/ClasspathMfs.java#L49-L58
-+
-+    /**
-+     * Get collection containing all META-INF/MANIFEST.MF streams
-+     *
-+     * @throws IOException if unable to get resources from classloader
-+     */
-+    public @NotNull Collection<@NotNull InputStream> getManifestStreams() throws IOException {
-+        final Enumeration<URL> resources = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF");
-+        final Collection<InputStream> streams = new ArrayList<>(1);
-+        while (resources.hasMoreElements()) {
-+            streams.add(resources.nextElement().openStream());
-+        }
-+        return streams;
-+    }
-+
-+    // Based on:
-+    // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/Manifests.java#L209-L225
-+    // https://github.com/jcabi/jcabi-manifests/blob/c4e1dd22bb6099769b8d279ebe3737e5b638b278/src/main/java/com/jcabi/manifests/Manifests.java#L381-L388
-+
-+    /**
-+     * Get map containing entries from all manifests
-+     *
-+     * @throws IOException if unable to get manifest streams
-+     */
-+    public @NotNull Map<@NotNull String, @NotNull String> getManifestMap() throws IOException {
-+        final HashMap<String, String> attribs = new HashMap<>();
-+        for (final InputStream stream : getManifestStreams()) {
-+            for (final Map.Entry<Object, Object> attr: new Manifest(stream).getMainAttributes().entrySet()) {
-+                attribs.put(attr.getKey().toString(), attr.getValue().toString());
++    public static Manifest manifest(final ClassLoader loader) {
++        return MANIFESTS.computeIfAbsent(loader, classLoader -> {
++            final @Nullable InputStream stream = classLoader.getResourceAsStream("META-INF/MANIFEST.MF");
++            if (stream == null) {
++                throw new IllegalArgumentException("Provided ClassLoader does not have a manifest file in the correct location!");
 +            }
-+        }
-+        return attribs;
++            try (stream) {
++                return new Manifest(stream);
++            } catch (final IOException ex) {
++                throw new RuntimeException("Failed to read manifest.");
++            }
++        });
 +    }
 +}
 diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
@@ -130,10 +69,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +      */
 +    @NotNull
 +    public static String getVersionMessage() {
-+        Map<String, String> attributes = JarManifests.MANIFEST_MAP;
-+        @NotNull String gitBranch = attributes.get("Git-Branch");
-+        @NotNull String gitCommit = attributes.get("Git-Commit");
-+        @NotNull String branchMsg = " on " + gitBranch;
++        final var manifest = JarManifests.manifest(Bukkit.getServer().getClass().getClassLoader());
++        final String gitBranch = manifest.getMainAttributes().getValue("Git-Branch");
++        final String gitCommit = manifest.getMainAttributes().getValue("Git-Commit");
++        String branchMsg = " on " + gitBranch;
 +        if ("master".equals(gitBranch) || "main".equals(gitBranch)) {
 +            branchMsg = "";  // Don't show branch on main/master
 +        }