More attempts at fixing the wrapper (also get rid of slf4j)
This commit is contained in:
parent
f1d1979977
commit
c7aafad507
|
@ -28,8 +28,7 @@ println("Using Inceptum Build Script $version")
|
|||
|
||||
val lwjglVersion by extra("3.3.1")
|
||||
val imguiVersion by extra("1.86.4")
|
||||
val logbackVersion by extra("1.3.0-alpha15")
|
||||
val jfCommonsVersion by extra("2022.9.4+14-8-34")
|
||||
val jfCommonsVersion by extra("2022.9.6+19-13-24")
|
||||
val jgitVersion by extra("6.2.0.202206071550-r")
|
||||
val flavorProp: String by extra(if (project.hasProperty("flavor")) "${project.property("flavor")}" else "custom")
|
||||
if (flavorProp != "custom" && flavorProp != "maven" && flavorProp != "fat" && flavorProp != "windows" && flavorProp != "linux" && flavorProp != "macos")
|
||||
|
|
|
@ -5,8 +5,6 @@ plugins {
|
|||
dependencies {
|
||||
api("io.gitlab.jfronny:commons:${rootProject.extra["jfCommonsVersion"]}")
|
||||
api("io.gitlab.jfronny:commons-gson:${rootProject.extra["jfCommonsVersion"]}")
|
||||
implementation("io.gitlab.jfronny:commons-slf4j:${rootProject.extra["jfCommonsVersion"]}")
|
||||
implementation("ch.qos.logback:logback-classic:${rootProject.extra["logbackVersion"]}")
|
||||
}
|
||||
|
||||
val javaVersion by extra(project.java.targetCompatibility)
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
package io.gitlab.jfronny.inceptum.common;
|
||||
|
||||
import io.gitlab.jfronny.commons.HttpUtils;
|
||||
import io.gitlab.jfronny.commons.log.Logger;
|
||||
import io.gitlab.jfronny.commons.log.StdoutLogger;
|
||||
import io.gitlab.jfronny.commons.serialize.gson.api.GsonHolder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class InceptumEnvironmentInitializer {
|
||||
public static void initialize() throws IOException {
|
||||
Logger.registerFactory(InceptumEnvironmentInitializer::defaultFactory);
|
||||
HttpUtils.setUserAgent("jfmods/inceptum/" + BuildMetadata.VERSION);
|
||||
GsonHolder.register();
|
||||
ConfigHolder.load();
|
||||
}
|
||||
|
||||
public static Logger defaultFactory(String name) {
|
||||
return new StdoutLogger(name, true, true, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum.common;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class MapAppender extends AppenderBase<ILoggingEvent> {
|
||||
public static final ConcurrentMap<String, ILoggingEvent> EVENT_MAP = new ConcurrentHashMap<>();
|
||||
public static final Set<String> LOG = new LinkedHashSet<>();
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent event) {
|
||||
EVENT_MAP.put(Instant.now().toString(), event);
|
||||
|
||||
LOG.add(event.getLevel().toString() +
|
||||
" | " +
|
||||
Instant.now().toString() +
|
||||
" | [" +
|
||||
event.getThreadName() +
|
||||
"] " +
|
||||
event.getFormattedMessage());
|
||||
}
|
||||
}
|
|
@ -7,8 +7,7 @@ import io.gitlab.jfronny.inceptum.common.api.GitlabApi;
|
|||
import io.gitlab.jfronny.inceptum.common.api.MavenApi;
|
||||
import io.gitlab.jfronny.inceptum.common.model.gitlab.*;
|
||||
import io.gitlab.jfronny.inceptum.common.model.inceptum.*;
|
||||
import io.gitlab.jfronny.inceptum.common.model.maven.MavenDependency;
|
||||
import io.gitlab.jfronny.inceptum.common.model.maven.Pom;
|
||||
import io.gitlab.jfronny.inceptum.common.model.maven.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
|
@ -48,15 +47,16 @@ public class Updater {
|
|||
|
||||
WrapperConfig config = new WrapperConfig();
|
||||
config.natives = new HashMap<>();
|
||||
config.libraries = new LinkedList<>();
|
||||
config.repositories = new LinkedList<>(source.repositories);
|
||||
source.natives.forEach((k, v) -> config.natives.put(k, new LinkedList<>(v)));
|
||||
config.libraries = new LinkedHashSet<>();
|
||||
config.repositories = new LinkedHashSet<>(source.repositories);
|
||||
source.natives.forEach((k, v) -> config.natives.put(k, new LinkedHashSet<>(v)));
|
||||
|
||||
downloadLibrary(source.repositories, "io.gitlab.jfronny.inceptum:launcher-dist:" + source.version, config.libraries);
|
||||
DependencyNode node = downloadLibrary(source.repositories, "io.gitlab.jfronny.inceptum:launcher-dist:" + source.version, config.libraries);
|
||||
Utils.LOGGER.info("Downloaded Dependencies:\n" + node);
|
||||
|
||||
List<String> currentLibraries = new LinkedList<>(config.libraries);
|
||||
if (source.natives.containsKey(Utils.getCurrentFlavor())) {
|
||||
List<String> natives = new LinkedList<>();
|
||||
Set<String> natives = new LinkedHashSet<>();
|
||||
for (String lib : source.natives.get(Utils.getCurrentFlavor())){
|
||||
downloadLibrary(source.repositories, lib, natives);
|
||||
}
|
||||
|
@ -83,10 +83,10 @@ public class Updater {
|
|||
}
|
||||
|
||||
public static List<Path> getLaunchClasspath(WrapperConfig wrapperConfig) throws IOException, URISyntaxException {
|
||||
List<String> natives = wrapperConfig.natives.get(Utils.getCurrentFlavor());
|
||||
if (natives == null) natives = new LinkedList<>();
|
||||
List<String> libs = wrapperConfig.libraries;
|
||||
if (libs == null) libs = new LinkedList<>();
|
||||
Set<String> natives = wrapperConfig.natives.get(Utils.getCurrentFlavor());
|
||||
if (natives == null) natives = new LinkedHashSet<>();
|
||||
Set<String> libs = wrapperConfig.libraries;
|
||||
if (libs == null) libs = new LinkedHashSet<>();
|
||||
|
||||
boolean configChanged = false;
|
||||
|
||||
|
@ -114,7 +114,7 @@ public class Updater {
|
|||
return libraries.map(Updater::artifactToPath);
|
||||
}
|
||||
|
||||
private static void downloadLibrary(List<String> repositories, final String artifact, List<String> libraries) throws IOException, URISyntaxException {
|
||||
private static DependencyNode downloadLibrary(Set<String> repositories, final String artifact, Set<String> libraries) throws IOException, URISyntaxException {
|
||||
List<Exception> exceptions = new LinkedList<>();
|
||||
for (String repository : Stream.concat(Stream.of(PROJECT_MAVEN), repositories.stream()).toList()) {
|
||||
Pom pom;
|
||||
|
@ -124,15 +124,16 @@ public class Updater {
|
|||
exceptions.add(new Exception("Could not download artifact from " + repository, e));
|
||||
continue;
|
||||
}
|
||||
Set<DependencyNode> dependencies = new LinkedHashSet<>();
|
||||
if (pom.dependencies != null) {
|
||||
for (MavenDependency dependency : pom.dependencies) {
|
||||
String mvnName = dependency.groupId + ":" + dependency.artifactId + ":" + dependency.version;
|
||||
downloadLibrary(repositories, mvnName, libraries);
|
||||
dependencies.add(downloadLibrary(repositories, mvnName, libraries));
|
||||
}
|
||||
}
|
||||
MavenApi.downloadLibrary(repository, artifact);
|
||||
libraries.add(artifact);
|
||||
return;
|
||||
return new DependencyNode(pom, dependencies);
|
||||
}
|
||||
IOException exception = new IOException("Could not find any repository containing the artifact " + artifact + " (searched: " + String.join(", ", repositories) + ")");
|
||||
for (Exception e : exceptions) {
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.*;
|
|||
|
||||
public class MavenApi {
|
||||
private static final DocumentBuilder FACTORY;
|
||||
private static final Set<String> RUNTIME_SCOPES = Set.of("compile", "runtime");
|
||||
|
||||
static {
|
||||
try {
|
||||
|
@ -127,7 +128,7 @@ public class MavenApi {
|
|||
case "scope" -> {
|
||||
hasScope = true;
|
||||
result.scope = node.getTextContent();
|
||||
if (!result.scope.equals("runtime")) return null;
|
||||
if (!RUNTIME_SCOPES.contains(result.scope)) return null;
|
||||
}
|
||||
case "optional" -> {
|
||||
if (node.getTextContent().equals("true")) return null;
|
||||
|
@ -142,14 +143,16 @@ public class MavenApi {
|
|||
// The required modules are explicit dependencies of launcher-imgui anyway
|
||||
return null;
|
||||
}
|
||||
throw new IOException("Pom lacks version");
|
||||
throw new IOException("Dependency " + result.groupId + ":" + result.artifactId + " lacks version");
|
||||
}
|
||||
if (!hasScope) throw new IOException("Pom lacks scope");
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(Node node) {
|
||||
return node.getNodeType() == Node.TEXT_NODE && node.getTextContent().isBlank();
|
||||
if (node.getNodeType() == Node.TEXT_NODE && node.getTextContent().isBlank()) return true;
|
||||
if (node.getNodeType() == Node.COMMENT_NODE) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Iterable<Node> iterable(NodeList list) {
|
||||
|
|
|
@ -2,8 +2,7 @@ package io.gitlab.jfronny.inceptum.common.model.inceptum;
|
|||
|
||||
import io.gitlab.jfronny.commons.ComparableVersion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class UpdateMetadata {
|
||||
public Integer wrapperVersion;
|
||||
|
@ -11,6 +10,6 @@ public class UpdateMetadata {
|
|||
public Boolean isPublic;
|
||||
public Boolean isRelease;
|
||||
public Integer jvm;
|
||||
public List<String> repositories;
|
||||
public Map<String, List<String>> natives;
|
||||
public Set<String> repositories;
|
||||
public Map<String, Set<String>> natives;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package io.gitlab.jfronny.inceptum.common.model.inceptum;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class WrapperConfig {
|
||||
public List<String> libraries;
|
||||
public List<String> repositories;
|
||||
public Map<String, List<String>> natives;
|
||||
public Set<String> libraries;
|
||||
public Set<String> repositories;
|
||||
public Map<String, Set<String>> natives;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
package io.gitlab.jfronny.inceptum.common.model.maven;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class DependencyNode {
|
||||
private final String name;
|
||||
private final Set<DependencyNode> dependencies;
|
||||
|
||||
public DependencyNode(Pom pom, Set<DependencyNode> dependencies) {
|
||||
Objects.requireNonNull(pom);
|
||||
this.name = pom.groupId + ":" + pom.artifactId + ":" + pom.version;
|
||||
this.dependencies = Objects.requireNonNull(dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DependencyNode that = (DependencyNode) o;
|
||||
return name.equals(that.name) && dependencies.equals(that.dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, dependencies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
generateTree(sb, "", "");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void generateTree(StringBuilder sb, String prefix, String childrenPrefix) {
|
||||
sb.append(prefix).append(name).append('\n');
|
||||
for (Iterator<DependencyNode> it = dependencies.iterator(); it.hasNext();) {
|
||||
DependencyNode next = it.next();
|
||||
if (it.hasNext()) {
|
||||
next.generateTree(sb, childrenPrefix + "├── ", childrenPrefix + "│ ");
|
||||
} else {
|
||||
next.generateTree(sb, childrenPrefix + "└── ", childrenPrefix + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration debug="false">
|
||||
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<pattern>%d{HH:mm:ss.SSS} %boldCyan(%thread) %boldGreen(%logger{0}) %highlight(%level) %msg%n</pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>inceptum.log</file>
|
||||
<append>false</append>
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<pattern>%d{HH:mm:ss.SSS} %thread %logger{0} %level %msg%n</pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<appender name="MEMORY" class="io.gitlab.jfronny.inceptum.common.MapAppender">
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
<appender-ref ref="MEMORY"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -6,6 +6,7 @@ import imgui.flag.ImGuiConfigFlags;
|
|||
import imgui.gl3.ImGuiImplGl3;
|
||||
import imgui.glfw.ImGuiImplGlfw;
|
||||
import io.gitlab.jfronny.commons.io.JFiles;
|
||||
import io.gitlab.jfronny.commons.log.*;
|
||||
import io.gitlab.jfronny.inceptum.common.model.inceptum.UpdateMetadata;
|
||||
import io.gitlab.jfronny.inceptum.imgui.window.MainWindow;
|
||||
import io.gitlab.jfronny.inceptum.launcher.LauncherEnv;
|
||||
|
@ -29,6 +30,7 @@ import java.nio.file.Files;
|
|||
import java.util.*;
|
||||
|
||||
public class GuiMain {
|
||||
public static final MemoryLogger MEMLOG = new MemoryLogger("Inceptum");
|
||||
public static final Set<Window> WINDOWS = new LinkedHashSet<>();
|
||||
private static final ImGuiImplGlfw imGuiGlfw = new ImGuiImplGlfw();
|
||||
private static final ImGuiImplGl3 imGuiGl3 = new ImGuiImplGl3();
|
||||
|
@ -40,9 +42,9 @@ public class GuiMain {
|
|||
|
||||
public static void main(String[] args) throws IOException {
|
||||
LauncherEnv.checkClassLoaderState();
|
||||
LauncherEnv.initialize(new GuiEnvBackend());
|
||||
Utils.LOGGER.info("Launching Inceptum v" + BuildMetadata.VERSION);
|
||||
Utils.LOGGER.info("Loading from " + MetaHolder.BASE_PATH);
|
||||
LauncherEnv.initialize(new GuiEnvBackend());
|
||||
try {
|
||||
main();
|
||||
} finally {
|
||||
|
@ -51,6 +53,7 @@ public class GuiMain {
|
|||
}
|
||||
|
||||
public static void main() {
|
||||
Logger.registerFactory(name -> new CompoundLogger(name, InceptumEnvironmentInitializer.defaultFactory(name), MEMLOG));
|
||||
UpdateMetadata update = BuildMetadata.IS_PUBLIC ? Updater.getUpdate() : null;
|
||||
AccountManager.loadAccounts();
|
||||
Utils.LOGGER.info("Initializing UI");
|
||||
|
|
|
@ -5,9 +5,9 @@ import imgui.ImGui;
|
|||
import java.util.Set;
|
||||
|
||||
public class LogWindow extends Window {
|
||||
private final Set<String> source;
|
||||
private final Iterable<String> source;
|
||||
|
||||
public LogWindow(Set<String> source) {
|
||||
public LogWindow(Iterable<String> source) {
|
||||
super("Log");
|
||||
this.source = source;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ public class MainWindow extends Window {
|
|||
}
|
||||
if (ImGui.beginMenu("Help")) {
|
||||
if (ImGui.menuItem("About")) GuiMain.open(new AboutWindow());
|
||||
if (ImGui.menuItem("Log")) GuiMain.open(new LogWindow(MapAppender.LOG));
|
||||
if (ImGui.menuItem("Log")) GuiMain.open(new LogWindow(GuiMain.MEMLOG));
|
||||
ImGui.checkbox("Debug Tools", debugTools);
|
||||
ImGui.endMenu();
|
||||
}
|
||||
|
|
|
@ -3,9 +3,11 @@ plugins {
|
|||
}
|
||||
|
||||
application {
|
||||
mainClass.set("io.gitlab.jfronny.inceptum.WrapperStrap")
|
||||
mainClass.set("io.gitlab.jfronny.inceptum.wrapper.Wrapper")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":common"))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.runShadow.get().workingDir = rootProject.projectDir
|
|
@ -1,40 +0,0 @@
|
|||
package io.gitlab.jfronny.inceptum;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
|
||||
public class WrapperStrap {
|
||||
public static final ClassLoader SYSTEM_LOADER = ClassLoader.getSystemClassLoader();
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, URISyntaxException {
|
||||
System.out.println("Starting Inceptum Wrapper ClassLoader");
|
||||
bootstrap(Set.of(new File(WrapperStrap.class.getProtectionDomain().getCodeSource().getLocation().toURI()).toPath()),
|
||||
"io.gitlab.jfronny.inceptum.Wrapper",
|
||||
args);
|
||||
}
|
||||
|
||||
public static void bootstrap(Iterable<Path> jars, String mainClass, String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, URISyntaxException {
|
||||
try (WrapperClassLoader loader = new WrapperClassLoader(jars, SYSTEM_LOADER)) {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
wrapperInit(loader);
|
||||
loader.loadClass(mainClass)
|
||||
.getDeclaredMethod("main", String[].class)
|
||||
.invoke(null, new Object[]{args});
|
||||
}
|
||||
}
|
||||
|
||||
private static void wrapperInit(ClassLoader loader) {
|
||||
try {
|
||||
loader.loadClass("io.gitlab.jfronny.inceptum.common.Utils")
|
||||
.getMethod("wrapperInit", ClassLoader.class)
|
||||
.invoke(null, SYSTEM_LOADER);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("Could not perform wrapper init, utils class probably moved");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum;
|
||||
package io.gitlab.jfronny.inceptum.wrapper;
|
||||
|
||||
import io.gitlab.jfronny.commons.io.JFiles;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -7,21 +7,24 @@ import java.io.Closeable;
|
|||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.nio.file.*;
|
||||
import java.security.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class WrapperClassLoader extends ClassLoader implements Closeable {
|
||||
/**
|
||||
* A ClassLoader that supports loading classes from Paths, which may be directories or jars
|
||||
* Does not support modules
|
||||
*/
|
||||
public class NioClassLoader extends ClassLoader implements Closeable {
|
||||
private final Set<Path> sources = new LinkedHashSet<>();
|
||||
private final Set<Closeable> closeables = new HashSet<>();
|
||||
private final ClassLoader parent;
|
||||
|
||||
static {
|
||||
registerAsParallelCapable();
|
||||
}
|
||||
|
||||
public WrapperClassLoader(Iterable<Path> jars, ClassLoader parent) throws IOException, URISyntaxException {
|
||||
super(null);
|
||||
this.parent = parent;
|
||||
public NioClassLoader(Iterable<Path> jars, ClassLoader parent) throws IOException, URISyntaxException {
|
||||
super(parent);
|
||||
for (Path jar : jars) {
|
||||
if (Files.isDirectory(jar)) {
|
||||
sources.add(jar);
|
||||
|
@ -35,44 +38,31 @@ public class WrapperClassLoader extends ClassLoader implements Closeable {
|
|||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
Path path = findClassSource(name);
|
||||
if (path == null) return parent.loadClass(name);
|
||||
Path path = findSource(name.replace('.', '/') + ".class");
|
||||
if (path == null) throw new ClassNotFoundException(name);
|
||||
byte[] clazz;
|
||||
try {
|
||||
clazz = Files.readAllBytes(path);
|
||||
} catch (IOException e) {
|
||||
throw new ClassNotFoundException("Could not find class", e);
|
||||
throw new ClassNotFoundException(name, e);
|
||||
}
|
||||
return defineClass(name, clazz, 0, clazz.length);
|
||||
CodeSource cs = new CodeSource(toUrl(path), (Certificate[]) null);
|
||||
ProtectionDomain pd = new ProtectionDomain(cs, null);
|
||||
return defineClass(name, clazz, 0, clazz.length, pd);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
if (findClassSource(name) == null || name.equals("io.gitlab.jfronny.inceptum.WrapperStrap"))
|
||||
return parent.loadClass(name);
|
||||
synchronized (this.getClassLoadingLock(name)) {
|
||||
Class<?> c = this.findLoadedClass(name);
|
||||
if (c == null) c = this.findClass(name);
|
||||
if (resolve) this.resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String name) {
|
||||
Path p = findSource(name);
|
||||
if (p == null) return parent.getResource(name);
|
||||
return toUrl(p);
|
||||
protected URL findResource(String name) {
|
||||
return toUrl(findSource(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Enumeration<URL> findResources(String name) {
|
||||
Stream<URL> resources = findPaths(name).map(this::toUrl);
|
||||
resources = Stream.concat(resources, parent.resources(name));
|
||||
return Collections.enumeration(resources.toList());
|
||||
return Collections.enumeration(findPaths(name).map(this::toUrl).toList());
|
||||
}
|
||||
|
||||
private URL toUrl(Path path) {
|
||||
if (path == null) return null;
|
||||
try {
|
||||
return path.toUri().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
|
@ -80,10 +70,6 @@ public class WrapperClassLoader extends ClassLoader implements Closeable {
|
|||
}
|
||||
}
|
||||
|
||||
private @Nullable Path findClassSource(String className) {
|
||||
return findSource(className.replace('.', '/') + ".class");
|
||||
}
|
||||
|
||||
private @Nullable Path findSource(String path) {
|
||||
return findPaths(path).findFirst().orElse(null);
|
||||
}
|
||||
|
@ -93,9 +79,21 @@ public class WrapperClassLoader extends ClassLoader implements Closeable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
public void close() {
|
||||
List<IOException> exceptions = new LinkedList<>();
|
||||
for (Closeable closeable : closeables) {
|
||||
closeable.close();
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (IOException e) {
|
||||
exceptions.add(e);
|
||||
}
|
||||
}
|
||||
if (!exceptions.isEmpty()) {
|
||||
RuntimeException ex = new RuntimeException("Could not properly close WrapperClassLoader");
|
||||
for (IOException suppressed : exceptions) {
|
||||
ex.addSuppressed(suppressed);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package io.gitlab.jfronny.inceptum.wrapper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public final class RuntimeEnv implements Runnable {
|
||||
public static void start(Iterable<Path> jars, String mainClass, String[] args) throws IOException, URISyntaxException {
|
||||
NioClassLoader loader = new NioClassLoader(jars, ClassLoader.getPlatformClassLoader());
|
||||
Thread th = new Thread(new RuntimeEnv(loader, mainClass, args), getThreadName(mainClass));
|
||||
th.setContextClassLoader(loader);
|
||||
th.start();
|
||||
}
|
||||
|
||||
private static String getThreadName(String className) {
|
||||
String[] split = className.split("\\.");
|
||||
return "[WS/" + split[split.length - 1] + "]";
|
||||
}
|
||||
|
||||
private final NioClassLoader loader;
|
||||
private final String mainClass;
|
||||
private final String[] args;
|
||||
private boolean ran = false;
|
||||
|
||||
private RuntimeEnv(NioClassLoader loader, String mainClass, String[] args) {
|
||||
this.loader = loader;
|
||||
this.mainClass = mainClass;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void run() {
|
||||
if (ran) throw new IllegalStateException("Attempted to run environment which already finished executing");
|
||||
ran = true;
|
||||
try {
|
||||
wrapperInit();
|
||||
try {
|
||||
loader.loadClass(mainClass)
|
||||
.getDeclaredMethod("main", String[].class)
|
||||
.invoke(null, new Object[]{args});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} finally {
|
||||
loader.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void wrapperInit() {
|
||||
try {
|
||||
loader.loadClass("io.gitlab.jfronny.inceptum.common.Utils")
|
||||
.getMethod("wrapperInit", ClassLoader.class)
|
||||
.invoke(null, ClassLoader.getSystemClassLoader());
|
||||
} catch (Throwable e) {
|
||||
System.out.println("Could not perform wrapper init, utils class probably moved");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.gitlab.jfronny.inceptum;
|
||||
package io.gitlab.jfronny.inceptum.wrapper;
|
||||
|
||||
import io.gitlab.jfronny.commons.ComparableVersion;
|
||||
import io.gitlab.jfronny.commons.io.JFiles;
|
||||
|
@ -6,7 +6,6 @@ import io.gitlab.jfronny.inceptum.common.*;
|
|||
import io.gitlab.jfronny.inceptum.common.model.inceptum.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -14,30 +13,25 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class Wrapper {
|
||||
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, URISyntaxException {
|
||||
public static void main(String[] args) throws IOException, URISyntaxException {
|
||||
System.out.println("Inceptum Wrapper v" + BuildMetadata.VERSION);
|
||||
System.out.println("Loading from " + MetaHolder.BASE_PATH);
|
||||
InceptumEnvironmentInitializer.initialize();
|
||||
List<Path> classpath = getClasspath();
|
||||
if (!BuildMetadata.IS_RELEASE) {
|
||||
System.out.println("Using classpath: " + classpath.stream().map(Path::toString).collect(Collectors.joining("" + File.pathSeparator)));
|
||||
}
|
||||
System.out.println("Starting Inceptum ClassLoader");
|
||||
WrapperStrap.bootstrap(classpath,
|
||||
"io.gitlab.jfronny.inceptum.Inceptum",
|
||||
args);
|
||||
}
|
||||
|
||||
private static List<Path> getClasspath() throws IOException, URISyntaxException {
|
||||
if (!Files.exists(MetaHolder.WRAPPER_CONFIG_PATH)) {
|
||||
UpdateMetadata update = Updater.check(UpdateChannel.Stable, new ComparableVersion("0"), R::nop);
|
||||
if (update == null) {
|
||||
throw new FileNotFoundException("Could not identify a valid inceptum version. Are you connected to the internet?");
|
||||
}
|
||||
Updater.update(update, false);
|
||||
if (!Files.exists(MetaHolder.WRAPPER_CONFIG_PATH))
|
||||
if (!Files.exists(MetaHolder.WRAPPER_CONFIG_PATH)) {
|
||||
throw new FileNotFoundException("Something went wrong while downloading the latest version.");
|
||||
}
|
||||
}
|
||||
return Updater.getLaunchClasspath(JFiles.readObject(MetaHolder.WRAPPER_CONFIG_PATH, WrapperConfig.class));
|
||||
List<Path> classpath = Updater.getLaunchClasspath(JFiles.readObject(MetaHolder.WRAPPER_CONFIG_PATH, WrapperConfig.class));
|
||||
if (!BuildMetadata.IS_RELEASE) {
|
||||
System.out.println("Using classpath: " + classpath.stream().map(Path::toString).collect(Collectors.joining("" + File.pathSeparator)));
|
||||
}
|
||||
System.out.println("Starting Inceptum ClassLoader");
|
||||
RuntimeEnv.start(classpath, "io.gitlab.jfronny.inceptum.Inceptum", args);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue