GUACAMOLE-1407: Automatically detect whether MySQL or MariaDB version of "Connector/J" is installed.

This commit is contained in:
Michael Jumper
2021-08-26 17:58:32 -07:00
parent 5cf030a9e3
commit be1ad5dff3
3 changed files with 82 additions and 10 deletions

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -54,9 +54,10 @@ 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.
* The default MySQL-compatible driver to use, if not specified and not
* automatically detected.
*/
private static final MySQLDriver DEFAULT_DRIVER = MySQLDriver.MYSQL;
private static final MySQLDriver FALLBACK_DEFAULT_DRIVER = MySQLDriver.MYSQL;
/**
* The default host to connect to, if MYSQL_HOSTNAME is not specified.
@@ -178,8 +179,10 @@ 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. If automatic detection fails, the
* "MySQL Connector/J" driver will be assumed.
*
* @return
* The MySQL driver that will be used to communicate with the MySQL-
@@ -189,10 +192,30 @@ public class MySQLEnvironment extends JDBCEnvironment {
* If guacamole.properties cannot be parsed.
*/
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;
}
// Fallback to MySQL Connector/J if nothing can be found
logger.warn("JDBC driver for MySQL/MariaDB couuld not be detected "
+ "and might not be installed. Assuming MySQL Connector/J...");
return FALLBACK_DEFAULT_DRIVER;
}
/**