diff options
5 files changed, 126 insertions, 5 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java index ec1ea9a..21f9210 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java +++ b/spark-common/src/main/java/me/lucko/spark/common/SparkPlatform.java @@ -53,6 +53,7 @@ import me.lucko.spark.common.tick.TickHook; import me.lucko.spark.common.tick.TickReporter; import me.lucko.spark.common.util.BytebinClient; import me.lucko.spark.common.util.Configuration; +import me.lucko.spark.common.util.SparkStaticLogger; import me.lucko.spark.common.util.TemporaryFiles; import me.lucko.spark.common.ws.TrustedKeyStore; import net.kyori.adventure.text.Component; @@ -116,6 +117,7 @@ public class SparkPlatform { public SparkPlatform(SparkPlugin plugin) { this.plugin = plugin; + SparkStaticLogger.setLogger(plugin::log); this.temporaryFiles = new TemporaryFiles(this.plugin.getPluginDirectory().resolve("tmp")); this.configuration = new Configuration(this.plugin.getPluginDirectory().resolve("config.json")); diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/ClassFinder.java b/spark-common/src/main/java/me/lucko/spark/common/util/ClassFinder.java index 8bc06a8..cead938 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/util/ClassFinder.java +++ b/spark-common/src/main/java/me/lucko/spark/common/util/ClassFinder.java @@ -26,6 +26,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.lang.instrument.Instrumentation; import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; /** * Uses {@link Instrumentation} to find a class reference for given class names. @@ -34,15 +35,27 @@ import java.util.Map; */ public class ClassFinder { - private final Map<String, Class<?>> classes = new HashMap<>(); + private static boolean warned = false; - public ClassFinder() { - Instrumentation instrumentation; + private static Instrumentation loadInstrumentation() { + Instrumentation instrumentation = null; try { instrumentation = ByteBuddyAgent.install(); + if (!warned && JavaVersion.getJavaVersion() >= 21) { + warned = true; + SparkStaticLogger.log(Level.INFO, "If you see a warning above that says \"WARNING: A Java agent has been loaded dynamically\", it can be safely ignored."); + SparkStaticLogger.log(Level.INFO, "See here for more information: https://spark.lucko.me/docs/misc/Java-agent-warning"); + } } catch (Exception e) { - return; + // ignored } + return instrumentation; + } + + private final Map<String, Class<?>> classes = new HashMap<>(); + + public ClassFinder() { + Instrumentation instrumentation = loadInstrumentation(); if (instrumentation == null) { return; } diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/JavaVersion.java b/spark-common/src/main/java/me/lucko/spark/common/util/JavaVersion.java new file mode 100644 index 0000000..efeabfc --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/JavaVersion.java @@ -0,0 +1,44 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.util; + +public class JavaVersion { + ; + + private static final int JAVA_VERSION; + static { + JAVA_VERSION = parseJavaVersion(System.getProperty("java.version")); + } + + private static int parseJavaVersion(String version) { + if (version.startsWith("1.")) { + // Java 8 and below + return Integer.parseInt(version.substring(2, 3)); + } else { + // Java 9 and above + return Integer.parseInt(version.split("\\.")[0]); + } + } + + public static int getJavaVersion() { + return JAVA_VERSION; + } +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/SparkStaticLogger.java b/spark-common/src/main/java/me/lucko/spark/common/util/SparkStaticLogger.java new file mode 100644 index 0000000..eb5f316 --- /dev/null +++ b/spark-common/src/main/java/me/lucko/spark/common/util/SparkStaticLogger.java @@ -0,0 +1,61 @@ +/* + * This file is part of spark. + * + * Copyright (c) lucko (Luck) <luck@lucko.me> + * Copyright (c) contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package me.lucko.spark.common.util; + +import java.util.logging.Level; + +/** + * Special logger for use by classes that don't easily have access to a + * {@link me.lucko.spark.common.SparkPlatform} instance. + * + * <p>This avoids warnings on platforms like Paper that get upset if plugins use + * {@link System#out} or {@link System#err}.</p> + */ +public enum SparkStaticLogger { + ; + + private static Logger logger = null; + + public synchronized static void setLogger(Logger logger) { + if (SparkStaticLogger.logger == null) { + SparkStaticLogger.logger = logger; + } + } + + public static void log(Level level, String msg) { + Logger logger = SparkStaticLogger.logger; + if (logger == null) { + if (level.intValue() >= 1000) { + System.err.println(msg); + } else { + System.out.println(msg); + } + return; + } + + logger.log(level, msg); + } + + public interface Logger { + void log(Level level, String msg); + } + +} diff --git a/spark-common/src/main/java/me/lucko/spark/common/util/SparkThreadFactory.java b/spark-common/src/main/java/me/lucko/spark/common/util/SparkThreadFactory.java index 42dca12..1d6971b 100644 --- a/spark-common/src/main/java/me/lucko/spark/common/util/SparkThreadFactory.java +++ b/spark-common/src/main/java/me/lucko/spark/common/util/SparkThreadFactory.java @@ -22,11 +22,12 @@ package me.lucko.spark.common.util; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; public class SparkThreadFactory implements ThreadFactory { public static final Thread.UncaughtExceptionHandler EXCEPTION_HANDLER = (t, e) -> { - System.err.println("Uncaught exception thrown by thread " + t.getName()); + SparkStaticLogger.log(Level.SEVERE, "Uncaught exception thrown by thread " + t.getName()); e.printStackTrace(); }; |