diff --git a/boot/pom.xml b/boot/pom.xml
new file mode 100644
index 0000000..09316fa
--- /dev/null
+++ b/boot/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+
+ io.smallrye.modules
+ smallrye-modules-parent
+ 1.0.beta2-SNAPSHOT
+
+
+ smallrye-modules-boot
+
+ SmallRye Modules - Boot
+ Bootstrap shim for loading the SmallRye Modules runtime from a composite JAR
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+
+
+
+
+ maven-jar-plugin
+
+
+
+ io.smallrye.modules.boot.Boot
+
+
+
+
+
+
+
diff --git a/boot/src/main/java/io/smallrye/modules/boot/Boot.java b/boot/src/main/java/io/smallrye/modules/boot/Boot.java
new file mode 100644
index 0000000..1772f48
--- /dev/null
+++ b/boot/src/main/java/io/smallrye/modules/boot/Boot.java
@@ -0,0 +1,176 @@
+package io.smallrye.modules.boot;
+
+import static java.lang.invoke.MethodHandles.lookup;
+import static java.lang.invoke.MethodHandles.publicLookup;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.lang.module.Configuration;
+import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleReader;
+import java.lang.module.ModuleReference;
+import java.net.URI;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.security.CodeSource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Stream;
+
+/**
+ * Bootstrap entry point for loading the SmallRye Modules runtime from a
+ * composite JAR without placing any dependencies on the application module path.
+ *
+ * The bootstrap sequence:
+ *
+ *
Locate the composite JAR from the boot module's code source
+ *
Memory-map the entire JAR
+ *
Load the synthesized {@link JarIndex} implementation from the system class loader
+ *
Create a {@link BootClassLoader} backed by the mapped buffer
+ *
Build a JPMS {@link ModuleLayer} over the boot class loader
+ *
Transfer the {@code jdk.internal.module} export to the infrastructure module
+ *
Invoke the runtime's {@code Launcher.main}
+ *
+ */
+public final class Boot {
+
+ private Boot() {
+ }
+
+ /**
+ * Main entry point.
+ *
+ * @param args the command-line arguments, forwarded to the runtime launcher
+ * @throws Throwable if bootstrap fails
+ */
+ public static void main(String[] args) throws Throwable {
+ // 1. Locate the composite JAR from our own code source
+ CodeSource codeSource = Boot.class.getProtectionDomain().getCodeSource();
+ if (codeSource == null) {
+ throw new IllegalStateException("Cannot determine Boot code source location");
+ }
+ Path jarPath = Path.of(codeSource.getLocation().toURI());
+
+ // 2. Memory-map the entire file
+ ByteBuffer compositeBuffer;
+ try (FileChannel channel = FileChannel.open(jarPath, StandardOpenOption.READ)) {
+ compositeBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
+ }
+
+ // 3. Load the synthesized JarIndex from the system class loader
+ Class> indexClass = Class.forName("io.smallrye.modules.boot.JarIndexImpl", true,
+ ClassLoader.getSystemClassLoader());
+ JarIndex jarIndex = (JarIndex) indexClass.getDeclaredConstructor().newInstance();
+
+ // 4. Create boot class loader (reads module descriptors, builds package index — no classes loaded)
+ BootClassLoader bootCL = new BootClassLoader(compositeBuffer, jarIndex, null);
+
+ // 5. Build the infrastructure ModuleLayer
+ // 5a. Build a ModuleFinder from the index
+ Map moduleRefs = buildModuleReferences(compositeBuffer, jarIndex);
+ java.lang.module.ModuleFinder finder = new java.lang.module.ModuleFinder() {
+ @Override
+ public Optional find(String name) {
+ return Optional.ofNullable(moduleRefs.get(name));
+ }
+
+ @Override
+ public Set findAll() {
+ return Set.copyOf(moduleRefs.values());
+ }
+ };
+
+ // 5b. Resolve the configuration against the boot layer
+ Set roots = Set.copyOf(jarIndex.moduleNames());
+ Configuration cf = ModuleLayer.boot().configuration().resolve(
+ finder, java.lang.module.ModuleFinder.of(), roots);
+
+ // 5c. Define the module layer
+ ModuleLayer.Controller controller = ModuleLayer.defineModules(
+ cf, List.of(ModuleLayer.boot()), name -> bootCL);
+ ModuleLayer infraLayer = controller.layer();
+
+ // 6. Transfer the jdk.internal.module export to the infrastructure module
+ Module infraModule = infraLayer.findModule("io.smallrye.modules")
+ .orElseThrow(() -> new IllegalStateException("io.smallrye.modules not found in infrastructure layer"));
+ transferInternalExport(infraModule);
+
+ // 7. Set TCCL and invoke Launcher.main
+ Thread.currentThread().setContextClassLoader(bootCL);
+ Class> launcherClass = Class.forName(infraModule, "io.smallrye.modules.Launcher");
+ if (launcherClass == null) {
+ throw new ClassNotFoundException("io.smallrye.modules.Launcher not found in infrastructure layer");
+ }
+ MethodHandle mainHandle = publicLookup().findStatic(launcherClass, "main",
+ MethodType.methodType(void.class, String[].class));
+ mainHandle.invokeExact(args);
+ }
+
+ /**
+ * Build a map of module name to {@link ModuleReference} from the composite index.
+ * Each reference wraps the {@link ModuleDescriptor} read from the composite buffer.
+ */
+ private static Map buildModuleReferences(ByteBuffer buffer, JarIndex index) {
+ HashMap refs = new HashMap<>();
+ for (String moduleName : index.moduleNames()) {
+ long offset = index.classOffset(moduleName, "module-info");
+ long size = index.classSize(moduleName, "module-info");
+ ByteBuffer descriptorBytes = buffer.slice((int) offset, (int) size);
+ ModuleDescriptor descriptor = ModuleDescriptor.read(descriptorBytes);
+ ModuleReference ref = new ModuleReference(descriptor, null) {
+ @Override
+ public ModuleReader open() {
+ // module reader is not needed for defineModules — the boot class loader handles all reads
+ return new ModuleReader() {
+ @Override
+ public Optional find(String name) {
+ return Optional.empty();
+ }
+
+ @Override
+ public Stream list() {
+ return Stream.empty();
+ }
+
+ @Override
+ public void close() {
+ }
+ };
+ }
+ };
+ refs.put(moduleName, ref);
+ }
+ return refs;
+ }
+
+ /**
+ * Use {@code jdk.internal.module.Modules.addExports} to export
+ * {@code jdk.internal.module} from {@code java.base} to the given module.
+ *
+ * This requires {@code --add-exports java.base/jdk.internal.module=ALL-UNNAMED}
+ * on the command line (since the boot module is on the unnamed module of the
+ * system class loader at startup).
+ */
+ private static void transferInternalExport(Module infraModule) {
+ try {
+ @SuppressWarnings("Java9ReflectionClassVisibility")
+ Class> modulesClass = Class.forName("jdk.internal.module.Modules", true, null);
+ MethodHandle addExports = lookup().findStatic(modulesClass, "addExports",
+ MethodType.methodType(void.class, Module.class, String.class, Module.class));
+ Module javaBase = Object.class.getModule();
+ addExports.invokeExact(javaBase, "jdk.internal.module", infraModule);
+ } catch (Throwable e) {
+ Module self = Boot.class.getModule();
+ String target = self.isNamed() ? self.getName() : "ALL-UNNAMED";
+ throw new IllegalStateException(
+ "Failed to transfer jdk.internal.module export — use: "
+ + "--add-exports java.base/jdk.internal.module=" + target,
+ e);
+ }
+ }
+}
diff --git a/boot/src/main/java/io/smallrye/modules/boot/BootClassLoader.java b/boot/src/main/java/io/smallrye/modules/boot/BootClassLoader.java
new file mode 100644
index 0000000..fe255ea
--- /dev/null
+++ b/boot/src/main/java/io/smallrye/modules/boot/BootClassLoader.java
@@ -0,0 +1,266 @@
+package io.smallrye.modules.boot;
+
+import java.io.IOException;
+import java.lang.module.ModuleDescriptor;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A lock-free class loader that defines classes from pre-indexed offsets
+ * within a memory-mapped composite JAR.
+ *
+ * This class loader eliminates class-loading locks using the same pattern
+ * as {@code ModuleClassLoader}: {@link #getClassLoadingLock(String)} eagerly
+ * loads the class and returns it as the "lock" object, so the JDK's
+ * {@code ClassLoader.loadClass(Module, String)} never blocks.
+ *
+ * Boot layer packages are delegated to the boot loader via
+ * {@link Class#forName(Module, String)}. All other classes are defined
+ * from zero-copy {@link ByteBuffer} slices of the composite JAR.
+ */
+public final class BootClassLoader extends ClassLoader {
+ static {
+ if (!ClassLoader.registerAsParallelCapable()) {
+ throw new InternalError("Class loader cannot be made parallel-capable");
+ }
+ }
+
+ /**
+ * Boot layer index: package name to {@code Module}.
+ */
+ private static final Map bootModuleIndex;
+
+ static {
+ HashMap map = new HashMap<>(1000);
+ populateIndex(map, ModuleLayer.boot());
+ bootModuleIndex = Map.copyOf(map);
+ }
+
+ private static void populateIndex(Map map, ModuleLayer layer) {
+ for (Module module : layer.modules()) {
+ for (String pn : module.getPackages()) {
+ map.put(pn, module);
+ }
+ }
+ for (ModuleLayer parent : layer.parents()) {
+ populateIndex(map, parent);
+ }
+ }
+
+ private final ByteBuffer compositeBuffer;
+ private final JarIndex jarIndex;
+ /**
+ * Package name (dots) to module name.
+ */
+ private final Map packageIndex;
+ private final ProtectionDomain protectionDomain;
+
+ /**
+ * Construct a new boot class loader.
+ *
+ * Reads module descriptors from the composite JAR via the index to build
+ * the package-to-module routing map. No classes are loaded during construction.
+ *
+ * @param compositeBuffer the memory-mapped composite JAR buffer (must not be {@code null})
+ * @param jarIndex the pre-built index of class entries (must not be {@code null})
+ * @param protectionDomain the protection domain to assign to defined classes, or {@code null}
+ */
+ public BootClassLoader(ByteBuffer compositeBuffer, JarIndex jarIndex, ProtectionDomain protectionDomain) {
+ // no parent class loader — boot layer delegation is handled explicitly
+ super("boot", null);
+ this.compositeBuffer = compositeBuffer;
+ this.jarIndex = jarIndex;
+ this.protectionDomain = protectionDomain;
+ this.packageIndex = buildPackageIndex(compositeBuffer, jarIndex);
+ }
+
+ private static Map buildPackageIndex(ByteBuffer buffer, JarIndex index) {
+ // scan module descriptors to map package → module name
+ HashMap map = new HashMap<>();
+ for (String moduleName : index.moduleNames()) {
+ long offset = index.classOffset(moduleName, "module-info");
+ long size = index.classSize(moduleName, "module-info");
+ if (offset < 0 || size < 0) {
+ throw new IllegalArgumentException("Module " + moduleName + " has no module-info.class entry");
+ }
+ ByteBuffer descriptorBytes = buffer.slice((int) offset, (int) size);
+ ModuleDescriptor descriptor = ModuleDescriptor.read(descriptorBytes);
+ for (String pkg : descriptor.packages()) {
+ map.put(pkg, moduleName);
+ }
+ }
+ return Map.copyOf(map);
+ }
+
+ // ── Lock elimination ──────────────────────────────────────────────
+
+ /**
+ * {@inheritDoc}
+ *
+ * Overridden as {@code final} to bypass parent delegation and route
+ * classes either to the boot layer or to direct definition from the
+ * composite buffer.
+ */
+ @Override
+ protected Class> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+ if (name.startsWith("[")) {
+ // array type — delegate to the boot loader
+ return Class.forName(name, false, null);
+ }
+ String binaryName = name.replace('/', '.');
+ String packageName = packageName(binaryName);
+ if (bootModuleIndex.containsKey(packageName)) {
+ // boot layer class — delegate via boot module
+ Module module = bootModuleIndex.get(packageName);
+ Class> result = Class.forName(module, binaryName);
+ if (result != null) {
+ return result;
+ }
+ throw new ClassNotFoundException("Cannot find " + name + " in boot layer module " + module.getName());
+ }
+ return loadClassDirect(binaryName);
+ }
+
+ /**
+ * Eagerly loads the requested class and returns it as the "lock" object.
+ *
+ * The JDK's {@code ClassLoader.loadClass(Module, String)} acquires this
+ * lock before calling {@link #findClass(String, String)}. By loading the
+ * class here, the subsequent {@code findClass} call becomes a no-op,
+ * eliminating all lock contention.
+ */
+ @Override
+ protected Object getClassLoadingLock(String className) {
+ try {
+ return loadClass(className);
+ } catch (ClassNotFoundException e) {
+ return new Object();
+ }
+ }
+
+ /**
+ * Returns {@code null} because the class was already loaded by
+ * {@link #getClassLoadingLock(String)}.
+ */
+ @Override
+ protected Class> findClass(String moduleName, String name) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Class> findClass(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ // ── Class definition ──────────────────────────────────────────────
+
+ /**
+ * Load a class directly from the composite buffer.
+ *
+ * Looks up the class in the package index, retrieves its byte offset
+ * and size from the jar index, slices a zero-copy view, and defines
+ * the class. Concurrent definition races are handled by catching
+ * {@link LinkageError} and falling back to {@link #findLoadedClass}.
+ *
+ * @param binaryName the binary name with dots (e.g. {@code "io.smallrye.modules.Launcher"})
+ * @return the defined or previously-loaded class
+ * @throws ClassNotFoundException if the class is not found in the composite
+ */
+ private Class> loadClassDirect(String binaryName) throws ClassNotFoundException {
+ Class> loaded = findLoadedClass(binaryName);
+ if (loaded != null) {
+ return loaded;
+ }
+ String packageName = packageName(binaryName);
+ String moduleName = packageIndex.get(packageName);
+ if (moduleName == null) {
+ throw new ClassNotFoundException("No module contains package " + packageName);
+ }
+ long offset = jarIndex.classOffset(moduleName, binaryName);
+ long size = jarIndex.classSize(moduleName, binaryName);
+ if (offset < 0 || size < 0) {
+ throw new ClassNotFoundException(binaryName + " not found in module " + moduleName);
+ }
+ ByteBuffer classBytes = compositeBuffer.slice((int) offset, (int) size);
+ if (!packageName.isEmpty() && getDefinedPackage(packageName) == null) {
+ try {
+ definePackage(packageName, null, null, null, null, null, null, null);
+ } catch (IllegalArgumentException ignored) {
+ // concurrent define — package already exists
+ }
+ }
+ return defineOrGetClass(binaryName, classBytes);
+ }
+
+ /**
+ * Define the class from the given buffer, handling concurrent definition races.
+ */
+ private Class> defineOrGetClass(String binaryName, ByteBuffer buffer) {
+ try {
+ return defineClass(binaryName, buffer, protectionDomain);
+ } catch (LinkageError e) {
+ // concurrent definition race — check if another thread defined it
+ Class> loaded = findLoadedClass(binaryName);
+ if (loaded != null) {
+ return loaded;
+ }
+ throw e;
+ }
+ }
+
+ // ── Sealed unsupported operations ─────────────────────────────────
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URL findResource(String moduleName, String name) throws IOException {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected URL findResource(String name) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Enumeration findResources(String name) {
+ return java.util.Collections.emptyEnumeration();
+ }
+
+ // ── Utility ───────────────────────────────────────────────────────
+
+ /**
+ * Extract the package name from a binary class name.
+ *
+ * @param binaryName the binary name (dots)
+ * @return the package name, or the empty string for the default package
+ */
+ private static String packageName(String binaryName) {
+ int lastDot = binaryName.lastIndexOf('.');
+ return lastDot < 0 ? "" : binaryName.substring(0, lastDot);
+ }
+}
diff --git a/boot/src/main/java/io/smallrye/modules/boot/JarIndex.java b/boot/src/main/java/io/smallrye/modules/boot/JarIndex.java
new file mode 100644
index 0000000..c688539
--- /dev/null
+++ b/boot/src/main/java/io/smallrye/modules/boot/JarIndex.java
@@ -0,0 +1,53 @@
+package io.smallrye.modules.boot;
+
+import java.util.List;
+
+/**
+ * Index of class entries within a composite JAR.
+ *
+ * An implementation of this interface is synthesized by the composite JAR builder
+ * and placed at the top level of the composite JAR so that it is visible to the
+ * system class loader. The boot shim loads the implementation and uses it to
+ * locate class bytes within the memory-mapped composite without any ZIP parsing.
+ *
+ * The {@code module-info.class} entries in the composite JAR must contain
+ * complete package lists. The boot class loader reads
+ * {@link java.lang.module.ModuleDescriptor#packages()} to build the
+ * package-to-module routing map; a module descriptor with a missing or
+ * incomplete package index will cause classes in unlisted packages to be
+ * unroutable.
+ *
+ * All offsets and sizes are {@code long} to future-proof for {@code MemorySegment}
+ * support.
+ */
+public interface JarIndex {
+
+ /**
+ * {@return the names of all modules stored in the composite JAR}
+ * The returned list is unmodifiable and never empty.
+ */
+ List moduleNames();
+
+ /**
+ * Return the byte offset within the composite JAR of the given class entry.
+ *
+ * The {@code className} is a binary name (dots, not slashes), e.g.
+ * {@code "io.smallrye.modules.Launcher"}.
+ * Use {@code "module-info"} to retrieve the {@code module-info.class} entry
+ * for the given module.
+ *
+ * @param moduleName the module name (must not be {@code null})
+ * @param className the binary class name (must not be {@code null})
+ * @return the byte offset, or {@code -1} if the entry is not found
+ */
+ long classOffset(String moduleName, String className);
+
+ /**
+ * Return the byte size of the given class entry within the composite JAR.
+ *
+ * @param moduleName the module name (must not be {@code null})
+ * @param className the binary class name (must not be {@code null})
+ * @return the byte size, or {@code -1} if the entry is not found
+ */
+ long classSize(String moduleName, String className);
+}
diff --git a/boot/src/main/java/module-info.java b/boot/src/main/java/module-info.java
new file mode 100644
index 0000000..a009cdb
--- /dev/null
+++ b/boot/src/main/java/module-info.java
@@ -0,0 +1,6 @@
+/**
+ * Boot shim for loading the SmallRye Modules runtime from a composite JAR.
+ */
+module io.smallrye.modules.boot {
+ exports io.smallrye.modules.boot;
+}
diff --git a/pom.xml b/pom.xml
index 108a27d..05056ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,18 +2,24 @@
4.0.0
- io.smallrye.modules
- smallrye-modules
- 1.0.beta2-SNAPSHOT
-
io.smallryesmallrye-parent50
- SmallRye Modules
- A dynamic modular class loading environment
+ io.smallrye.modules
+ smallrye-modules-parent
+ 1.0.beta2-SNAPSHOT
+ pom
+
+ SmallRye Modules - Parent
+ Parent and aggregator for SmallRye Modules
+
+
+ runtime
+ boot
+ 17
@@ -32,54 +38,8 @@
-
-
- io.smallrye.common
- smallrye-common-cpu
-
-
- io.smallrye.common
- smallrye-common-os
-
-
- io.smallrye.common
- smallrye-common-resource
-
-
- io.smallrye.classfile
- jdk-classfile-backport
- 27
-
-
- org.jboss.logging
- jboss-logging
- 3.6.3.Final
-
-
- org.junit.jupiter
- junit-jupiter
- test
-
-
-
-
- maven-surefire-plugin
-
- --add-exports java.base/jdk.internal.module=io.smallrye.modules
-
-
-
- maven-jar-plugin
-
-
-
- io.smallrye.modules.Launcher
-
-
-
- net.revelc.codeimpsort-maven-plugin
@@ -119,12 +79,6 @@
-
- maven-javadoc-plugin
-
- 17
-
-
diff --git a/runtime/pom.xml b/runtime/pom.xml
new file mode 100644
index 0000000..7faa841
--- /dev/null
+++ b/runtime/pom.xml
@@ -0,0 +1,72 @@
+
+
+ 4.0.0
+
+
+ io.smallrye.modules
+ smallrye-modules-parent
+ 1.0.beta2-SNAPSHOT
+
+
+ smallrye-modules
+
+ SmallRye Modules
+ A dynamic modular class loading environment
+
+
+
+ io.smallrye.common
+ smallrye-common-cpu
+
+
+ io.smallrye.common
+ smallrye-common-os
+
+
+ io.smallrye.common
+ smallrye-common-resource
+
+
+ io.smallrye.classfile
+ jdk-classfile-backport
+ 27
+
+
+ org.jboss.logging
+ jboss-logging
+ 3.6.3.Final
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+
+
+
+
+ maven-surefire-plugin
+
+ --add-exports java.base/jdk.internal.module=io.smallrye.modules
+
+
+
+ maven-jar-plugin
+
+
+
+ io.smallrye.modules.Launcher
+
+
+
+
+
+ maven-javadoc-plugin
+
+ 17
+
+
+
+
+
diff --git a/src/main/java/io/smallrye/modules/DefinedModule.java b/runtime/src/main/java/io/smallrye/modules/DefinedModule.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/DefinedModule.java
rename to runtime/src/main/java/io/smallrye/modules/DefinedModule.java
diff --git a/src/main/java/io/smallrye/modules/DelegatingModuleLoader.java b/runtime/src/main/java/io/smallrye/modules/DelegatingModuleLoader.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/DelegatingModuleLoader.java
rename to runtime/src/main/java/io/smallrye/modules/DelegatingModuleLoader.java
diff --git a/src/main/java/io/smallrye/modules/FoundModule.java b/runtime/src/main/java/io/smallrye/modules/FoundModule.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/FoundModule.java
rename to runtime/src/main/java/io/smallrye/modules/FoundModule.java
diff --git a/src/main/java/io/smallrye/modules/JarFileModuleFinder.java b/runtime/src/main/java/io/smallrye/modules/JarFileModuleFinder.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/JarFileModuleFinder.java
rename to runtime/src/main/java/io/smallrye/modules/JarFileModuleFinder.java
diff --git a/src/main/java/io/smallrye/modules/Launcher.java b/runtime/src/main/java/io/smallrye/modules/Launcher.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/Launcher.java
rename to runtime/src/main/java/io/smallrye/modules/Launcher.java
diff --git a/src/main/java/io/smallrye/modules/LinkState.java b/runtime/src/main/java/io/smallrye/modules/LinkState.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/LinkState.java
rename to runtime/src/main/java/io/smallrye/modules/LinkState.java
diff --git a/src/main/java/io/smallrye/modules/LoadedDependency.java b/runtime/src/main/java/io/smallrye/modules/LoadedDependency.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/LoadedDependency.java
rename to runtime/src/main/java/io/smallrye/modules/LoadedDependency.java
diff --git a/src/main/java/io/smallrye/modules/LoadedModule.java b/runtime/src/main/java/io/smallrye/modules/LoadedModule.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/LoadedModule.java
rename to runtime/src/main/java/io/smallrye/modules/LoadedModule.java
diff --git a/src/main/java/io/smallrye/modules/ModuleClassLoader.java b/runtime/src/main/java/io/smallrye/modules/ModuleClassLoader.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ModuleClassLoader.java
rename to runtime/src/main/java/io/smallrye/modules/ModuleClassLoader.java
diff --git a/src/main/java/io/smallrye/modules/ModuleDescriptorLoader.java b/runtime/src/main/java/io/smallrye/modules/ModuleDescriptorLoader.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ModuleDescriptorLoader.java
rename to runtime/src/main/java/io/smallrye/modules/ModuleDescriptorLoader.java
diff --git a/src/main/java/io/smallrye/modules/ModuleFinder.java b/runtime/src/main/java/io/smallrye/modules/ModuleFinder.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ModuleFinder.java
rename to runtime/src/main/java/io/smallrye/modules/ModuleFinder.java
diff --git a/src/main/java/io/smallrye/modules/ModuleLoadException.java b/runtime/src/main/java/io/smallrye/modules/ModuleLoadException.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ModuleLoadException.java
rename to runtime/src/main/java/io/smallrye/modules/ModuleLoadException.java
diff --git a/src/main/java/io/smallrye/modules/ModuleLoader.java b/runtime/src/main/java/io/smallrye/modules/ModuleLoader.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ModuleLoader.java
rename to runtime/src/main/java/io/smallrye/modules/ModuleLoader.java
diff --git a/src/main/java/io/smallrye/modules/ModuleNotFoundException.java b/runtime/src/main/java/io/smallrye/modules/ModuleNotFoundException.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ModuleNotFoundException.java
rename to runtime/src/main/java/io/smallrye/modules/ModuleNotFoundException.java
diff --git a/src/main/java/io/smallrye/modules/ResourceLoaderOpener.java b/runtime/src/main/java/io/smallrye/modules/ResourceLoaderOpener.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/ResourceLoaderOpener.java
rename to runtime/src/main/java/io/smallrye/modules/ResourceLoaderOpener.java
diff --git a/src/main/java/io/smallrye/modules/desc/Biterator.java b/runtime/src/main/java/io/smallrye/modules/desc/Biterator.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/Biterator.java
rename to runtime/src/main/java/io/smallrye/modules/desc/Biterator.java
diff --git a/src/main/java/io/smallrye/modules/desc/Dependency.java b/runtime/src/main/java/io/smallrye/modules/desc/Dependency.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/Dependency.java
rename to runtime/src/main/java/io/smallrye/modules/desc/Dependency.java
diff --git a/src/main/java/io/smallrye/modules/desc/ModifierFlag.java b/runtime/src/main/java/io/smallrye/modules/desc/ModifierFlag.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/ModifierFlag.java
rename to runtime/src/main/java/io/smallrye/modules/desc/ModifierFlag.java
diff --git a/src/main/java/io/smallrye/modules/desc/Modifiers.java b/runtime/src/main/java/io/smallrye/modules/desc/Modifiers.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/Modifiers.java
rename to runtime/src/main/java/io/smallrye/modules/desc/Modifiers.java
diff --git a/src/main/java/io/smallrye/modules/desc/ModuleDescriptor.java b/runtime/src/main/java/io/smallrye/modules/desc/ModuleDescriptor.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/ModuleDescriptor.java
rename to runtime/src/main/java/io/smallrye/modules/desc/ModuleDescriptor.java
diff --git a/src/main/java/io/smallrye/modules/desc/PackageAccess.java b/runtime/src/main/java/io/smallrye/modules/desc/PackageAccess.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/PackageAccess.java
rename to runtime/src/main/java/io/smallrye/modules/desc/PackageAccess.java
diff --git a/src/main/java/io/smallrye/modules/desc/PackageInfo.java b/runtime/src/main/java/io/smallrye/modules/desc/PackageInfo.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/desc/PackageInfo.java
rename to runtime/src/main/java/io/smallrye/modules/desc/PackageInfo.java
diff --git a/src/main/java/io/smallrye/modules/impl/Access.java b/runtime/src/main/java/io/smallrye/modules/impl/Access.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/impl/Access.java
rename to runtime/src/main/java/io/smallrye/modules/impl/Access.java
diff --git a/src/main/java/io/smallrye/modules/impl/TextIter.java b/runtime/src/main/java/io/smallrye/modules/impl/TextIter.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/impl/TextIter.java
rename to runtime/src/main/java/io/smallrye/modules/impl/TextIter.java
diff --git a/src/main/java/io/smallrye/modules/impl/Util.java b/runtime/src/main/java/io/smallrye/modules/impl/Util.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/impl/Util.java
rename to runtime/src/main/java/io/smallrye/modules/impl/Util.java
diff --git a/src/main/java/io/smallrye/modules/jfr/DefineDuplicateEvent.java b/runtime/src/main/java/io/smallrye/modules/jfr/DefineDuplicateEvent.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/jfr/DefineDuplicateEvent.java
rename to runtime/src/main/java/io/smallrye/modules/jfr/DefineDuplicateEvent.java
diff --git a/src/main/java/io/smallrye/modules/jfr/DefineFailedEvent.java b/runtime/src/main/java/io/smallrye/modules/jfr/DefineFailedEvent.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/jfr/DefineFailedEvent.java
rename to runtime/src/main/java/io/smallrye/modules/jfr/DefineFailedEvent.java
diff --git a/src/main/java/io/smallrye/modules/jfr/LinkEvent.java b/runtime/src/main/java/io/smallrye/modules/jfr/LinkEvent.java
similarity index 100%
rename from src/main/java/io/smallrye/modules/jfr/LinkEvent.java
rename to runtime/src/main/java/io/smallrye/modules/jfr/LinkEvent.java
diff --git a/src/main/java/module-info.java b/runtime/src/main/java/module-info.java
similarity index 100%
rename from src/main/java/module-info.java
rename to runtime/src/main/java/module-info.java
diff --git a/src/test/java/io/smallrye/modules/test/BasicTests.java b/runtime/src/test/java/io/smallrye/modules/test/BasicTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/BasicTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/BasicTests.java
diff --git a/src/test/java/io/smallrye/modules/test/DelegatingModuleLoaderTests.java b/runtime/src/test/java/io/smallrye/modules/test/DelegatingModuleLoaderTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/DelegatingModuleLoaderTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/DelegatingModuleLoaderTests.java
diff --git a/src/test/java/io/smallrye/modules/test/DependencyModifierTests.java b/runtime/src/test/java/io/smallrye/modules/test/DependencyModifierTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/DependencyModifierTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/DependencyModifierTests.java
diff --git a/src/test/java/io/smallrye/modules/test/DependencyTests.java b/runtime/src/test/java/io/smallrye/modules/test/DependencyTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/DependencyTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/DependencyTests.java
diff --git a/src/test/java/io/smallrye/modules/test/ExceptionTests.java b/runtime/src/test/java/io/smallrye/modules/test/ExceptionTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/ExceptionTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/ExceptionTests.java
diff --git a/src/test/java/io/smallrye/modules/test/FoundModuleTests.java b/runtime/src/test/java/io/smallrye/modules/test/FoundModuleTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/FoundModuleTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/FoundModuleTests.java
diff --git a/src/test/java/io/smallrye/modules/test/LoadedModuleTests.java b/runtime/src/test/java/io/smallrye/modules/test/LoadedModuleTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/LoadedModuleTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/LoadedModuleTests.java
diff --git a/src/test/java/io/smallrye/modules/test/ModuleDescriptorBuilderTests.java b/runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorBuilderTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/ModuleDescriptorBuilderTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorBuilderTests.java
diff --git a/src/test/java/io/smallrye/modules/test/ModuleDescriptorManifestTests.java b/runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorManifestTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/ModuleDescriptorManifestTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorManifestTests.java
diff --git a/src/test/java/io/smallrye/modules/test/ModuleDescriptorModifierTests.java b/runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorModifierTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/ModuleDescriptorModifierTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorModifierTests.java
diff --git a/src/test/java/io/smallrye/modules/test/ModuleDescriptorXmlTests.java b/runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorXmlTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/ModuleDescriptorXmlTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/ModuleDescriptorXmlTests.java
diff --git a/src/test/java/io/smallrye/modules/test/ModuleLoaderTests.java b/runtime/src/test/java/io/smallrye/modules/test/ModuleLoaderTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/ModuleLoaderTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/ModuleLoaderTests.java
diff --git a/src/test/java/io/smallrye/modules/test/PackageAccessTests.java b/runtime/src/test/java/io/smallrye/modules/test/PackageAccessTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/PackageAccessTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/PackageAccessTests.java
diff --git a/src/test/java/io/smallrye/modules/test/PackageInfoTests.java b/runtime/src/test/java/io/smallrye/modules/test/PackageInfoTests.java
similarity index 100%
rename from src/test/java/io/smallrye/modules/test/PackageInfoTests.java
rename to runtime/src/test/java/io/smallrye/modules/test/PackageInfoTests.java
diff --git a/src/test/java/module-info.java b/runtime/src/test/java/module-info.java
similarity index 100%
rename from src/test/java/module-info.java
rename to runtime/src/test/java/module-info.java