PooledConnection#connectUsingDriver, Thread.currentThread().getContextClassLoader() is null

2019-07-24 Thread Clemens Wyss DEV
I tried posting this in the tomcat-users-ml, but I guess it rather fits here:

Context:
Debian GNU/Linux 9 \n \l
java version 1.8.0_162
Tomcat 8.5.35

>From time to time we are facing the follwing exception (call stack):
...
Caused by: java.sql.SQLException: Unable to load class: org.mariadb.jdbc.Driver 
from ClassLoader:java.net.URLClassLoader@4c873330;ClassLoader:null
at 
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:292)
at 
org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:212)
at 
org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:736)
at 
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:668)
at 
org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:198)
at 
org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132)
at org.apache.torque.Torque.getConnection(Torque.java:924)
... 53 common frames omitted
Caused by: java.lang.ClassNotFoundException: Unable to load class: 
org.mariadb.jdbc.Driver from 
ClassLoader:java.net.URLClassLoader@4c873330;ClassLoader:null
at 
org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:56)
at 
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:280)
... 59 common frames omitted
Caused by: java.lang.ClassNotFoundException: Classloader is null
at 
org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:40)
... 60 common frames omitted

According to the code (in PooledConnection# connectUsingDriver) 
Thread.currentThread().getContextClassLoader() returns null

Googling for " Thread.currentThread().getContextClassLoader() is null" the 
common demoniator seems to be `getContextClassLoader can be null`. If this is 
true there should be
a) a null-check in PooledConnection# connectUsingDriver
b) if null, then there should be a fallback-Classloader (the system class 
laoder?)

WDYT ?

Or any ideas why the given exception pops up from time to time

Thx
Clemens


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



AW: PooledConnection#connectUsingDriver, Thread.currentThread().getContextClassLoader() is null

2019-07-24 Thread Clemens Wyss DEV
< mais c'était rapide 😉 >
>+1
should/can I file a bug?

> init at bootstrap the pool (initial size) to ensure it is in one tomcat 
> classloader
how would you achieve this? By setting «initialSize» to «maxSize» in 
PoolProperties?

--
Von: Romain Manni-Bucau  
Gesendet: Donnerstag, 25. Juli 2019 07:30
An: Tomcat Developers List 
Betreff: Re: PooledConnection#connectUsingDriver, 
Thread.currentThread().getContextClassLoader() is null

+1, there is no real other option AFAIK until you init at bootstrap the pool 
(initial size) to ensure it is in one tomcat classloader.

Le jeu. 25 juil. 2019 à 07:08, Clemens Wyss DEV <mailto:clemens...@mysign.ch> a 
écrit :
I tried posting this in the tomcat-users-ml, but I guess it rather fits here:
--
Context:
Debian GNU/Linux 9 \n \l
java version 1.8.0_162
Tomcat 8.5.35

From time to time we are facing the follwing exception (call stack):
...
Caused by: java.sql.SQLException: Unable to load class: org.mariadb.jdbc.Driver 
from ClassLoader:http://java.net.URLClassLoader@4c873330;ClassLoader:null
        at 
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:292)
        at 
org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:212)
        at 
org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:736)
        at 
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:668)
        at 
org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:198)
        at 
org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132)
        at org.apache.torque.Torque.getConnection(Torque.java:924)
        ... 53 common frames omitted
Caused by: java.lang.ClassNotFoundException: Unable to load class: 
org.mariadb.jdbc.Driver from 
ClassLoader:http://java.net.URLClassLoader@4c873330;ClassLoader:null
        at 
org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:56)
        at 
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:280)
        ... 59 common frames omitted
Caused by: java.lang.ClassNotFoundException: Classloader is null
        at 
org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:40)
        ... 60 common frames omitted

According to the code (in PooledConnection# connectUsingDriver) 
Thread.currentThread().getContextClassLoader() returns null

Googling for " Thread.currentThread().getContextClassLoader() is null" the 
common demoniator seems to be `getContextClassLoader can be null`. If this is 
true there should be
a) a null-check in PooledConnection# connectUsingDriver
b) if null, then there should be a fallback-Classloader (the system class 
laoder?)

WDYT ?

Or any ideas why the given exception pops up from time to time

Thx
Clemens


-
To unsubscribe, e-mail: mailto:dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: mailto:dev-h...@tomcat.apache.org


AW: PooledConnection#connectUsingDriver, Thread.currentThread().getContextClassLoader() is null

2019-07-28 Thread Clemens Wyss DEV
https://bz.apache.org/bugzilla/show_bug.cgi?id=63612

