From 1a83e8355ceae94f5db7ebe2c8ded5eee4f34207 Mon Sep 17 00:00:00 2001 From: Telesphoreo Date: Thu, 28 May 2026 18:05:46 -0400 Subject: [PATCH] Update MigrationRunner.java --- .../storage/database/MigrationRunner.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/dev/plex/storage/database/MigrationRunner.java b/server/src/main/java/dev/plex/storage/database/MigrationRunner.java index 3916c57..c9fbf67 100644 --- a/server/src/main/java/dev/plex/storage/database/MigrationRunner.java +++ b/server/src/main/java/dev/plex/storage/database/MigrationRunner.java @@ -7,6 +7,9 @@ import dev.plex.util.PlexLog; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.sql.Connection; import java.sql.PreparedStatement; @@ -128,7 +131,7 @@ public class MigrationRunner private String readModule(PlexModule module, String resourceRoot, String version) throws SQLException { String resource = resourceRoot + "/" + storageType.dialect().migrationDirectory() + "/" + version + ".sql"; - try (InputStream stream = module.getResource(resource)) + try (InputStream stream = openModuleResource(module, resource)) { if (stream == null) { @@ -142,6 +145,32 @@ public class MigrationRunner } } + /** + * Opens a migration resource from the module's own jar. + * + *

A module class loader is parent-first with the Plex class loader as its + * parent, and core ships migration scripts at the same + * {@code db/migration//.sql} paths a module uses. A plain + * {@link PlexModule#getResource(String)} lookup therefore resolves to Plex's + * core script instead of the module's own. {@link URLClassLoader#findResource} + * searches only the module jar, so the module always reads its own migration.

+ */ + private InputStream openModuleResource(PlexModule module, String resource) throws IOException + { + if (module.getClass().getClassLoader() instanceof URLClassLoader moduleClassLoader) + { + URL url = moduleClassLoader.findResource(resource); + if (url == null) + { + return null; + } + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + return connection.getInputStream(); + } + return module.getResource(resource); + } + private String replaceTableTokens(String script, Function tableResolver) throws SQLException { Matcher matcher = TABLE_TOKEN_PATTERN.matcher(script);