From a10874ecfccc3b8373482cd7f0a024b1eeb8c20a Mon Sep 17 00:00:00 2001 From: Jason Ho Date: Sat, 24 Aug 2024 23:04:07 -0700 Subject: [PATCH] Fix JDK12+ final field modification startup issues with java version detection and a method from https://stackoverflow.com/questions/61141836/change-static-final-field-in-java-12 --- ...DK12-final-field-modification-issues.patch | 65 +++++++++++++++++++ ...DK12-final-field-modification-issues.patch | 60 +++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 patches/api/0105-Fix-JDK12-final-field-modification-issues.patch create mode 100644 patches/server/0223-Fix-JDK12-final-field-modification-issues.patch diff --git a/patches/api/0105-Fix-JDK12-final-field-modification-issues.patch b/patches/api/0105-Fix-JDK12-final-field-modification-issues.patch new file mode 100644 index 00000000..668eacc1 --- /dev/null +++ b/patches/api/0105-Fix-JDK12-final-field-modification-issues.patch @@ -0,0 +1,65 @@ +From fa5d9f5884279a1dbbe301a165e5e769d64d82ff Mon Sep 17 00:00:00 2001 +From: Jason Ho +Date: Sat, 24 Aug 2024 23:00:45 -0700 +Subject: [PATCH] Fix JDK12+ final field modification issues + + +diff --git a/src/main/java/app/ashcon/sportpaper/api/reflection/ReflectionUtils.java b/src/main/java/app/ashcon/sportpaper/api/reflection/ReflectionUtils.java +new file mode 100644 +index 00000000..88b50515 +--- /dev/null ++++ b/src/main/java/app/ashcon/sportpaper/api/reflection/ReflectionUtils.java +@@ -0,0 +1,50 @@ ++package app.ashcon.sportpaper.api.reflection; ++ ++import jdk.internal.misc.Unsafe; ++ ++import java.lang.reflect.Field; ++import java.lang.reflect.Modifier; ++ ++public class ReflectionUtils { ++ ++ static final double JDK12 = 56.0; ++ ++ public static Double getJavaVersion() { ++ String version = System.getProperty("java.class.version"); ++ return Double.parseDouble(version); ++ } ++ ++ public static void modifyFinal(Class clazz, String fieldName, Object instance, Object value) throws Exception { ++ Double javaVersion = getJavaVersion(); ++ if (javaVersion < JDK12) { ++ jdk8_modifyFinal(clazz, fieldName, instance, value); ++ } else { ++ try { ++ jdklatest_modifyFinal(clazz, fieldName, instance, value); ++ } catch(Exception e) { ++ throw new RuntimeException("ReflectionUtils: " + ++ "Unsupported Java version, cannot perform reflections on version " + javaVersion, e); ++ } ++ } ++ } ++ ++ public static void jdklatest_modifyFinal(Class clazz, String fieldName, Object instance, Object value) throws NoSuchFieldException, IllegalAccessException { ++ final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); ++ unsafeField.setAccessible(true); ++ final Unsafe unsafe = (Unsafe) unsafeField.get(null); ++ ++ final Field field = clazz.getDeclaredField(fieldName); ++ unsafe.putObject(instance, unsafe.objectFieldOffset(field), value); ++ } ++ ++ public static void jdk8_modifyFinal(Class clazz, String fieldName, Object instance, Object value) throws NoSuchFieldException, IllegalAccessException { ++ Field field = clazz.getDeclaredField(fieldName); ++ field.setAccessible(true); ++ ++ Field modifiers = Field.class.getDeclaredField("modifiers"); ++ modifiers.setAccessible(true); ++ modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); ++ ++ field.set(instance, value); ++ } ++} +-- +2.39.5 (Apple Git-154) + diff --git a/patches/server/0223-Fix-JDK12-final-field-modification-issues.patch b/patches/server/0223-Fix-JDK12-final-field-modification-issues.patch new file mode 100644 index 00000000..125e08f4 --- /dev/null +++ b/patches/server/0223-Fix-JDK12-final-field-modification-issues.patch @@ -0,0 +1,60 @@ +From bca366f2a4ed49ada403e19373383e7f39c93e5d Mon Sep 17 00:00:00 2001 +From: Jason Ho +Date: Sat, 24 Aug 2024 23:01:02 -0700 +Subject: [PATCH] Fix JDK12+ final field modification issues + + +diff --git a/src/main/java/org/github/paperspigot/PaperSpigotConfig.java b/src/main/java/org/github/paperspigot/PaperSpigotConfig.java +index 8cdcaf3a..6bdf4134 100644 +--- a/src/main/java/org/github/paperspigot/PaperSpigotConfig.java ++++ b/src/main/java/org/github/paperspigot/PaperSpigotConfig.java +@@ -5,6 +5,7 @@ import java.lang.reflect.Modifier; + import java.util.*; + import java.util.logging.Level; + ++import app.ashcon.sportpaper.api.reflection.ReflectionUtils; + import app.ashcon.sportpaper.server.KnockbackModificationCommand; + import net.minecraft.server.Items; + import org.apache.commons.lang.StringUtils; +@@ -162,33 +163,22 @@ public class PaperSpigotConfig + stackableWaterBuckets = getBoolean( "stackable-buckets.water", false ); + stackableMilkBuckets = getBoolean( "stackable-buckets.milk", false ); + +- Field maxStack; +- +- try { +- maxStack = Material.class.getDeclaredField("maxStack"); +- maxStack.setAccessible(true); +- +- Field modifiers = Field.class.getDeclaredField("modifiers"); +- modifiers.setAccessible(true); +- modifiers.setInt(maxStack, maxStack.getModifiers() & ~Modifier.FINAL); +- } catch (Exception e) { +- e.printStackTrace(); +- return; +- } ++ Class materialClass = Material.class; ++ String maxStackFieldName = "maxStack"; + + try { + if (stackableLavaBuckets) { +- maxStack.set(Material.LAVA_BUCKET, Material.BUCKET.getMaxStackSize()); ++ ReflectionUtils.modifyFinal(materialClass, maxStackFieldName, Material.LAVA_BUCKET, Material.BUCKET.getMaxStackSize()); + Items.LAVA_BUCKET.c(Material.BUCKET.getMaxStackSize()); + } + + if (stackableWaterBuckets) { +- maxStack.set(Material.WATER_BUCKET, Material.BUCKET.getMaxStackSize()); ++ ReflectionUtils.modifyFinal(materialClass, maxStackFieldName, Material.WATER_BUCKET, Material.BUCKET.getMaxStackSize()); + Items.WATER_BUCKET.c(Material.BUCKET.getMaxStackSize()); + } + + if (stackableMilkBuckets) { +- maxStack.set(Material.MILK_BUCKET, Material.BUCKET.getMaxStackSize()); ++ ReflectionUtils.modifyFinal(materialClass, maxStackFieldName, Material.MILK_BUCKET, Material.BUCKET.getMaxStackSize()); + Items.MILK_BUCKET.c(Material.BUCKET.getMaxStackSize()); + } + } catch (Exception e) { +-- +2.39.5 (Apple Git-154) +