mirror of
https://github.com/xHyroM/lighteco.git
synced 2024-11-21 14:31:09 +01:00
feat: make jar even more small, dependency relocation
This commit is contained in:
parent
3802dba410
commit
1ae9a2e5bc
11 changed files with 224 additions and 36 deletions
|
@ -37,5 +37,8 @@ tasks.shadowJar {
|
||||||
|
|
||||||
relocate("org.yaml.snakeyaml", "dev.xhyrom.lighteco.libraries.org.yaml.snakeyaml")
|
relocate("org.yaml.snakeyaml", "dev.xhyrom.lighteco.libraries.org.yaml.snakeyaml")
|
||||||
|
|
||||||
relocate("com.zaxxer.hikari", "dev.xhyrom.lighteco.libraries.com.zaxxer.hikari")
|
relocate("org.mariadb.jdbc", "dev.xhyrom.lighteco.libraries.mariadb")
|
||||||
|
relocate("com.mysql", "dev.xhyrom.lighteco.libraries.mysql")
|
||||||
|
relocate("org.postgresql", "dev.xhyrom.lighteco.libraries.postgresql")
|
||||||
|
relocate("com.zaxxer.hikari", "dev.xhyrom.lighteco.libraries.hikari")
|
||||||
}
|
}
|
|
@ -52,7 +52,7 @@ public class BukkitLightEcoPlugin extends AbstractLightEcoPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void registerPlatformHooks() {
|
protected void registerPlatformHooks() {
|
||||||
Hooks.register();
|
Hooks.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -2,18 +2,28 @@ package dev.xhyrom.lighteco.bukkit;
|
||||||
|
|
||||||
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter;
|
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerAdapter;
|
||||||
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerTask;
|
import dev.xhyrom.lighteco.common.plugin.scheduler.SchedulerTask;
|
||||||
|
import lombok.Getter;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class BukkitSchedulerAdapter implements SchedulerAdapter {
|
public class BukkitSchedulerAdapter implements SchedulerAdapter {
|
||||||
|
private final Executor async;
|
||||||
|
|
||||||
private final BukkitLightEcoBootstrap bootstrap;
|
private final BukkitLightEcoBootstrap bootstrap;
|
||||||
private final BukkitScheduler scheduler;
|
private final BukkitScheduler scheduler;
|
||||||
|
|
||||||
public BukkitSchedulerAdapter(BukkitLightEcoBootstrap bootstrap) {
|
public BukkitSchedulerAdapter(BukkitLightEcoBootstrap bootstrap) {
|
||||||
this.bootstrap = bootstrap;
|
this.bootstrap = bootstrap;
|
||||||
this.scheduler = bootstrap.getServer().getScheduler();
|
this.scheduler = bootstrap.getServer().getScheduler();
|
||||||
|
|
||||||
|
this.async = runnable -> this.scheduler.runTaskAsynchronously(this.bootstrap.getLoader(), runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Executor async() {
|
||||||
|
return this.async;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package dev.xhyrom.lighteco.bukkit.hooks;
|
package dev.xhyrom.lighteco.bukkit.hooks;
|
||||||
|
|
||||||
|
import dev.xhyrom.lighteco.bukkit.BukkitLightEcoPlugin;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
public class Hooks {
|
public class Hooks {
|
||||||
private static PlaceholderAPIExpansion placeholderAPIExpansion;
|
private static PlaceholderAPIExpansion placeholderAPIExpansion;
|
||||||
|
|
||||||
public static void register() {
|
public static void register(BukkitLightEcoPlugin plugin) {
|
||||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null)
|
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||||
|
placeholderAPIExpansion = new PlaceholderAPIExpansion(plugin);
|
||||||
placeholderAPIExpansion.register();
|
placeholderAPIExpansion.register();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void unregister() {
|
public static void unregister() {
|
||||||
|
|
|
@ -9,13 +9,16 @@ dependencies {
|
||||||
exclude(module = "checker-qual")
|
exclude(module = "checker-qual")
|
||||||
exclude(module = "annotations")
|
exclude(module = "annotations")
|
||||||
}
|
}
|
||||||
api("net.kyori:adventure-text-minimessage:4.14.0")
|
api("net.kyori:adventure-text-minimessage:4.14.0") {
|
||||||
|
exclude(module = "adventure-bom")
|
||||||
|
exclude(module = "adventure-api")
|
||||||
|
}
|
||||||
api("com.google.guava:guava:32.1.2-jre")
|
api("com.google.guava:guava:32.1.2-jre")
|
||||||
|
|
||||||
implementation("eu.okaeri:okaeri-configs-yaml-snakeyaml:5.0.0-beta.5")
|
implementation("eu.okaeri:okaeri-configs-yaml-snakeyaml:5.0.0-beta.5")
|
||||||
implementation("eu.okaeri:okaeri-configs-validator-okaeri:5.0.0-beta.5")
|
implementation("eu.okaeri:okaeri-configs-validator-okaeri:5.0.0-beta.5")
|
||||||
|
|
||||||
implementation("com.zaxxer:HikariCP:5.0.1")
|
compileOnly("com.zaxxer:HikariCP:5.0.1")
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.28")
|
compileOnly("org.projectlombok:lombok:1.18.28")
|
||||||
annotationProcessor("org.projectlombok:lombok:1.18.28")
|
annotationProcessor("org.projectlombok:lombok:1.18.28")
|
||||||
|
|
|
@ -1,55 +1,104 @@
|
||||||
package dev.xhyrom.lighteco.common.dependencies;
|
package dev.xhyrom.lighteco.common.dependencies;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import dev.xhyrom.lighteco.common.dependencies.relocation.Relocation;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public enum Dependency {
|
public enum Dependency {
|
||||||
|
/**
|
||||||
|
* Somewhere we use brackets instad of dots, so we need to rewrite them
|
||||||
|
* This is because gradle's shadow plugin relocates using replacing full paths (dots)
|
||||||
|
*/
|
||||||
|
|
||||||
|
ASM(
|
||||||
|
"org.ow2.asm",
|
||||||
|
"asm",
|
||||||
|
"9.1"
|
||||||
|
),
|
||||||
|
ASM_COMMONS(
|
||||||
|
"org.ow2.asm",
|
||||||
|
"asm-commons",
|
||||||
|
"9.1"
|
||||||
|
),
|
||||||
|
JAR_RELOCATOR(
|
||||||
|
"me.lucko",
|
||||||
|
"jar-relocator",
|
||||||
|
"1.7"
|
||||||
|
),
|
||||||
|
HIKARI(
|
||||||
|
"com{}zaxxer",
|
||||||
|
"HikariCP",
|
||||||
|
"5.0.1",
|
||||||
|
Relocation.of("hikari", "com{}zaxxer{}hikari")
|
||||||
|
),
|
||||||
H2_DRIVER(
|
H2_DRIVER(
|
||||||
"com.h2database",
|
"com.h2database",
|
||||||
"h2",
|
"h2",
|
||||||
"2.1.214"
|
"2.1.214"
|
||||||
),
|
),
|
||||||
SQLITE_DRIVER(
|
SQLITE_DRIVER(
|
||||||
"org.xerial",
|
"org.xerial",
|
||||||
"sqlite-jdbc",
|
"sqlite-jdbc",
|
||||||
"3.28.0"
|
"3.28.0"
|
||||||
),
|
),
|
||||||
MARIADB_DRIVER(
|
MARIADB_DRIVER(
|
||||||
"org.mariadb.jdbc",
|
"org{}mariadb{}jdbc",
|
||||||
"mariadb-java-client",
|
"mariadb-java-client",
|
||||||
"3.1.3"
|
"3.1.3",
|
||||||
|
Relocation.of("mariadb", "org{}mariadb{}jdbc")
|
||||||
),
|
),
|
||||||
MYSQL_DRIVER(
|
MYSQL_DRIVER(
|
||||||
"mysql",
|
"mysql",
|
||||||
"mysql-connector-java",
|
"mysql-connector-java",
|
||||||
"8.0.23"
|
"8.0.23",
|
||||||
|
Relocation.of("mysql", "com{}mysql")
|
||||||
),
|
),
|
||||||
POSTGRESQL_DRIVER(
|
POSTGRESQL_DRIVER(
|
||||||
"org.postgresql",
|
"org{}postgresql",
|
||||||
"postgresql",
|
"postgresql",
|
||||||
"42.6.0"
|
"42.6.0",
|
||||||
|
Relocation.of("postgresql", "org{}postgresql")
|
||||||
);
|
);
|
||||||
|
|
||||||
private final String fullPath;
|
private final String fullPath;
|
||||||
private final String version;
|
private final String version;
|
||||||
|
@Getter
|
||||||
|
private final List<Relocation> relocations;
|
||||||
|
|
||||||
private static final String MAVEN_FORMAT = "%s/%s/%s/%s-%s.jar";
|
private static final String MAVEN_FORMAT = "%s/%s/%s/%s-%s.jar";
|
||||||
|
|
||||||
Dependency(String groupId, String artifactId, String version) {
|
Dependency(String groupId, String artifactId, String version) {
|
||||||
|
this(groupId, artifactId, version, new Relocation[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dependency(String groupId, String artifactId, String version, Relocation... relocations) {
|
||||||
this.fullPath = String.format(MAVEN_FORMAT,
|
this.fullPath = String.format(MAVEN_FORMAT,
|
||||||
groupId.replace('.', '/'),
|
rewriteEscape(groupId).replace('.', '/'),
|
||||||
artifactId,
|
rewriteEscape(artifactId),
|
||||||
version,
|
version,
|
||||||
artifactId,
|
rewriteEscape(artifactId),
|
||||||
version
|
version
|
||||||
);
|
);
|
||||||
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
this.relocations = ImmutableList.copyOf(relocations);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String rewriteEscape(String path) {
|
||||||
|
return path.replace("{}", ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
String name = name().toLowerCase().replace('_', '-');
|
return getFileName(null);
|
||||||
|
}
|
||||||
|
|
||||||
return String.format("%s-%s.jar", name, this.version);
|
public String getFileName(String classifier) {
|
||||||
|
String name = name().toLowerCase().replace('_', '-');
|
||||||
|
String extra = classifier == null ? "" : "-" + classifier;
|
||||||
|
|
||||||
|
return String.format("%s-%s.jar", name, this.version + extra);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,22 +2,23 @@ package dev.xhyrom.lighteco.common.dependencies;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.io.MoreFiles;
|
import com.google.common.io.MoreFiles;
|
||||||
|
import dev.xhyrom.lighteco.common.dependencies.relocation.Relocation;
|
||||||
|
import dev.xhyrom.lighteco.common.dependencies.relocation.RelocationHandler;
|
||||||
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
|
import dev.xhyrom.lighteco.common.plugin.LightEcoPlugin;
|
||||||
import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger;
|
import dev.xhyrom.lighteco.common.plugin.logger.PluginLogger;
|
||||||
import dev.xhyrom.lighteco.common.util.URLClassLoaderAccess;
|
import dev.xhyrom.lighteco.common.util.URLClassLoaderAccess;
|
||||||
import dev.xhyrom.lighteco.common.storage.StorageType;
|
import dev.xhyrom.lighteco.common.storage.StorageType;
|
||||||
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.EnumMap;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
public class DependencyManagerImpl implements DependencyManager {
|
public class DependencyManagerImpl implements DependencyManager {
|
||||||
private final EnumMap<Dependency, Path> loaded = new EnumMap<>(Dependency.class);
|
private final EnumMap<Dependency, Path> loaded = new EnumMap<>(Dependency.class);
|
||||||
|
@ -27,6 +28,7 @@ public class DependencyManagerImpl implements DependencyManager {
|
||||||
private final DependencyRegistry registry;
|
private final DependencyRegistry registry;
|
||||||
private final Path cacheDirectory;
|
private final Path cacheDirectory;
|
||||||
private final URLClassLoaderAccess classLoader;
|
private final URLClassLoaderAccess classLoader;
|
||||||
|
private @MonotonicNonNull RelocationHandler relocationHandler;
|
||||||
|
|
||||||
public DependencyManagerImpl(LightEcoPlugin plugin) {
|
public DependencyManagerImpl(LightEcoPlugin plugin) {
|
||||||
this.logger = plugin.getBootstrap().getLogger();
|
this.logger = plugin.getBootstrap().getLogger();
|
||||||
|
@ -35,9 +37,18 @@ public class DependencyManagerImpl implements DependencyManager {
|
||||||
this.classLoader = URLClassLoaderAccess.create((URLClassLoader) plugin.getBootstrap().getClass().getClassLoader());
|
this.classLoader = URLClassLoaderAccess.create((URLClassLoader) plugin.getBootstrap().getClass().getClassLoader());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized RelocationHandler getRelocationHandler() {
|
||||||
|
if (this.relocationHandler == null) {
|
||||||
|
this.relocationHandler = new RelocationHandler(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.relocationHandler;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadDependencies(Set<Dependency> dependencies) {
|
public void loadDependencies(Set<Dependency> dependencies) {
|
||||||
CountDownLatch latch = new CountDownLatch(dependencies.size());
|
CountDownLatch latch = new CountDownLatch(dependencies.size());
|
||||||
|
this.logger.info("Loading dependencies: " + dependencies);
|
||||||
|
|
||||||
for (Dependency dependency : dependencies) {
|
for (Dependency dependency : dependencies) {
|
||||||
if (this.loaded.containsKey(dependency)) {
|
if (this.loaded.containsKey(dependency)) {
|
||||||
|
@ -46,18 +57,22 @@ public class DependencyManagerImpl implements DependencyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
|
System.out.println("Loading dependency " + dependency);
|
||||||
try {
|
try {
|
||||||
loadDependency(dependency);
|
loadDependency(dependency);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to load dependency " + dependency, e);
|
throw new RuntimeException("Failed to load dependency " + dependency, e);
|
||||||
} finally {
|
} finally {
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
|
System.out.println("Loaded dependency " + dependency);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
latch.await();
|
latch.await();
|
||||||
|
|
||||||
|
this.logger.info("Loaded dependencies: " + dependencies);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +83,7 @@ public class DependencyManagerImpl implements DependencyManager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Path file = downloadDependency(dependency);
|
Path file = remapDependency(dependency, downloadDependency(dependency));
|
||||||
|
|
||||||
this.loaded.put(dependency, file);
|
this.loaded.put(dependency, file);
|
||||||
|
|
||||||
|
@ -95,6 +110,24 @@ public class DependencyManagerImpl implements DependencyManager {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Path remapDependency(Dependency dependency, Path normalFile) throws Exception {
|
||||||
|
List<Relocation> rules = new ArrayList<>(dependency.getRelocations());
|
||||||
|
|
||||||
|
if (rules.isEmpty()) {
|
||||||
|
return normalFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path remappedFile = this.cacheDirectory.resolve(dependency.getFileName("remapped"));
|
||||||
|
|
||||||
|
// if the remapped source exists already, just use that.
|
||||||
|
if (Files.exists(remappedFile)) {
|
||||||
|
return remappedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getRelocationHandler().remap(normalFile, remappedFile, rules);
|
||||||
|
return remappedFile;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadStorageDependencies(Set<StorageType> types) {
|
public void loadStorageDependencies(Set<StorageType> types) {
|
||||||
loadDependencies(this.registry.resolveStorageDependencies(types));
|
loadDependencies(this.registry.resolveStorageDependencies(types));
|
||||||
|
|
|
@ -9,11 +9,11 @@ import java.util.Set;
|
||||||
|
|
||||||
public class DependencyRegistry {
|
public class DependencyRegistry {
|
||||||
private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES = ImmutableSetMultimap.<StorageType, Dependency>builder()
|
private static final SetMultimap<StorageType, Dependency> STORAGE_DEPENDENCIES = ImmutableSetMultimap.<StorageType, Dependency>builder()
|
||||||
.putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER)
|
.putAll(StorageType.SQLITE, Dependency.SQLITE_DRIVER)
|
||||||
.putAll(StorageType.H2, Dependency.H2_DRIVER)
|
.putAll(StorageType.H2, Dependency.H2_DRIVER)
|
||||||
.putAll(StorageType.MYSQL, Dependency.MYSQL_DRIVER)
|
.putAll(StorageType.MYSQL, Dependency.MYSQL_DRIVER, Dependency.HIKARI)
|
||||||
.putAll(StorageType.MARIADB, Dependency.MARIADB_DRIVER)
|
.putAll(StorageType.MARIADB, Dependency.MARIADB_DRIVER, Dependency.HIKARI)
|
||||||
.putAll(StorageType.POSTGRESQL, Dependency.POSTGRESQL_DRIVER)
|
.putAll(StorageType.POSTGRESQL, Dependency.POSTGRESQL_DRIVER, Dependency.HIKARI)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) {
|
public Set<Dependency> resolveStorageDependencies(Set<StorageType> types) {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package dev.xhyrom.lighteco.common.dependencies.relocation;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class Relocation {
|
||||||
|
private static final String RELOCATION_PREFIX = "dev.xhyrom.lighteco.libraries.";
|
||||||
|
|
||||||
|
public static Relocation of(String id, String pattern) {
|
||||||
|
return new Relocation(pattern.replace("{}", "."), RELOCATION_PREFIX + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String pattern;
|
||||||
|
private final String relocatedPattern;
|
||||||
|
|
||||||
|
private Relocation(String pattern, String relocatedPattern) {
|
||||||
|
this.pattern = pattern;
|
||||||
|
this.relocatedPattern = relocatedPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package dev.xhyrom.lighteco.common.dependencies.relocation;
|
||||||
|
|
||||||
|
import dev.xhyrom.lighteco.common.dependencies.Dependency;
|
||||||
|
import dev.xhyrom.lighteco.common.dependencies.DependencyManager;
|
||||||
|
import dev.xhyrom.lighteco.common.dependencies.IsolatedClassLoader;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class RelocationHandler {
|
||||||
|
public static final Set<Dependency> DEPENDENCIES = EnumSet.of(Dependency.ASM, Dependency.ASM_COMMONS, Dependency.JAR_RELOCATOR);
|
||||||
|
private static final String JAR_RELOCATOR_CLASS = "me.lucko.jarrelocator.JarRelocator";
|
||||||
|
private static final String JAR_RELOCATOR_RUN_METHOD = "run";
|
||||||
|
|
||||||
|
private final Constructor<?> jarRelocatorConstructor;
|
||||||
|
private final Method jarRelocatorRunMethod;
|
||||||
|
|
||||||
|
public RelocationHandler(DependencyManager dependencyManager) {
|
||||||
|
ClassLoader classLoader = null;
|
||||||
|
try {
|
||||||
|
// download the required dependencies for remapping
|
||||||
|
dependencyManager.loadDependencies(DEPENDENCIES);
|
||||||
|
// get a classloader containing the required dependencies as sources
|
||||||
|
classLoader = dependencyManager.obtainClassLoaderWith(DEPENDENCIES);
|
||||||
|
|
||||||
|
// load the relocator class
|
||||||
|
Class<?> jarRelocatorClass = classLoader.loadClass(JAR_RELOCATOR_CLASS);
|
||||||
|
|
||||||
|
// prepare the reflected constructor & method instances
|
||||||
|
this.jarRelocatorConstructor = jarRelocatorClass.getDeclaredConstructor(File.class, File.class, Map.class);
|
||||||
|
this.jarRelocatorConstructor.setAccessible(true);
|
||||||
|
|
||||||
|
this.jarRelocatorRunMethod = jarRelocatorClass.getDeclaredMethod(JAR_RELOCATOR_RUN_METHOD);
|
||||||
|
this.jarRelocatorRunMethod.setAccessible(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
if (classLoader instanceof IsolatedClassLoader) {
|
||||||
|
((IsolatedClassLoader) classLoader).close();
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
e.addSuppressed(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remap(Path input, Path output, List<Relocation> relocations) throws Exception {
|
||||||
|
Map<String, String> mappings = new HashMap<>();
|
||||||
|
for (Relocation relocation : relocations) {
|
||||||
|
mappings.put(relocation.getPattern(), relocation.getRelocatedPattern());
|
||||||
|
}
|
||||||
|
|
||||||
|
// create and invoke a new relocator
|
||||||
|
Object relocator = this.jarRelocatorConstructor.newInstance(input.toFile(), output.toFile(), mappings);
|
||||||
|
this.jarRelocatorRunMethod.invoke(relocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
package dev.xhyrom.lighteco.common.plugin.scheduler;
|
package dev.xhyrom.lighteco.common.plugin.scheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public interface SchedulerAdapter {
|
public interface SchedulerAdapter {
|
||||||
|
Executor async();
|
||||||
|
|
||||||
SchedulerTask asyncLater(Runnable runnable, long delay, TimeUnit unit);
|
SchedulerTask asyncLater(Runnable runnable, long delay, TimeUnit unit);
|
||||||
|
|
||||||
SchedulerTask asyncRepeating(Runnable runnable, long interval, TimeUnit unit);
|
SchedulerTask asyncRepeating(Runnable runnable, long interval, TimeUnit unit);
|
||||||
|
|
Loading…
Reference in a new issue