> with a small project reproducing it?
Unfortunately not easily extractable/reproducible

Maybe :

th = new Thread() {
@Override
public void run() {
« do something that requires a connection from the pool »
}
} ;
th.set getContextClassLoader( null ) ;
th.run() ;

Von: Romain Manni-Bucau 
Gesendet: Donnerstag, 25. Juli 2019 08:06
An: Tomcat Developers List 
Betreff: Re: PooledConnection#connectUsingDriver, 
Thread.currentThread().getContextClassLoader() is null


Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV 
mailto:clemens...@mysign.ch>> a écrit :
< mais c'était rapide 😉 >
>+1
should/can I file a bug?

Guess so, with a small project reproducing it?


> init at bootstrap the pool (initial size) to ensure it is in one tomcat 
> classloader
how would you achieve this? By setting «initialSize» to «maxSize» in 
PoolProperties?

1 should be sufficient, however tomcat-jdbc (vs dbcp2 for instance) loads it 
per connection and not once for all the pool 
(https://github.com/apache/tomcat/blob/master/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java#L196)
 which is likely 1. Bad for perf but moreover 2. Buggy if the classloader 
changes between usages of a connection in apps. Loader, driver should be loaded 
once and potentially the datasource be duplicated per app if needed (driver in 
the app) IMHO. This would also fix your NPE transitively ;).




--
Von: Romain Manni-Bucau mailto:rmannibu...@gmail.com>>
Gesendet: Donnerstag, 25. Juli 2019 07:30
An: Tomcat Developers List mailto:dev@tomcat.apache.org>>
Betreff: Re: PooledConnection#connectUsingDriver, 
Thread.currentThread().getContextClassLoader() is null

+1, there is no real other option AFAIK until you init at bootstrap the pool 
(initial size) to ensure it is in one tomcat classloader.

Le jeu. 25 juil. 2019 à 07:08, Clemens Wyss DEV 
<mailto:clemens...@mysign.ch<mailto:clemens...@mysign.ch>> a écrit :
I tried posting this in the tomcat-users-ml, but I guess it rather fits here:
--
Context:
Debian GNU/Linux 9 \n \l
java version 1.8.0_162
Tomcat 8.5.35

From time to time we are facing the follwing exception (call stack):
...
Caused by: java.sql.SQLException: Unable to load class: org.mariadb.jdbc.Driver 
from ClassLoader:http://java.net.URLClassLoader@4c873330;ClassLoader:null
at 
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:292)
at 
org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:212)
at 
org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:736)
at 
org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:668)
at 
org.apache.tomcat.jdbc.pool.ConnectionPool.getConnection(ConnectionPool.java:198)
at 
org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:132)
at org.apache.torque.Torque.getConnection(Torque.java:924)
... 53 common frames omitted
Caused by: java.lang.ClassNotFoundException: Unable to load class: 
org.mariadb.jdbc.Driver from 
ClassLoader:http://java.net.URLClassLoader@4c873330;ClassLoader:null
at 
org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:56)
at 
org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:280)
... 59 common frames omitted
Caused by: java.lang.ClassNotFoundException: Classloader is null
at 
org.apache.tomcat.jdbc.pool.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:40)
... 60 common frames omitted

According to the code (in PooledConnection# connectUsingDriver) 
Thread.currentThread().getContextClassLoader() returns null

Googling for " Thread.currentThread().getContextClassLoader() is null" the 
common demoniator seems to be `getContextClassLoader can be null`. If this is 
true there should be
a) a null-check in PooledConnection# connectUsingDriver
b) if null, then there should be a fallback-Classloader (the system class 
laoder?)

WDYT ?

Or any ideas why the given exception pops up from time to time

Thx
Clemens


-
To unsubscribe, e-mail: 
mailto:dev-unsubscr...@tomcat.apache.org<mailto:dev-unsubscr...@tomcat.apache.org>
For additional commands, e-mail: 
mailto:dev-h...@tomcat.apache.org<mailto:dev-h...@tomcat.apache.org>


AW: PooledConnection#connectUsingDriver, Thread.currentThread().getContextClassLoader() is null

2019-07-30 Thread Clemens Wyss DEV
> recent tomcat version
9.0.22 has the same class loading code as 8.5.35
https://jar-download.com/artifacts/org.apache.tomcat/tomcat-jdbc/9.0.22/source-code/org/apache/tomcat/jdbc/pool/PooledConnection.java

driver = (java.sql.Driver)
ClassLoaderUtil.loadClass(
poolProperties.getDriverClassName(),
PooledConnection.class.getClassLoader(),
Thread.currentThread().getContextClassLoader()
).getConstructor().newInstance();


