Implement SlimJar as a runtime dependency downloader (#1990)

MySQL & SQLite are dynamically (down)loaded to the classpath instead of being shaded.

Affects issues:
- Close #1944
This commit is contained in:
Antti Koponen 2021-08-07 15:29:54 +03:00 committed by GitHub
parent 9873eceeb4
commit d29a94e6a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 109 additions and 9 deletions

View File

@ -7,7 +7,8 @@ buildscript {
}
plugins {
id "com.github.johnrengelman.shadow" version "7.0.0"
id "com.github.johnrengelman.shadow" version "7.0.0" apply false
id "io.github.slimjar" version "1.2.1" apply false
id "java"
id "jacoco"
id "checkstyle"
@ -48,6 +49,7 @@ logger.lifecycle("Building artifact for version $fullVersion")
subprojects {
// Build plugins
apply plugin: "com.github.johnrengelman.shadow"
apply plugin: "io.github.slimjar"
apply plugin: "java"
apply plugin: "maven-publish"

View File

@ -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 io.github.slimjar.app.builder.ApplicationBuilder;
import net.playeranalytics.plugin.BukkitPlatformLayer;
import net.playeranalytics.plugin.PlatformAbstractionLayer;
import net.playeranalytics.plugin.scheduling.RunnableFactory;
@ -34,6 +35,10 @@ import org.bukkit.command.PluginCommand;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.Optional;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@ -61,6 +66,20 @@ public class Plan extends JavaPlugin implements PlanPlugin {
abstractionLayer = new BukkitPlatformLayer(this);
pluginLogger = abstractionLayer.getPluginLogger();
runnableFactory = abstractionLayer.getRunnableFactory();
getLogger().log(Level.INFO, "Loading dependencies, this might take a while...");
try {
ApplicationBuilder.appending("Plan")
.logger((message, args) -> getLogger().log(Level.INFO, message, args))
.downloadDirectoryPath(Paths.get(getDataFolder().getAbsolutePath()).resolve("libraries"))
.build();
} catch (IOException | ReflectiveOperationException | URISyntaxException | NoSuchAlgorithmException e) {
String version = abstractionLayer.getPluginInformation().getVersion();
getLogger().log(Level.SEVERE, e, () -> this.getClass().getSimpleName() + "-v" + version);
getLogger().log(Level.SEVERE, "Plan failed to load its dependencies correctly!");
getLogger().log(Level.SEVERE, "This error should be reported at https://github.com/plan-player-analytics/Plan/issues");
onDisable();
}
}
@Override

View File

@ -23,13 +23,18 @@ 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 io.github.slimjar.app.builder.ApplicationBuilder;
import net.md_5.bungee.api.plugin.Plugin;
import net.playeranalytics.plugin.BungeePlatformLayer;
import net.playeranalytics.plugin.PlatformAbstractionLayer;
import net.playeranalytics.plugin.scheduling.RunnableFactory;
import net.playeranalytics.plugin.server.PluginLogger;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -52,6 +57,20 @@ public class PlanBungee extends Plugin implements PlanPlugin {
abstractionLayer = new BungeePlatformLayer(this);
logger = abstractionLayer.getPluginLogger();
runnableFactory = abstractionLayer.getRunnableFactory();
getLogger().log(Level.INFO, "Loading dependencies, this might take a while...");
try {
ApplicationBuilder.appending("Plan")
.logger((message, args) -> getLogger().log(Level.INFO, message, args))
.downloadDirectoryPath(Paths.get(getDataFolder().getAbsolutePath()).resolve("libraries"))
.build();
} catch (IOException | ReflectiveOperationException | URISyntaxException | NoSuchAlgorithmException e) {
String version = abstractionLayer.getPluginInformation().getVersion();
getLogger().log(Level.SEVERE, e, () -> this.getClass().getSimpleName() + "-v" + version);
getLogger().log(Level.SEVERE, "Plan failed to load its dependencies correctly!");
getLogger().log(Level.SEVERE, "This error should be reported at https://github.com/plan-player-analytics/Plan/issues");
onDisable();
}
}
@Override

View File

@ -6,8 +6,8 @@ dependencies {
implementation "org.apache.commons:commons-text:$commonsTextVersion"
implementation "org.apache.commons:commons-compress:$commonsCompressVersion"
implementation "com.github.ben-manes.caffeine:caffeine:$caffeineVersion"
implementation "mysql:mysql-connector-java:$mysqlVersion"
implementation "org.xerial:sqlite-jdbc:$sqliteVersion"
compileOnly "mysql:mysql-connector-java:$mysqlVersion"
compileOnly "org.xerial:sqlite-jdbc:$sqliteVersion"
implementation "com.zaxxer:HikariCP:$hikariVersion"
implementation "org.slf4j:slf4j-nop:$slf4jVersion"
implementation "org.slf4j:slf4j-api:$slf4jVersion"
@ -76,8 +76,6 @@ shadowJar {
exclude '**/Linux/android-arm/libsqlitejdbc.so'
exclude '**/DragonFlyBSD/**/libsqlitejdbc.so'
relocate 'com.google.protobuf', 'plan.com.mysql.cj.x.google.protobuf'
relocate 'com.maxmind', 'plan.com.maxmind'
relocate 'com.fasterxml', 'plan.com.fasterxml'
relocate 'com.zaxxer', 'plan.com.zaxxer'

View File

@ -35,7 +35,6 @@ public class OldDependencyCacheDeletionTask extends TaskSystem.Task {
private final File oldDependencyCache;
private final File dependencyCache;
private final File libraries;
private final ErrorLogger errorLogger;
@ -46,7 +45,6 @@ public class OldDependencyCacheDeletionTask extends TaskSystem.Task {
) {
oldDependencyCache = files.getDataDirectory().resolve("dependency_cache").toFile();
dependencyCache = files.getDataDirectory().resolve("dep_cache").toFile();
libraries = files.getDataDirectory().resolve("libraries").toFile();
this.errorLogger = errorLogger;
}
@ -60,7 +58,6 @@ public class OldDependencyCacheDeletionTask extends TaskSystem.Task {
public void run() {
tryToDeleteDirectory(oldDependencyCache);
tryToDeleteDirectory(dependencyCache);
tryToDeleteDirectory(libraries);
}
private void tryToDeleteDirectory(File directory) {

1
Plan/gradle.properties Normal file
View File

@ -0,0 +1 @@
slimjar.version=1.2.5

View File

@ -29,11 +29,16 @@ 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.logging.ErrorContext;
import io.github.slimjar.app.builder.ApplicationBuilder;
import net.playeranalytics.plugin.NukkitPlatformLayer;
import net.playeranalytics.plugin.PlatformAbstractionLayer;
import net.playeranalytics.plugin.scheduling.RunnableFactory;
import net.playeranalytics.plugin.server.PluginLogger;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -66,6 +71,20 @@ public class PlanNukkit extends PluginBase implements PlanPlugin {
abstractionLayer = new NukkitPlatformLayer(this);
logger = abstractionLayer.getPluginLogger();
runnableFactory = abstractionLayer.getRunnableFactory();
getLogger().info( "Loading dependencies, this might take a while...");
try {
ApplicationBuilder.appending("Plan")
.logger((message, args) -> Logger.getGlobal().log(Level.INFO, message, args))
.downloadDirectoryPath(Paths.get(getDataFolder().getAbsolutePath()).resolve("libraries"))
.build();
} catch (IOException | ReflectiveOperationException | URISyntaxException | NoSuchAlgorithmException e) {
String version = abstractionLayer.getPluginInformation().getVersion();
Logger.getGlobal().log(Level.SEVERE, e, () -> this.getClass().getSimpleName() + "-v" + version);
getLogger().error("Plan failed to load its dependencies correctly!");
getLogger().error( "This error should be reported at https://github.com/plan-player-analytics/Plan/issues");
onDisable();
}
}
@Override

View File

@ -11,6 +11,14 @@ dependencies {
testImplementation project(path: ":sponge", configuration: 'testArtifacts')
testImplementation project(path: ":bungeecord", configuration: 'testArtifacts')
testImplementation project(path: ":velocity", configuration: 'testArtifacts')
slim "mysql:mysql-connector-java:$mysqlVersion"
slim "org.xerial:sqlite-jdbc:$sqliteVersion"
}
slimJar {
relocate 'com.mysql', 'plan.com.mysql'
relocate 'com.google.protobuf', 'plan.com.mysql.cj.x.google.protobuf'
}
shadowJar {
@ -18,7 +26,6 @@ shadowJar {
exclude 'org/apache/logging/**'
}
relocate 'dagger', 'plan.dagger'
relocate 'com.mysql', 'plan.com.mysql'
// Don't relocate SQLite since the org.sqlite.NativeDB class calls are not relocated properly
// relocate 'org.sqlite', 'plan.org.sqlite'
relocate 'javax.inject', 'plan.javax.inject'

View File

@ -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 io.github.slimjar.app.builder.ApplicationBuilder;
import net.playeranalytics.plugin.PlatformAbstractionLayer;
import net.playeranalytics.plugin.SpongePlatformLayer;
import net.playeranalytics.plugin.scheduling.RunnableFactory;
@ -44,7 +45,11 @@ import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.scheduler.Task;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@ -115,6 +120,20 @@ public class PlanSponge implements PlanPlugin {
abstractionLayer = new SpongePlatformLayer(this, dataFolder, slf4jLogger);
logger = abstractionLayer.getPluginLogger();
runnableFactory = abstractionLayer.getRunnableFactory();
logger.info("Loading dependencies, this might take a while...");
try {
ApplicationBuilder.appending("Plan")
.logger((message, args) -> java.util.logging.Logger.getGlobal().log(Level.INFO, message, args))
.downloadDirectoryPath(Paths.get(getDataFolder().getAbsolutePath()).resolve("libraries"))
.build();
} catch (IOException | ReflectiveOperationException | URISyntaxException | NoSuchAlgorithmException e) {
String version = abstractionLayer.getPluginInformation().getVersion();
java.util.logging.Logger.getGlobal().log(Level.SEVERE, e, () -> this.getClass().getSimpleName() + "-v" + version);
logger.error("Plan failed to load its dependencies correctly!");
logger.error("This error should be reported at https://github.com/plan-player-analytics/Plan/issues");
onDisable();
}
}
public void onEnable() {

View File

@ -31,6 +31,7 @@ import com.velocitypowered.api.plugin.Dependency;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import io.github.slimjar.app.builder.ApplicationBuilder;
import net.playeranalytics.plugin.PlatformAbstractionLayer;
import net.playeranalytics.plugin.VelocityPlatformLayer;
import net.playeranalytics.plugin.scheduling.RunnableFactory;
@ -39,8 +40,12 @@ import org.bstats.velocity.Metrics;
import org.slf4j.Logger;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
/**
@ -99,6 +104,20 @@ public class PlanVelocity implements PlanPlugin {
logger = abstractionLayer.getPluginLogger();
runnableFactory = abstractionLayer.getRunnableFactory();
logger.info("Loading dependencies, this might take a while...");
try {
ApplicationBuilder.appending("Plan")
.logger((message, args) -> java.util.logging.Logger.getGlobal().log(Level.INFO, message, args))
.downloadDirectoryPath(Paths.get(getDataFolder().getAbsolutePath()).resolve("libraries"))
.build();
} catch (IOException | ReflectiveOperationException | URISyntaxException | NoSuchAlgorithmException e) {
String version = abstractionLayer.getPluginInformation().getVersion();
java.util.logging.Logger.getGlobal().log(Level.SEVERE, e, () -> this.getClass().getSimpleName() + "-v" + version);
logger.error("Plan failed to load its dependencies correctly!");
logger.error("This error should be reported at https://github.com/plan-player-analytics/Plan/issues");
onDisable();
}
PlanVelocityComponent component = DaggerPlanVelocityComponent.builder()
.plan(this)
.abstractionLayer(abstractionLayer)