Environment:
Using mariadb-java-client-1.1.9.jar, JNDI data source pool is OK
Using mariadb-java-client-1.2.0.jar, JNDI data source pool is NOT OK
Tomcat context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/myDs" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSourceClassName="org.mariadb.jdbc.MySQLDataSource"
dataSource.user="username"
dataSource.password="password"
dataSource.url="jdbc:mysql://localhost:3306/myDatabase"
/>
</Context>
I used same context.xml for MariaDB client 1.1.9 and 1.2.0, but 1.2.0 would throw error on my username and password.
Attached tomcat exception log
RMI TCP Connection(5)-127.0.0.1] INFO com.zaxxer.hikari.HikariDataSource - Hikari pool HikariPool-1 is starting.
[RMI TCP Connection(5)-127.0.0.1] INFO com.zaxxer.hikari.pool.HikariPool - Hikari pool HikariPool-1 is shutting down.
18-Aug-2015 23:08:10.070 WARNING [RMI TCP Connection(5)-127.0.0.1] org.apache.naming.NamingContext.lookup Unexpected exception resolving reference
com.zaxxer.hikari.pool.PoolInitializationException: Exception during pool initialization
at com.zaxxer.hikari.pool.HikariPool.initializeConnections(HikariPool.java:580)
at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:150)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:73)
at com.zaxxer.hikari.HikariJNDIFactory.createDataSource(HikariJNDIFactory.java:76)
at com.zaxxer.hikari.HikariJNDIFactory.getObjectInstance(HikariJNDIFactory.java:67)
at org.apache.naming.factory.FactoryBase.getObjectInstance(FactoryBase.java:94)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:841)
at org.apache.naming.NamingContext.lookup(NamingContext.java:152)
at org.apache.naming.NamingContext.lookup(NamingContext.java:829)
at org.apache.naming.NamingContext.lookup(NamingContext.java:166)
at org.apache.catalina.core.NamingContextListener.addResource(NamingContextListener.java:1084)
at org.apache.catalina.core.NamingContextListener.createNamingContext(NamingContextListener.java:663)
at org.apache.catalina.core.NamingContextListener.lifecycleEvent(NamingContextListener.java:256)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5066)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717)
at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1648)
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:497)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:463)
at org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:413)
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:497)
at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1470)
at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1311)
at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1403)
at javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:832)
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:497)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:323)
at sun.rmi.transport.Transport$1.run(Transport.java:200)
at sun.rmi.transport.Transport$1.run(Transport.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$255(TCPTransport.java:683)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$2/847502541.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.sql.SQLInvalidAuthorizationSpecException: Could not connect: Access denied for user ''@'localhost' (using password: NO)
at org.mariadb.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:134)
at org.mariadb.jdbc.internal.SQLExceptionMapper.throwException(SQLExceptionMapper.java:106)
at org.mariadb.jdbc.MySQLDataSource.getConnection(MySQLDataSource.java:257)
at com.zaxxer.hikari.pool.HikariPool.addConnection(HikariPool.java:495)
at com.zaxxer.hikari.pool.HikariPool.initializeConnections(HikariPool.java:564)
... 60 more
Caused by: org.mariadb.jdbc.internal.common.QueryException: Could not connect: Access denied for user ''@'localhost' (using password: NO)
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.checkErrorPacket(MySQLProtocol.java:453)
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connect(MySQLProtocol.java:380)
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.connectWithoutProxy(MySQLProtocol.java:624)
at org.mariadb.jdbc.internal.common.Utils.retrieveProxy(Utils.java:541)
at org.mariadb.jdbc.MySQLDataSource.getConnection(MySQLDataSource.java:254)
... 62 more
18-Aug-2015 23:08:10.074 WARNING [RMI TCP Connection(5)-127.0.0.1] org.apache.catalina.core.NamingContextListener.addResource Failed to register in JMX: javax.naming.NamingException: Exception during pool initialization
I'm not sure what broke on their side, there are a few commits in MariaDB affecting their handling of username. You might want to open an issue over there. From the HikariCP side, you can enable debug logging to see if it provides any more clues.
I will note that you should either use dataSourceClasName and "dataSource." properties (for server, port, etc), or don't use dataSourceClassName at all and just use the jdbcUrl (but continue to use "dataSource." properties).
UPDATE: looking at their code, it is possible that the use of the URL is overriding the username. It looks like they expect that, if a URL is used it also contains a "?user=xxxxx&password=yyyy...".
You might eliminate the "dataSource.url" property, and set the server, port, etc. as "dataSource.serverName=localhost" etc. You can see their setters here, just strip off the "set" and lowercase the first letter.
Your suggestion is excellent~! MariaDB java connection 1.2.0 works after taking your advice.
Hope you include it in wiki also. You can close it now. Thanks.
Good tomcat context.xml (with above environment)
<Context>
<Resource name="jdbc/myDs" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSourceClassName="org.mariadb.jdbc.MySQLDataSource"
dataSource.serverName="localhost"
dataSource.port="3306"
dataSource.databaseName="myDatabase"
dataSource.user="username"
dataSource.password="password"
/>
</Context>
Glad it worked for you. I do recommend opening an issue against the MariaDB driver, and referencing this issue. It is certainly a regression in their driver.
I use the url part to solve this problem, because I took the SSL feature.
The configuration will also works, thanks very very much
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/myDs" auth="Container"
factory="com.zaxxer.hikari.HikariJNDIFactory"
type="javax.sql.DataSource"
minimumIdle="5"
maximumPoolSize="10"
connectionTimeout="300000"
dataSourceClassName="org.mariadb.jdbc.MySQLDataSource"
dataSource.url="jdbc:mysql://localhost:3306/myDatabase?useSSL=false&user=username&password=password"
/>
</Context>
Most helpful comment
I'm not sure what broke on their side, there are a few commits in MariaDB affecting their handling of username. You might want to open an issue over there. From the HikariCP side, you can enable debug logging to see if it provides any more clues.
I will note that you should either use
dataSourceClasNameand "dataSource." properties (for server, port, etc), or don't usedataSourceClassNameat all and just use thejdbcUrl(but continue to use "dataSource." properties).UPDATE: looking at their code, it is possible that the use of the URL is overriding the username. It looks like they expect that, if a URL is used it also contains a "?user=xxxxx&password=yyyy...".
You might eliminate the "dataSource.url" property, and set the server, port, etc. as "dataSource.serverName=localhost" etc. You can see their setters here, just strip off the "set" and lowercase the first letter.