I'm trying to set up a simple web application that uses Spark and Apache shiro (for authentication and authorization).
I want authentication to happen from MySQL database, but I get a ClassNotFoundException
that it could not be found.
This is my shiro.ini configuration file:
[main]
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.serverName = localhost
ds.user = ...
ds.password = ...
ds.databaseName = mydb
jdbcRealm.dataSource = $ds
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.authenticationQuery = "SELECT password FROM users WHERE user_name = ?"
jdbcRealm.userRolesQuery = "SELECT role_name FROM user_roles WHERE user_name = ?"
jdbcRealm.permissionsQuery = "SELECT permission FROM roles_permissions WHERE role_name = ?
And my build.gradle file
group 'test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'application'
mainClassName = "Main"
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile 'com.sparkjava:spark-core:2.5.4'
compile 'ch.qos.logback:logback-classic:1.1.8'
compile 'org.apache.shiro:shiro-core:1.1.0'
compile 'mysql:mysql-connector-java:6.0.5'
compile 'commons-logging:commons-logging:1.2'
compile 'commons-dbcp:commons-dbcp:1.4'
}
jar {
from {
(configurations.runtime).collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
The exception I'm getting is:
Exception in thread "main" org.apache.shiro.config.ConfigurationException: Unable to instantiate class [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] for object named 'ds'. Please ensure you've specified the fully qualified class name correctly.
at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:143)
at org.apache.shiro.config.ReflectionBuilder.buildObjects(ReflectionBuilder.java:114)
at org.apache.shiro.config.IniSecurityManagerFactory.buildInstances(IniSecurityManagerFactory.java:170)
at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:119)
at org.apache.shiro.config.IniSecurityManagerFactory.createSecurityManager(IniSecurityManagerFactory.java:97)
at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:83)
at org.apache.shiro.config.IniSecurityManagerFactory.createInstance(IniSecurityManagerFactory.java:41)
at org.apache.shiro.config.IniFactorySupport.createInstance(IniFactorySupport.java:123)
at org.apache.shiro.util.AbstractFactory.getInstance(AbstractFactory.java:47)
at Main.main(Main.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.apache.shiro.util.UnknownClassException: Unable to load class named [com.mysql.jdbc.jdbc2.optional.MysqlDataSource] from the thread context, current, or system/application ClassLoaders. All heuristics have been exhausted. Class could not be found.
at org.apache.shiro.util.ClassUtils.forName(ClassUtils.java:148)
at org.apache.shiro.util.ClassUtils.newInstance(ClassUtils.java:164)
at org.apache.shiro.config.ReflectionBuilder.createNewInstance(ReflectionBuilder.java:136)
... 14 more
Although I'm not 100% sure, I believe the issue is that the mysql driver is not on the classpath at runtime...
Try to use
com.mysql.cj.jdbc.MysqlDataSource
instead of
com.mysql.jdbc.jdbc2.optional.MysqlDataSource
You are compiling
mysql-connector-java:6.0.5
.reference