mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-15 05:41:51 +08:00
Use plugin classloader for thread context when initializing system
This allows ServiceLoader to find slf4j-nop provider for Jetty preventing SLF4J "No provider" error Affects issues: - Fixed #2438
This commit is contained in:
parent
a82bcbff0d
commit
b0be4f296d
@ -90,7 +90,7 @@ subprojects {
|
||||
mysqlVersion = "8.0.26"
|
||||
sqliteVersion = "3.36.0.3"
|
||||
hikariVersion = "5.0.1"
|
||||
slf4jVersion = "1.7.36"
|
||||
slf4jVersion = "2.0.0-alpha7"
|
||||
geoIpVersion = "3.0.1"
|
||||
gsonVersion = "2.9.0"
|
||||
dependencyDownloadVersion = "1.2.1"
|
||||
|
@ -23,5 +23,4 @@ shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
|
||||
relocate 'org.bstats', 'net.playeranalytics.bstats.utilities.metrics'
|
||||
relocate 'org.slf4j', 'plan.org.slf4j'
|
||||
}
|
@ -25,6 +25,7 @@ import com.djrapitops.plan.gathering.ServerShutdownSave;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import net.playeranalytics.plugin.BukkitPlatformLayer;
|
||||
import net.playeranalytics.plugin.PlatformAbstractionLayer;
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
@ -71,7 +72,7 @@ public class Plan extends JavaPlugin implements PlanPlugin {
|
||||
.server(getServer())
|
||||
.build();
|
||||
try {
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
serverShutdownSave = component.serverShutdownSave();
|
||||
locale = system.getLocaleSystem().getLocale();
|
||||
system.enable();
|
||||
@ -175,37 +176,37 @@ public class Plan extends JavaPlugin implements PlanPlugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated due to use of APF Config
|
||||
* @deprecated Deprecated due to use of custom Config
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
@Deprecated(since = "Config.java (2018)")
|
||||
public void reloadConfig() {
|
||||
throw new IllegalStateException("This method should be used on this plugin. Use onReload() instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated due to use of APF Config
|
||||
* @deprecated Deprecated due to use of custom Config
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
@Deprecated(since = "Config.java (2018)")
|
||||
public FileConfiguration getConfig() {
|
||||
throw new IllegalStateException("This method should be used on this plugin. Use getMainConfig() instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated due to use of APF Config
|
||||
* @deprecated Deprecated due to use of custom Config
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
@Deprecated(since = "Config.java (2018)")
|
||||
public void saveConfig() {
|
||||
throw new IllegalStateException("This method should be used on this plugin. Use getMainConfig().save() instead");
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Deprecated due to use of APF Config
|
||||
* @deprecated Deprecated due to use of custom Config
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
@Deprecated(since = "Config.java (2018)")
|
||||
public void saveDefaultConfig() {
|
||||
throw new IllegalStateException("This method should be used on this plugin.");
|
||||
}
|
||||
|
@ -17,5 +17,4 @@ dependencies {
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
relocate 'org.bstats', 'net.playeranalytics.bstats.utilities.metrics'
|
||||
relocate 'org.slf4j', 'plan.org.slf4j'
|
||||
}
|
@ -23,6 +23,7 @@ import com.djrapitops.plan.exceptions.EnableException;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import net.playeranalytics.plugin.BungeePlatformLayer;
|
||||
import net.playeranalytics.plugin.PlatformAbstractionLayer;
|
||||
@ -61,7 +62,7 @@ public class PlanBungee extends Plugin implements PlanPlugin {
|
||||
.abstractionLayer(abstractionLayer)
|
||||
.build();
|
||||
try {
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
locale = system.getLocaleSystem().getLocale();
|
||||
system.enable();
|
||||
|
||||
|
@ -170,6 +170,4 @@ processResources {
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
|
||||
relocate 'org.slf4j', 'plan.org.slf4j'
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ public class PlanSystem implements SubSystem {
|
||||
|
||||
/**
|
||||
* Enables only the systems that are required for {@link com.djrapitops.plan.commands.PlanCommand}.
|
||||
*
|
||||
* @see #enableOtherThanCommands()
|
||||
*/
|
||||
public void enableForCommands() {
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.delivery.webserver.ResponseResolver;
|
||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
|
||||
import com.djrapitops.plan.delivery.webserver.configuration.WebserverLogMessages;
|
||||
import com.djrapitops.plan.exceptions.EnableException;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import net.playeranalytics.plugin.server.PluginLogger;
|
||||
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
|
||||
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
|
||||
@ -129,24 +130,19 @@ public class JettyWebserver implements WebServer {
|
||||
}
|
||||
|
||||
private ALPNServerConnectionFactory getAlpnServerConnectionFactory(String protocol) {
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
ClassLoader pluginClassLoader = getClass().getClassLoader();
|
||||
// Jetty uses Thread context classloader, so we need to change to plugin classloader where the ALPNProcessor is.
|
||||
Thread.currentThread().setContextClassLoader(pluginClassLoader);
|
||||
|
||||
Class.forName("org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor");
|
||||
// ALPN is protocol upgrade protocol required for upgrading http 1.1 connections to 2
|
||||
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory("h2", "h2c", "http/1.1");
|
||||
alpn.setDefaultProtocol(protocol);
|
||||
|
||||
return alpn;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
logger.warn("JDK9ServerALPNProcessor not found. ALPN is not available.");
|
||||
return null;
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||
}
|
||||
ClassLoader pluginClassLoader = getClass().getClassLoader();
|
||||
return ThreadContextClassLoaderSwap.performOperation(pluginClassLoader, () -> {
|
||||
try {
|
||||
Class.forName("org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor");
|
||||
// ALPN is protocol upgrade protocol required for upgrading http 1.1 connections to 2
|
||||
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory("h2", "h2c", "http/1.1");
|
||||
alpn.setDefaultProtocol(protocol);
|
||||
return alpn;
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
logger.warn("JDK9ServerALPNProcessor not found. ALPN is not available.");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Optional<SslContextFactory.Server> getSslContextFactory() {
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.java;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ThreadContextClassLoaderSwap {
|
||||
|
||||
private ThreadContextClassLoaderSwap() {
|
||||
/* static method utility class */
|
||||
}
|
||||
|
||||
public static void performOperation(ClassLoader usingClassLoader, Runnable operation) {
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// Jetty uses Thread context classloader, so we need to change to plugin classloader where the ALPNProcessor is.
|
||||
Thread.currentThread().setContextClassLoader(usingClassLoader);
|
||||
|
||||
operation.run();
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T performOperation(ClassLoader usingClassLoader, Supplier<T> operation) {
|
||||
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
// Jetty uses Thread context classloader, so we need to change to plugin classloader where the ALPNProcessor is.
|
||||
Thread.currentThread().setContextClassLoader(usingClassLoader);
|
||||
|
||||
return operation.get();
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(contextClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -50,6 +50,8 @@ shadowJar {
|
||||
exclude "**/*.svg"
|
||||
exclude "**/*.psd"
|
||||
exclude "**/*.map"
|
||||
exclude "LICENSE*.txt"
|
||||
exclude "jetty-dir.css"
|
||||
|
||||
exclude "**/module-info.class"
|
||||
exclude "module-info.class"
|
||||
|
@ -25,6 +25,7 @@ import com.djrapitops.plan.gathering.ServerShutdownSave;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import net.fabricmc.api.DedicatedServerModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
@ -93,7 +94,7 @@ public class PlanFabric implements PlanPlugin, DedicatedServerModInitializer {
|
||||
.build();
|
||||
|
||||
try {
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
serverShutdownSave = component.serverShutdownSave();
|
||||
locale = system.getLocaleSystem().getLocale();
|
||||
system.enable();
|
||||
|
@ -19,5 +19,4 @@ dependencies {
|
||||
|
||||
shadowJar {
|
||||
configurations = [project.configurations.shadow]
|
||||
relocate 'org.slf4j', 'plan.org.slf4j'
|
||||
}
|
@ -28,6 +28,7 @@ import com.djrapitops.plan.gathering.ServerShutdownSave;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||
import net.playeranalytics.plugin.NukkitPlatformLayer;
|
||||
import net.playeranalytics.plugin.PlatformAbstractionLayer;
|
||||
@ -75,7 +76,7 @@ public class PlanNukkit extends PluginBase implements PlanPlugin {
|
||||
.abstractionLayer(abstractionLayer)
|
||||
.build();
|
||||
try {
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
serverShutdownSave = component.serverShutdownSave();
|
||||
locale = system.getLocaleSystem().getLocale();
|
||||
system.enable();
|
||||
|
@ -31,6 +31,8 @@ shadowJar {
|
||||
exclude "**/*.svg"
|
||||
exclude "**/*.psd"
|
||||
exclude "**/*.map"
|
||||
exclude "LICENSE*.txt"
|
||||
exclude "jetty-dir.css"
|
||||
|
||||
exclude "**/module-info.class"
|
||||
exclude "module-info.class"
|
||||
@ -56,6 +58,12 @@ shadowJar {
|
||||
exclude "jakarta/xml/**/*"
|
||||
exclude "javassist/**/*"
|
||||
|
||||
relocate('org.slf4j', 'plan.org.slf4j') {
|
||||
exclude 'com.djrapitops.plan.PlanVelocity'
|
||||
exclude 'net.playeranalytics.plugin.VelocityPlatformLayer'
|
||||
exclude 'net.playeranalytics.plugin.server.VelocityPluginLogger'
|
||||
}
|
||||
|
||||
relocate('org.apache', 'plan.org.apache') {
|
||||
exclude 'org/apache/logging/**'
|
||||
exclude 'org/apache/maven/**' // This needs to be unrelocated for Sponge
|
||||
|
@ -24,6 +24,7 @@ import com.djrapitops.plan.gathering.ServerShutdownSave;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import net.playeranalytics.plugin.PlatformAbstractionLayer;
|
||||
import net.playeranalytics.plugin.SpongePlatformLayer;
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
@ -104,7 +105,7 @@ public class PlanSponge implements PlanPlugin {
|
||||
|
||||
catchStartupErrors(() -> {
|
||||
component = makeComponent();
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
system.enableForCommands();
|
||||
});
|
||||
}
|
||||
@ -120,7 +121,7 @@ public class PlanSponge implements PlanPlugin {
|
||||
if (!firstBoot) {
|
||||
// Reinitialize component & system
|
||||
component = makeComponent();
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
}
|
||||
|
||||
serverShutdownSave = component.serverShutdownSave();
|
||||
|
@ -23,6 +23,7 @@ import com.djrapitops.plan.exceptions.EnableException;
|
||||
import com.djrapitops.plan.settings.locale.Locale;
|
||||
import com.djrapitops.plan.settings.locale.lang.PluginLang;
|
||||
import com.djrapitops.plan.settings.theme.PlanColorScheme;
|
||||
import com.djrapitops.plan.utilities.java.ThreadContextClassLoaderSwap;
|
||||
import com.velocitypowered.api.command.CommandManager;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
@ -106,7 +107,7 @@ public class PlanVelocity implements PlanPlugin {
|
||||
.abstractionLayer(abstractionLayer)
|
||||
.build();
|
||||
try {
|
||||
system = component.system();
|
||||
system = ThreadContextClassLoaderSwap.performOperation(getClass().getClassLoader(), component::system);
|
||||
locale = system.getLocaleSystem().getLocale();
|
||||
system.enable();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user