diff --git a/src/main/java/net/elytrium/limboauth/dependencies/DatabaseLibrary.java b/src/main/java/net/elytrium/limboauth/dependencies/DatabaseLibrary.java index 9cab1768..62f68892 100644 --- a/src/main/java/net/elytrium/limboauth/dependencies/DatabaseLibrary.java +++ b/src/main/java/net/elytrium/limboauth/dependencies/DatabaseLibrary.java @@ -32,6 +32,7 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; +import java.util.Locale; import java.util.Properties; public enum DatabaseLibrary { @@ -96,6 +97,7 @@ public enum DatabaseLibrary { private final BaseLibrary baseLibrary; private final DatabaseConnector connector; private final DatabaseStringGetter stringGetter; + private final IsolatedDriver driver = new IsolatedDriver("jdbc:limboauth_" + this.name().toLowerCase(Locale.ROOT) + ":"); DatabaseLibrary(BaseLibrary baseLibrary, DatabaseConnector connector, DatabaseStringGetter stringGetter) { this.baseLibrary = baseLibrary; @@ -124,16 +126,26 @@ public Connection connect(Path dir, String jdbc, String user, String password) t public ConnectionSource connectToORM(Path dir, String hostname, String database, String user, String password) throws ReflectiveOperationException, IOException, SQLException, URISyntaxException { - String jdbc = this.stringGetter.getJdbcString(dir, hostname, database); - URL baseLibraryURL = this.baseLibrary.getClassLoaderURL(); - ClassLoader currentClassLoader = DatabaseLibrary.class.getClassLoader(); - Method addPath = currentClassLoader.getClass().getDeclaredMethod("addPath", Path.class); - addPath.setAccessible(true); - addPath.invoke(currentClassLoader, Path.of(baseLibraryURL.toURI())); + if (this.driver.getOriginal() == null) { + IsolatedClassLoader classLoader = new IsolatedClassLoader(new URL[] {this.baseLibrary.getClassLoaderURL()}); + Class driverClass = classLoader.loadClass( + switch (this) { + case H2_LEGACY_V1, H2 -> "org.h2.Driver"; + case MYSQL -> "com.mysql.cj.jdbc.NonRegisteringDriver"; + case MARIADB -> "org.mariadb.jdbc.Driver"; + case POSTGRESQL -> "org.postgresql.Driver"; + case SQLITE -> "org.sqlite.JDBC"; + } + ); + + this.driver.setOriginal((Driver) driverClass.getConstructor().newInstance()); + DriverManager.registerDriver(this.driver); + } - this.connect(currentClassLoader, dir, jdbc, user, password).close(); // Load database driver (Will be rewritten soon) + String jdbc = this.stringGetter.getJdbcString(dir, hostname, database); boolean h2 = this.baseLibrary == BaseLibrary.H2_V1 || this.baseLibrary == BaseLibrary.H2_V2; - return new JdbcPooledConnectionSource(jdbc, h2 ? null : user, h2 ? null : password, DatabaseTypeUtils.createDatabaseType(jdbc)); + return new JdbcPooledConnectionSource(this.driver.getInitializer() + jdbc, + h2 ? null : user, h2 ? null : password, DatabaseTypeUtils.createDatabaseType(jdbc)); } private static Connection fromDriver(Class connectionClass, String jdbc, String user, String password, boolean register) diff --git a/src/main/java/net/elytrium/limboauth/dependencies/IsolatedDriver.java b/src/main/java/net/elytrium/limboauth/dependencies/IsolatedDriver.java new file mode 100644 index 00000000..b3ed93a5 --- /dev/null +++ b/src/main/java/net/elytrium/limboauth/dependencies/IsolatedDriver.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2021 - 2024 Elytrium + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package net.elytrium.limboauth.dependencies; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.Logger; + +public class IsolatedDriver implements Driver { + + private final String initializer; + private Driver original; + + public IsolatedDriver(String initializer) { + this.initializer = initializer; + } + + public String getInitializer() { + return this.initializer; + } + + public Driver getOriginal() { + return this.original; + } + + public void setOriginal(Driver driver) { + this.original = driver; + } + + @Override + public Connection connect(String url, Properties info) throws SQLException { + if (url.startsWith(this.initializer)) { + return this.original.connect(url.substring(this.initializer.length()), info); + } + + return null; + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + if (url.startsWith(this.initializer)) { + if (this.original == null) { + return false; + } + + return this.original.acceptsURL(url.substring(this.initializer.length())); + } + + return false; + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { + if (url.startsWith(this.initializer)) { + return this.original.getPropertyInfo(url.substring(this.initializer.length()), info); + } + + return new DriverPropertyInfo[0]; + } + + @Override + public int getMajorVersion() { + return this.original.getMajorVersion(); + } + + @Override + public int getMinorVersion() { + return this.original.getMinorVersion(); + } + + @Override + public boolean jdbcCompliant() { + return this.original.jdbcCompliant(); + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return this.original.getParentLogger(); + } +}