Von: Romain Manni-Bucau 
Gesendet: Montag, 29. Juli 2019 09:35
An: Tomcat Developers List 
Betreff: Re: PooledConnection#connectUsingDriver, 
Thread.currentThread().getContextClassLoader() is null

Can you give a try on a more recent tomcat version? Seems it works with master 
version since the tomcat-jdbc module classloader is tried first before the tccl?
Tested with:


public class PooledConnectionTest {
@Test
public void avoidNPEWhenTcclIsNull() throws SQLException {
final PoolProperties poolProperties = new PoolProperties();
poolProperties.setDriverClassName("org.h2.Driver");
poolProperties.setUsername("sa");
poolProperties.setPassword("");

poolProperties.setUrl("jdbc:h2:mem:PooledConnectionTest_avoidNPEWhenTcclIsNull");
poolProperties.setMaxIdle(1);
poolProperties.setMinIdle(1);
poolProperties.setInitialSize(1);
poolProperties.setMaxActive(1);

ensureDataSourceIsValid(poolProperties);

final Thread thread = Thread.currentThread();
final ClassLoader testLoader = thread.getContextClassLoader();
thread.setContextClassLoader(null);
try {
ensureDataSourceIsValid(poolProperties);
} finally {
thread.setContextClassLoader(testLoader);
}
}

private void ensureDataSourceIsValid(final PoolProperties poolProperties) 
throws SQLException {
final DataSource dataSource = new DataSource(poolProperties);
try (final Connection connection = dataSource.getConnection()) {
assertTrue(connection.isValid(5));
} finally {
dataSource.close();
}
}
}

Romain Manni-Bucau
@rmannibucau<https://twitter.com/rmannibucau> |  
Blog<https://rmannibucau.metawerx.net/> | Old 
Blog<http://rmannibucau.wordpress.com> | Github<https://github.com/rmannibucau> 
| LinkedIn<https://www.linkedin.com/in/rmannibucau> | 
Book<https://www.packtpub.com/application-development/java-ee-8-high-performance>


Le lun. 29 juil. 2019 à 07:36, Clemens Wyss DEV 
mailto:clemens...@mysign.ch>> a écrit :
https://bz.apache.org/bugzilla/show_bug.cgi?id=63612

> with a small project reproducing it?
Unfortunately not easily extractable/reproducible

Maybe :

th = new Thread() {
@Override
public void run() {
« do something that requires a connection from the pool »
}
} ;
th.set getContextClassLoader( null ) ;
th.run() ;

Von: Romain Manni-Bucau mailto:rmannibu...@gmail.com>>
Gesendet: Donnerstag, 25. Juli 2019 08:06
An: Tomcat Developers List mailto:dev@tomcat.apache.org>>
Betreff: Re: PooledConnection#connectUsingDriver, 
Thread.currentThread().getContextClassLoader() is null


Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV 
mailto:clemens...@mysign.ch>> a écrit :
< mais c'était rapide 😉 >
>+1
should/can I file a bug?

Guess so, with a small project reproducing it?


> init at bootstrap the pool (initial size) to ensure it is in one tomcat 
> classloader
how would you achieve this? By setting «initialSize» to «maxSize» in 
PoolProperties?

1 should be sufficient, however tomcat-jdbc (vs dbcp2 for instance) loads it 
per connection and not once for all the pool 
(https://github.com/apache/tomcat/blob/master/modules/jdbc-pool/src/main/java/org/apache/tomcat/jdbc/pool/PooledConnection.java#L196)
 which is likely 1. Bad for perf but moreover 2. Buggy if the classloader 
changes between usages of a connection in apps. Loader, driver should be loaded 
once and potentially the datasource be duplicated per app if needed (driver in 
the app) IMHO. This would also fix your NPE transitively ;).




--
Von: Romain Manni-Bucau mailto:rmannibu...@gmail.com>>
Gesendet: Donnerstag, 25. Juli 2019 07:30
An: Tomcat Developers List mailto:dev@tomcat.apache.org>>
Betreff: Re: PooledConnection#connectUsingDriver, 
Thread.currentThread().getContextClassLoader() is null

+1, there is no real other option AFAIK until you init at bootstrap the pool 
(initial size) to ensure it is in one tomcat classloader.

Le jeu. 25 juil. 2019 à 07:08, Clemens Wyss DEV 
<mailto:clemens...@mysign.ch<mailto:clemens...@mysign.ch>> a écrit :
I tried posting this in the tomcat-users-ml, but I guess it rather fits here:
-