Skip to content

Commit f701e05

Browse files
committed
More work done...
1 parent a6699f2 commit f701e05

5 files changed

Lines changed: 278 additions & 279 deletions

File tree

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ plugins {
2525
apply plugin: 'maven-publish'
2626

2727
group = 'org.mangorage'
28-
version = getLatestGitTag() + "." + getLatestGitVersion()
28+
version = getLatestGitTag() + "." + getLatestGitVersion() + "-beta.10"
2929

3030
println("Version -> " + version)
3131

src/main/java/module-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
requires jdk.unsupported;
33

44
exports org.mangorage.bootstrap;
5-
uses org.mangorage.bootstrap.Bootstrap;
5+
uses Bootstrap;
66
}
Lines changed: 34 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -1,243 +1,59 @@
11
package org.mangorage.bootstrap;
22

3-
import java.io.IOException;
4-
import java.lang.ModuleLayer;
5-
import java.lang.module.Configuration;
6-
import java.lang.module.ModuleFinder;
7-
import java.lang.module.ModuleReference;
3+
import java.io.File;
84
import java.lang.reflect.Method;
95
import java.net.MalformedURLException;
10-
import java.net.URI;
116
import java.net.URL;
127
import java.net.URLClassLoader;
13-
import java.nio.file.Files;
14-
import java.nio.file.Path;
15-
import java.nio.file.Paths;
168
import java.util.ArrayList;
17-
import java.util.HashSet; // Added for HashSet
189
import java.util.List;
19-
import java.util.Optional;
20-
import java.util.Set; // Added for Set
21-
import java.util.stream.Collectors;
22-
import java.util.stream.Stream;
2310

24-
public final class Bootstrap {
25-
26-
public static void main(String[] args) throws Exception {
27-
Path librariesDir = Paths.get("libraries");
28-
Path pluginsDir = Paths.get("plugins");
11+
public class Bootstrap {
12+
public static void initOld(final String[] args) {
13+
URLClassLoader CL_libraries = new URLClassLoader(fetchJars(new File[]{new File("libraries")}), Thread.currentThread().getContextClassLoader().getParent());
14+
URLClassLoader cl = new URLClassLoader(fetchJars(new File[]{new File("plugins")}), CL_libraries);
15+
Thread.currentThread().setContextClassLoader(cl);
16+
callMain("org.mangorage.entrypoint.MangoBotCore", args, cl);
17+
}
2918

30-
// Ensure directories exist
31-
ensureDirectoryExists(librariesDir);
32-
ensureDirectoryExists(pluginsDir);
19+
public static URL[] fetchJars(File[] directories) {
20+
// Add your extra folder here, you glutton for suffering
3321

34-
// --- Step 1: Prepare Library Paths ---
35-
List<Path> libraryJarPaths = listJarFiles(librariesDir);
36-
if (libraryJarPaths.isEmpty()) {
37-
System.out.println("No library JARs found in " + librariesDir.toAbsolutePath());
38-
// Decide if this is acceptable or an error
39-
}
22+
List<URL> urls = new ArrayList<>();
4023

41-
// --- FIX START: Explicitly define problematic Library JARs to exclude from ModuleFinder ---
42-
// List JARs that should be treated as non-modular classpath JARs ONLY,
43-
// even if they are in the libraries directory.
44-
// Add 'libraries/luaj-jse-3.0.1.jar' as it caused the InvalidModuleDescriptorException.
45-
Set<Path> nonModularOnlyLibJars = new HashSet<>();
46-
nonModularOnlyLibJars.add(librariesDir.resolve("luaj-jse-3.0.1.jar"));
47-
// Add any other Library JARs here that cause similar module descriptor errors.
48-
// nonModularOnlyLibJars.add(librariesDir.resolve("another-problematic-lib.jar"));
24+
for (File dir : directories) {
25+
if (!dir.exists() || !dir.isDirectory()) continue;
4926

50-
List<Path> modularCandidateLibJarPaths = libraryJarPaths.stream()
51-
.filter(p -> !nonModularOnlyLibJars.contains(p))
52-
.collect(Collectors.toList());
27+
File[] jarFiles = dir.listFiles((d, name) -> name.endsWith(".jar"));
28+
if (jarFiles == null) continue;
5329

54-
nonModularOnlyLibJars.forEach(p -> {
55-
if (libraryJarPaths.contains(p)) {
56-
System.out.println("Explicitly excluding library " + p.getFileName() + " from Library ModuleFinder.");
57-
} else {
58-
System.err.println("Warning: Problematic Library JAR listed for exclusion (" + p.getFileName() + ") was not found in the libraries directory.");
30+
for (File jar : jarFiles) {
31+
try {
32+
urls.add(jar.toURI().toURL());
33+
} catch (MalformedURLException e) {
34+
throw new RuntimeException("Malformed URL while processing: " + jar.getAbsolutePath(), e);
35+
}
5936
}
60-
});
61-
// --- FIX END ---
62-
63-
64-
// --- Step 2: Create Library ClassLoader ---
65-
// Simple approach: Put ALL library JARs (including the problematic ones) into one ClassLoader.
66-
// Modular JARs will be found by the ModuleFinder later.
67-
// Non-modular JARs will be on the classpath (unnamed module) of this loader.
68-
ClassLoader libraryClassLoader = createUrlClassLoader("LibraryLoader", libraryJarPaths, ClassLoader.getSystemClassLoader()); // Use the original list
69-
System.out.println("Library ClassLoader parent: " + (libraryClassLoader.getParent() != null ? libraryClassLoader.getParent().getName() : "null"));
70-
71-
72-
// --- Step 3: Find Library Modules ---
73-
// This finder scans ONLY the candidate modular library JARs.
74-
ModuleFinder libFinder = ModuleFinder.of(modularCandidateLibJarPaths.toArray(Path[]::new)); // Use the filtered list
75-
Set<ModuleReference> libModuleRefs = libFinder.findAll(); // Should succeed now
76-
Set<String> libModuleNames = getModuleNames(libModuleRefs);
77-
System.out.println("Found Library Modules: " + libModuleNames);
78-
79-
80-
// --- Step 4: Define Library Layer ---
81-
// Resolve the found library modules against the boot layer.
82-
Configuration libConfig = ModuleLayer.boot()
83-
.configuration()
84-
.resolve(libFinder, ModuleFinder.of(), libModuleNames);
85-
86-
// Define the layer using the resolved configuration and the library classloader.
87-
ModuleLayer libLayer = ModuleLayer.boot().defineModulesWithOneLoader(libConfig, libraryClassLoader);
88-
System.out.println("Library Layer Defined.");
89-
90-
91-
// --- Step 5: Prepare Plugin Paths ---
92-
List<Path> pluginJarPaths = listJarFiles(pluginsDir);
93-
if (pluginJarPaths.isEmpty()) {
94-
System.out.println("No plugins found in " + pluginsDir.toAbsolutePath() + ". Exiting.");
95-
return; // Exit if no plugins are present (adjust as needed)
9637
}
9738

98-
// --- Step 6: Create Plugin ClassLoader ---
99-
// Simple approach: Put ALL plugin JARs into one ClassLoader.
100-
// Its parent is the Library ClassLoader, allowing plugins to see libraries (both modular and non-modular).
101-
ClassLoader pluginClassLoader = createUrlClassLoader("PluginLoader", pluginJarPaths, libraryClassLoader);
102-
System.out.println("Plugin ClassLoader parent: " + (pluginClassLoader.getParent() != null ? pluginClassLoader.getParent().getName() : "null"));
103-
104-
105-
// --- Step 7: Find Plugin Modules ---
106-
// This finder scans all plugin JARs to find explicit or automatic modules.
107-
// If any plugin JARs cause InvalidModuleDescriptorException, you might need
108-
// to add similar exclusion logic for plugins as done for libraries.
109-
ModuleFinder pluginFinder = ModuleFinder.of(pluginJarPaths.toArray(Path[]::new));
110-
Set<ModuleReference> pluginModuleRefs = pluginFinder.findAll();
111-
Set<String> pluginModuleNames = getModuleNames(pluginModuleRefs);
112-
System.out.println("Found Plugin Modules: " + pluginModuleNames);
113-
114-
115-
// --- Step 8: Resolve Plugin Configuration ---
116-
// Resolve plugin modules using the library layer's configuration as the parent.
117-
Configuration pluginConfig;
118-
try {
119-
pluginConfig = libLayer.configuration()
120-
.resolve(pluginFinder, ModuleFinder.of(), pluginModuleNames);
121-
} catch (Exception e) {
122-
System.err.println("Failed to resolve plugin module dependencies. Check plugin requirements and library modules.");
123-
e.printStackTrace();
124-
return;
125-
}
126-
127-
128-
// --- Step 9: Define Plugin Layer ---
129-
// Define the plugin layer using its resolved configuration and the plugin classloader.
130-
// It is layered ON TOP of the library layer.
131-
ModuleLayer pluginLayer = libLayer.defineModulesWithManyLoaders(pluginConfig, pluginClassLoader);
132-
System.out.println("Plugin Layer Defined.");
133-
134-
135-
// --- Step 10: Load and Execute Target Plugin Main Class ---
136-
// Hardcoded for the example, replace with dynamic discovery if needed
137-
String targetPluginModule = "org.mangorage.mangobotcore"; // Example module name
138-
String entrypointClass = "org.mangorage.entrypoint.MangoBotCore"; // Example entry point
139-
140-
Optional<Module> pluginModuleOptional = pluginLayer.findModule(targetPluginModule);
141-
142-
if (pluginModuleOptional.isEmpty()) {
143-
System.err.println("Target plugin module '" + targetPluginModule + "' not found in the plugin layer.");
144-
System.err.println("Available plugin modules: " + pluginLayer.modules().stream().map(Module::getName).collect(Collectors.toSet()));
145-
// If the entry point is in a non-modular JAR, you'd load it directly
146-
// from the pluginClassLoader here using Class.forName(entrypointClass, true, pluginClassLoader);
147-
// and invoke its main method if applicable.
148-
return;
149-
}
150-
151-
// Use the specific ClassLoader associated with the target plugin module
152-
// In this simple setup, it will be the main pluginClassLoader.
153-
ClassLoader targetPluginModuleLoader = pluginModuleOptional.get().getClassLoader();
154-
System.out.println("Target Plugin Module Loader: " + targetPluginModuleLoader.getName());
155-
156-
157-
// Set the ContextClassLoader - useful for many libraries
158-
Thread currentThread = Thread.currentThread();
159-
ClassLoader originalContextClassLoader = currentThread.getContextClassLoader();
160-
currentThread.setContextClassLoader(targetPluginModuleLoader);
39+
return urls.toArray(URL[]::new);
40+
}
16141

42+
public static void callMain(String className, String[] args, ClassLoader classLoader) {
16243
try {
163-
// Load the main plugin class using its specific ClassLoader
164-
Class<?> mainClass = Class.forName(entrypointClass, true, targetPluginModuleLoader);
165-
System.out.println("Loaded main plugin class: " + mainClass.getName() + " using loader: " + mainClass.getClassLoader().getName());
44+
Class<?> clazz = Class.forName(className, false, classLoader);
45+
Method mainMethod = clazz.getMethod("main", String[].class);
16646

167-
// Find and invoke the main method
168-
Method mainMethod = mainClass.getMethod("main", String[].class);
169-
170-
System.out.println("Invoking main method on " + entrypointClass + " in module " + targetPluginModule);
171-
mainMethod.invoke(null, (Object) new String[0]); // Pass empty args array
172-
System.out.println("Plugin execution finished successfully.");
173-
174-
} catch (ClassNotFoundException e) {
175-
System.err.println("Entry point class not found: " + entrypointClass + " using classloader for module " + targetPluginModule);
176-
e.printStackTrace();
177-
} catch (NoSuchMethodException e) {
178-
System.err.println("main(String[]) method not found in class: " + entrypointClass);
179-
e.printStackTrace();
180-
} catch (ReflectiveOperationException e) { // Catch broader reflection issues
181-
System.err.println("Error invoking main method in " + entrypointClass);
182-
e.printStackTrace(); // Often holds the actual exception from the plugin's main method
183-
if (e.getCause() != null) {
184-
System.err.println("Caused by:");
185-
e.getCause().printStackTrace();
47+
// Make sure it's static and public
48+
if (!java.lang.reflect.Modifier.isStatic(mainMethod.getModifiers())) {
49+
throw new IllegalStateException("Main method is not static, are you high?");
18650
}
187-
} catch (Exception e) { // Catch any other unexpected errors
188-
System.err.println("An unexpected error occurred during plugin execution.");
189-
e.printStackTrace();
190-
} finally {
191-
// Restore original TCCL
192-
currentThread.setContextClassLoader(originalContextClassLoader);
193-
System.out.println("Restored original Thread Context ClassLoader.");
194-
}
195-
}
196-
197-
// Helper to ensure a directory exists
198-
private static void ensureDirectoryExists(Path directory) throws IOException {
199-
if (!Files.exists(directory)) {
200-
System.out.println("Directory not found, creating: " + directory.toAbsolutePath());
201-
Files.createDirectories(directory);
202-
} else if (!Files.isDirectory(directory)) {
203-
throw new IOException("Path exists but is not a directory: " + directory.toAbsolutePath());
204-
}
205-
}
20651

207-
// Helper to list JAR files in a directory
208-
private static List<Path> listJarFiles(Path directory) throws IOException {
209-
if (!Files.isDirectory(directory)) {
210-
System.err.println("Warning: Directory not found or not a directory: " + directory.toAbsolutePath());
211-
return List.of(); // Return empty list
212-
}
213-
try (Stream<Path> stream = Files.list(directory)) {
214-
return stream
215-
.filter(path -> path.toString().toLowerCase().endsWith(".jar") && Files.isRegularFile(path))
216-
.collect(Collectors.toList());
52+
// Invoke the main method with a godawful cast
53+
mainMethod.invoke(null, (Object) args);
54+
} catch (Exception e) {
55+
e.printStackTrace();
56+
throw new RuntimeException("Couldn't reflectively call main because something exploded.", e);
21757
}
21858
}
219-
220-
// Helper to create a URLClassLoader with a name (for debugging)
221-
private static URLClassLoader createUrlClassLoader(String name, List<Path> jars, ClassLoader parent) {
222-
URL[] urls = jars.stream()
223-
.map(path -> {
224-
try {
225-
return path.toUri().toURL();
226-
} catch (MalformedURLException e) {
227-
throw new RuntimeException("Invalid JAR path URI: " + path, e);
228-
}
229-
})
230-
.toArray(URL[]::new);
231-
232-
// Create the URLClassLoader
233-
System.out.println("Creating URLClassLoader '" + name + "' with " + jars.size() + " JARs.");
234-
return new URLClassLoader(name, urls, parent);
235-
}
236-
237-
// Get module names from references
238-
private static Set<String> getModuleNames(Set<ModuleReference> refs) {
239-
return refs.stream()
240-
.map(ref -> ref.descriptor().name())
241-
.collect(Collectors.toSet());
242-
}
24359
}

0 commit comments

Comments
 (0)