diff --git a/patches/server/Add-support-for-Proxy-Protocol.patch b/patches/server/Add-support-for-Proxy-Protocol.patch
index 97d1393f3f..b9e55ef5ab 100644
--- a/patches/server/Add-support-for-Proxy-Protocol.patch
+++ b/patches/server/Add-support-for-Proxy-Protocol.patch
@@ -9,9 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/build.gradle.kts
 +++ b/build.gradle.kts
 @@ -0,0 +0,0 @@ dependencies {
-      */
-     implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
-     annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for our Log4j plugins
+     log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
+     runtimeOnly(log4jPlugins.output)
+     alsoShade(log4jPlugins.output)
 +    implementation("io.netty:netty-codec-haproxy:4.1.87.Final") // Paper - Add support for proxy protocol
      // Paper end
      implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
diff --git a/patches/server/Build-system-changes.patch b/patches/server/Build-system-changes.patch
index 5d8ee56be2..050771abfd 100644
--- a/patches/server/Build-system-changes.patch
+++ b/patches/server/Build-system-changes.patch
@@ -48,6 +48,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          )
          for (tld in setOf("net", "com", "org")) {
              attributes("$tld/bukkit", "Sealed" to true)
+@@ -0,0 +0,0 @@ tasks.jar {
+     }
+ }
+ 
++tasks.compileJava {
++    // incremental compilation is currently broken due to patched files having compiled counterparts already on the compile classpath
++    options.setIncremental(false)
++}
++
+ publishing {
+     publications.create<MavenPublication>("maven") {
+         artifact(tasks.shadowJar)
 @@ -0,0 +0,0 @@ tasks.shadowJar {
      }
  }
diff --git a/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch
index 6d4ff62aea..e0ca054f6a 100644
--- a/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch
+++ b/patches/server/Deobfuscate-stacktraces-in-log-messages-crash-report.patch
@@ -36,28 +36,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  tasks.test {
      exclude("org/bukkit/craftbukkit/inventory/ItemStack*Test.class")
  }
-diff --git a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
-+++ b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
-@@ -0,0 +0,0 @@ public class SyncLoadFinder {
- 
-                 final JsonArray traces = new JsonArray();
- 
--                for (StackTraceElement element : pair.getFirst().stacktrace) {
-+                for (StackTraceElement element : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(pair.getFirst().stacktrace)) {
-                     traces.add(String.valueOf(element));
-                 }
- 
-diff --git a/src/main/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java b/src/main/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java
+diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java b/src/log4jPlugins/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
 --- /dev/null
-+++ b/src/main/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java
++++ b/src/log4jPlugins/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.logging;
 +
-+import io.papermc.paper.util.StacktraceDeobfuscator;
++import java.lang.invoke.MethodHandle;
++import java.lang.invoke.MethodHandles;
++import java.lang.invoke.VarHandle;
 +import org.apache.logging.log4j.core.Core;
 +import org.apache.logging.log4j.core.LogEvent;
 +import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy;
@@ -73,6 +62,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    printObject = true
 +)
 +public final class StacktraceDeobfuscatingRewritePolicy implements RewritePolicy {
++    private static final MethodHandle DEOBFUSCATE_THROWABLE;
++
++    static {
++        try {
++            final Class<?> cls = Class.forName("io.papermc.paper.util.StacktraceDeobfuscator");
++            final MethodHandles.Lookup lookup = MethodHandles.lookup();
++            final VarHandle instanceHandle = lookup.findStaticVarHandle(cls, "INSTANCE", cls);
++            final Object deobfuscator = instanceHandle.get();
++            DEOBFUSCATE_THROWABLE = lookup
++                .unreflect(cls.getDeclaredMethod("deobfuscateThrowable", Throwable.class))
++                .bindTo(deobfuscator);
++        } catch (final ReflectiveOperationException ex) {
++            throw new IllegalStateException(ex);
++        }
++    }
++
 +    private StacktraceDeobfuscatingRewritePolicy() {
 +    }
 +
@@ -80,7 +85,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    public @NonNull LogEvent rewrite(final @NonNull LogEvent rewrite) {
 +        final Throwable thrown = rewrite.getThrown();
 +        if (thrown != null) {
-+            StacktraceDeobfuscator.INSTANCE.deobfuscateThrowable(thrown);
++            deobfuscateThrowable(thrown);
 +            return new Log4jLogEvent.Builder(rewrite)
 +                .setThrownProxy(null)
 +                .build();
@@ -88,11 +93,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return rewrite;
 +    }
 +
++    private static void deobfuscateThrowable(final Throwable thrown) {
++        try {
++            DEOBFUSCATE_THROWABLE.invoke(thrown);
++        } catch (final Error e) {
++            throw e;
++        } catch (final Throwable e) {
++            throw new RuntimeException(e);
++        }
++    }
++
 +    @PluginFactory
 +    public static @NonNull StacktraceDeobfuscatingRewritePolicy createPolicy() {
 +        return new StacktraceDeobfuscatingRewritePolicy();
 +    }
 +}
+diff --git a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
++++ b/src/main/java/com/destroystokyo/paper/io/SyncLoadFinder.java
+@@ -0,0 +0,0 @@ public class SyncLoadFinder {
+ 
+                 final JsonArray traces = new JsonArray();
+ 
+-                for (StackTraceElement element : pair.getFirst().stacktrace) {
++                for (StackTraceElement element : io.papermc.paper.util.StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(pair.getFirst().stacktrace)) {
+                     traces.add(String.valueOf(element));
+                 }
+ 
 diff --git a/src/main/java/io/papermc/paper/util/ObfHelper.java b/src/main/java/io/papermc/paper/util/ObfHelper.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
diff --git a/patches/server/Handle-plugin-prefixes-using-Log4J-configuration.patch b/patches/server/Handle-plugin-prefixes-using-Log4J-configuration.patch
index cf13c857ce..c8f5bc619c 100644
--- a/patches/server/Handle-plugin-prefixes-using-Log4J-configuration.patch
+++ b/patches/server/Handle-plugin-prefixes-using-Log4J-configuration.patch
@@ -22,11 +22,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
            all its classes to check if they are plugins.
            Scanning takes about 1-2 seconds so adding this speeds up the server start.
       */
--    runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
-+    implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
-     annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for our Log4j plugins
-     // Paper end
-     implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
+-    runtimeOnly("org.apache.logging.log4j:log4j-core:2.19.0")
++    implementation("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - implementation
+     log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
+     runtimeOnly(log4jPlugins.output)
+     alsoShade(log4jPlugins.output)
 diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/spigotmc/SpigotConfig.java
diff --git a/patches/server/Implement-Brigadier-Mojang-API.patch b/patches/server/Implement-Brigadier-Mojang-API.patch
index c5a0f48711..a28c905285 100644
--- a/patches/server/Implement-Brigadier-Mojang-API.patch
+++ b/patches/server/Implement-Brigadier-Mojang-API.patch
@@ -13,7 +13,7 @@ diff --git a/build.gradle.kts b/build.gradle.kts
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/build.gradle.kts
 +++ b/build.gradle.kts
-@@ -0,0 +0,0 @@ plugins {
+@@ -0,0 +0,0 @@ val alsoShade: Configuration by configurations.creating
  
  dependencies {
      implementation(project(":paper-api"))
diff --git a/patches/server/Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch b/patches/server/Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch
index a6c29fb1fd..584d5d2186 100644
--- a/patches/server/Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch
+++ b/patches/server/Rewrite-LogEvents-to-contain-the-source-jars-in-stac.patch
@@ -4,11 +4,11 @@ Date: Sat, 10 Jul 2021 11:12:30 +0200
 Subject: [PATCH] Rewrite LogEvents to contain the source jars in stack traces
 
 
-diff --git a/src/main/java/io/papermc/paper/logging/DelegateLogEvent.java b/src/main/java/io/papermc/paper/logging/DelegateLogEvent.java
+diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/DelegateLogEvent.java b/src/log4jPlugins/java/io/papermc/paper/logging/DelegateLogEvent.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
 --- /dev/null
-+++ b/src/main/java/io/papermc/paper/logging/DelegateLogEvent.java
++++ b/src/log4jPlugins/java/io/papermc/paper/logging/DelegateLogEvent.java
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.logging;
 +
@@ -140,11 +140,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.original.getNanoTime();
 +    }
 +}
-diff --git a/src/main/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java b/src/main/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
+diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
 --- /dev/null
-+++ b/src/main/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
++++ b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.logging;
 +
@@ -194,11 +194,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        }
 +    }
 +}
-diff --git a/src/main/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java b/src/main/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
+diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
 --- /dev/null
-+++ b/src/main/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
++++ b/src/log4jPlugins/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.logging;
 +
diff --git a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
index d2d241ed57..b052bde64b 100644
--- a/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
+++ b/patches/server/Use-TerminalConsoleAppender-for-console-improvements.patch
@@ -29,7 +29,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 --- a/build.gradle.kts
 +++ b/build.gradle.kts
 @@ -0,0 +0,0 @@ plugins {
+     id("com.github.johnrengelman.shadow")
+ }
  
++val log4jPlugins = sourceSets.create("log4jPlugins")
++configurations.named(log4jPlugins.compileClasspathConfigurationName) {
++    extendsFrom(configurations.compileClasspath.get())
++}
++val alsoShade: Configuration by configurations.creating
++
  dependencies {
      implementation(project(":paper-api"))
 -    implementation("jline:jline:2.12.1")
@@ -44,12 +52,80 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +          all its classes to check if they are plugins.
 +          Scanning takes about 1-2 seconds so adding this speeds up the server start.
 +     */
-+    runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
-+    annotationProcessor("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - Needed to generate meta for our Log4j plugins
++    runtimeOnly("org.apache.logging.log4j:log4j-core:2.19.0")
++    log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
++    runtimeOnly(log4jPlugins.output)
++    alsoShade(log4jPlugins.output)
 +    // Paper end
      implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
      implementation("org.ow2.asm:asm:9.4")
      implementation("org.ow2.asm:asm-commons:9.4") // Paper - ASM event executor generation
+@@ -0,0 +0,0 @@ relocation {
+ }
+ 
+ tasks.shadowJar {
+-    configurations = listOf(project.configurations.vanillaServer.get())
++    configurations = listOf(project.configurations.vanillaServer.get(), alsoShade)
+     archiveClassifier.set("mojang-mapped")
+ 
+     for (relocation in relocation.relocations.get()) {
+diff --git a/src/log4jPlugins/java/io/papermc/paper/console/StripANSIConverter.java b/src/log4jPlugins/java/io/papermc/paper/console/StripANSIConverter.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
+--- /dev/null
++++ b/src/log4jPlugins/java/io/papermc/paper/console/StripANSIConverter.java
+@@ -0,0 +0,0 @@
++package io.papermc.paper.console;
++
++import org.apache.logging.log4j.core.LogEvent;
++import org.apache.logging.log4j.core.config.Configuration;
++import org.apache.logging.log4j.core.config.plugins.Plugin;
++import org.apache.logging.log4j.core.layout.PatternLayout;
++import org.apache.logging.log4j.core.pattern.ConverterKeys;
++import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
++import org.apache.logging.log4j.core.pattern.PatternConverter;
++import org.apache.logging.log4j.core.pattern.PatternFormatter;
++import org.apache.logging.log4j.core.pattern.PatternParser;
++
++import java.util.List;
++import java.util.regex.Pattern;
++
++@Plugin(name = "stripAnsi", category = PatternConverter.CATEGORY)
++@ConverterKeys({"stripAnsi"})
++public final class StripANSIConverter extends LogEventPatternConverter {
++    final private Pattern ANSI_PATTERN = Pattern.compile("\\e\\[[\\d;]*[^\\d;]");
++
++    private final List<PatternFormatter> formatters;
++
++    private StripANSIConverter(List<PatternFormatter> formatters) {
++        super("stripAnsi", null);
++        this.formatters = formatters;
++    }
++
++    @Override
++    public void format(LogEvent event, StringBuilder toAppendTo) {
++        int start = toAppendTo.length();
++        for (PatternFormatter formatter : formatters) {
++            formatter.format(event, toAppendTo);
++        }
++        String content = toAppendTo.substring(start);
++        content = ANSI_PATTERN.matcher(content).replaceAll("");
++
++        toAppendTo.setLength(start);
++        toAppendTo.append(content);
++    }
++
++    public static StripANSIConverter newInstance(Configuration config, String[] options) {
++        if (options.length != 1) {
++            LOGGER.error("Incorrect number of options on stripAnsi. Expected exactly 1, received " + options.length);
++            return null;
++        }
++
++        PatternParser parser = PatternLayout.createPatternParser(config);
++        List<PatternFormatter> formatters = parser.parse(options[0]);
++        return new StripANSIConverter(formatters);
++    }
++}
 diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
 new file mode 100644
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
@@ -175,63 +251,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return PaperAdventure.ANSI_SERIALIZER.serialize(GlobalTranslator.render(message, Locale.getDefault()));
      }
  }
-diff --git a/src/main/java/io/papermc/paper/console/StripANSIConverter.java b/src/main/java/io/papermc/paper/console/StripANSIConverter.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
---- /dev/null
-+++ b/src/main/java/io/papermc/paper/console/StripANSIConverter.java
-@@ -0,0 +0,0 @@
-+package io.papermc.paper.console;
-+
-+import org.apache.logging.log4j.core.LogEvent;
-+import org.apache.logging.log4j.core.config.Configuration;
-+import org.apache.logging.log4j.core.config.plugins.Plugin;
-+import org.apache.logging.log4j.core.layout.PatternLayout;
-+import org.apache.logging.log4j.core.pattern.ConverterKeys;
-+import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
-+import org.apache.logging.log4j.core.pattern.PatternConverter;
-+import org.apache.logging.log4j.core.pattern.PatternFormatter;
-+import org.apache.logging.log4j.core.pattern.PatternParser;
-+
-+import java.util.List;
-+import java.util.regex.Pattern;
-+
-+@Plugin(name = "stripAnsi", category = PatternConverter.CATEGORY)
-+@ConverterKeys({"stripAnsi"})
-+public final class StripANSIConverter extends LogEventPatternConverter {
-+    final private Pattern ANSI_PATTERN = Pattern.compile("\\e\\[[\\d;]*[^\\d;]");
-+
-+    private final List<PatternFormatter> formatters;
-+
-+    private StripANSIConverter(List<PatternFormatter> formatters) {
-+        super("stripAnsi", null);
-+        this.formatters = formatters;
-+    }
-+
-+    @Override
-+    public void format(LogEvent event, StringBuilder toAppendTo) {
-+        int start = toAppendTo.length();
-+        for (PatternFormatter formatter : formatters) {
-+            formatter.format(event, toAppendTo);
-+        }
-+        String content = toAppendTo.substring(start);
-+        content = ANSI_PATTERN.matcher(content).replaceAll("");
-+
-+        toAppendTo.setLength(start);
-+        toAppendTo.append(content);
-+    }
-+
-+    public static StripANSIConverter newInstance(Configuration config, String[] options) {
-+        if (options.length != 1) {
-+            LOGGER.error("Incorrect number of options on stripAnsi. Expected exactly 1, received " + options.length);
-+            return null;
-+        }
-+
-+        PatternParser parser = PatternLayout.createPatternParser(config);
-+        List<PatternFormatter> formatters = parser.parse(options[0]);
-+        return new StripANSIConverter(formatters);
-+    }
-+}
 diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/net/minecraft/server/MinecraftServer.java