diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java index a6313a965..19544447d 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java @@ -192,4 +192,24 @@ public abstract class JDBCEnvironment extends DelegatingEnvironment { */ public abstract String getPassword() throws GuacamoleException; + /** + * Returns whether the given Java class is defined within the classpath. + * + * @param classname + * The name of the Java class to check. + * + * @return + * true if the given Java class is present within the classpath, false + * otherwise. + */ + public static boolean isClassDefined(String classname) { + try { + Class.forName(classname, false, JDBCEnvironment.class.getClassLoader()); + return true; + } + catch (ClassNotFoundException e) { + return false; + } + } + } diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLDriver.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLDriver.java index 36e8e9b1b..7ce915ab3 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLDriver.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLDriver.java @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.mysql.conf; +import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.properties.EnumGuacamoleProperty.PropertyValue; /** @@ -31,11 +32,39 @@ public enum MySQLDriver { * MySQL driver. */ @PropertyValue("mysql") - MYSQL, + MYSQL("com.mysql.jdbc.Driver"), /** * MariaDB driver. */ @PropertyValue("mariadb") - MARIADB; + MARIADB("org.mariadb.jdbc.Driver"); + + /** + * The name of the JDBC driver class. + */ + private final String driverClass; + + /** + * Creates a new MySQLDriver that points to the given Java class as the + * entrypoint of the JDBC driver. + * + * @param classname + * The name of the JDBC driver class. + */ + private MySQLDriver(String classname) { + this.driverClass = classname; + } + + /** + * Returns whether this MySQL JDBC driver is installed and can be found + * within the Java classpath. + * + * @return + * true if this MySQL JDBC driver is installed, false otherwise. + */ + public boolean isInstalled() { + return JDBCEnvironment.isClassDefined(driverClass); + } + } \ No newline at end of file diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java index f4aa645b1..ee3fd8aa1 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/conf/MySQLEnvironment.java @@ -25,6 +25,7 @@ import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.TimeZone; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -53,11 +54,6 @@ public class MySQLEnvironment extends JDBCEnvironment { */ private static final MySQLVersion MYSQL_SUPPORTS_CTE = new MySQLVersion(8, 0, 1, false); - /** - * The default MySQL-compatible driver to use, if not specified. - */ - private static final MySQLDriver DEFAULT_DRIVER = MySQLDriver.MYSQL; - /** * The default host to connect to, if MYSQL_HOSTNAME is not specified. */ @@ -178,21 +174,41 @@ public class MySQLEnvironment extends JDBCEnvironment { /** * Returns the MySQL driver that will be used to talk to the MySQL-compatible - * database server hosting the Guacamole Client database. If unspecified - * a default value of MySQL will be used. + * database server hosting the Guacamole database. If unspecified, the + * installed MySQL driver will be automatically detected by inspecting the + * classes available in the classpath. * * @return * The MySQL driver that will be used to communicate with the MySQL- * compatible server. * * @throws GuacamoleException - * If guacamole.properties cannot be parsed. + * If guacamole.properties cannot be parsed, or if no MySQL-compatible + * JDBC driver is present. */ public MySQLDriver getMySQLDriver() throws GuacamoleException { - return getProperty( - MySQLGuacamoleProperties.MYSQL_DRIVER, - DEFAULT_DRIVER - ); + + // Use any explicitly-specified driver + MySQLDriver driver = getProperty(MySQLGuacamoleProperties.MYSQL_DRIVER); + if (driver != null) + return driver; + + // Attempt autodetection based on presence of JDBC driver within + // classpath... + + if (MySQLDriver.MARIADB.isInstalled()) { + logger.info("Installed JDBC driver for MySQL/MariaDB detected as \"MariaDB Connector/J\"."); + return MySQLDriver.MARIADB; + } + + if (MySQLDriver.MYSQL.isInstalled()) { + logger.info("Installed JDBC driver for MySQL/MariaDB detected as \"MySQL Connector/J\"."); + return MySQLDriver.MYSQL; + } + + // No driver found at all + throw new GuacamoleServerException("No JDBC driver for MySQL/MariaDB is installed."); + } /**