You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Clemens Wyss DEV <cl...@mysign.ch> on 2019/07/25 05:08:51 UTC

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

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


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

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Finally managed to reproduce it in a test:
https://github.com/apache/tomcat/pull/183

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 mar. 30 juil. 2019 à 14:21, Romain Manni-Bucau <rm...@gmail.com> a
écrit :

> Yes, got caught by PooledConnection.class.getClassLoader() which tries to
> load the driver from tomcat/lib first (common.loader actually) so if you
> put your driver there it will work in your case. Stays the bug when the
> driver is only in the webapp.
>
>
> 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 mar. 30 juil. 2019 à 13:30, Clemens Wyss DEV <cl...@mysign.ch> a
> écrit :
>
>> > 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 <rm...@gmail.com>
>> *Gesendet:* Montag, 29. Juli 2019 09:35
>> *An:* Tomcat Developers List <de...@tomcat.apache.org>
>> *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 <cl...@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 <rm...@gmail.com>
>> *Gesendet:* Donnerstag, 25. Juli 2019 08:06
>> *An:* Tomcat Developers List <de...@tomcat.apache.org>
>> *Betreff:* Re: PooledConnection#connectUsingDriver,
>> Thread.currentThread().getContextClassLoader() is null
>>
>>
>>
>>
>>
>> Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <cl...@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 <rm...@gmail.com>
>> Gesendet: Donnerstag, 25. Juli 2019 07:30
>> An: Tomcat Developers List <de...@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:
>> clemensdev@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-unsubscribe@tomcat.apache.org
>> For additional commands, e-mail: mailto:dev-help@tomcat.apache.org
>>
>>

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

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Yes, got caught by PooledConnection.class.getClassLoader() which tries to
load the driver from tomcat/lib first (common.loader actually) so if you
put your driver there it will work in your case. Stays the bug when the
driver is only in the webapp.


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 mar. 30 juil. 2019 à 13:30, Clemens Wyss DEV <cl...@mysign.ch> a
écrit :

> > 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 <rm...@gmail.com>
> *Gesendet:* Montag, 29. Juli 2019 09:35
> *An:* Tomcat Developers List <de...@tomcat.apache.org>
> *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 <cl...@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 <rm...@gmail.com>
> *Gesendet:* Donnerstag, 25. Juli 2019 08:06
> *An:* Tomcat Developers List <de...@tomcat.apache.org>
> *Betreff:* Re: PooledConnection#connectUsingDriver,
> Thread.currentThread().getContextClassLoader() is null
>
>
>
>
>
> Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <cl...@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 <rm...@gmail.com>
> Gesendet: Donnerstag, 25. Juli 2019 07:30
> An: Tomcat Developers List <de...@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:
> clemensdev@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-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: mailto:dev-help@tomcat.apache.org
>
>

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

Posted by Clemens Wyss DEV <cl...@mysign.ch>.
> 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 <rm...@gmail.com>
Gesendet: Montag, 29. Juli 2019 09:35
An: Tomcat Developers List <de...@tomcat.apache.org>
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 <cl...@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 <rm...@gmail.com>>
Gesendet: Donnerstag, 25. Juli 2019 08:06
An: Tomcat Developers List <de...@tomcat.apache.org>>
Betreff: Re: PooledConnection#connectUsingDriver, Thread.currentThread().getContextClassLoader() is null


Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <cl...@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 <rm...@gmail.com>>
Gesendet: Donnerstag, 25. Juli 2019 07:30
An: Tomcat Developers List <de...@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 <ma...@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-unsubscribe@tomcat.apache.org<ma...@tomcat.apache.org>
For additional commands, e-mail: mailto:dev-help@tomcat.apache.org<ma...@tomcat.apache.org>

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

Posted by Romain Manni-Bucau <rm...@gmail.com>.
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 <cl...@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 <rm...@gmail.com>
> *Gesendet:* Donnerstag, 25. Juli 2019 08:06
> *An:* Tomcat Developers List <de...@tomcat.apache.org>
> *Betreff:* Re: PooledConnection#connectUsingDriver,
> Thread.currentThread().getContextClassLoader() is null
>
>
>
>
>
> Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <cl...@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 <rm...@gmail.com>
> Gesendet: Donnerstag, 25. Juli 2019 07:30
> An: Tomcat Developers List <de...@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:
> clemensdev@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-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: mailto:dev-help@tomcat.apache.org
>
>

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

Posted by Clemens Wyss DEV <cl...@mysign.ch>.
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 <rm...@gmail.com>
Gesendet: Donnerstag, 25. Juli 2019 08:06
An: Tomcat Developers List <de...@tomcat.apache.org>
Betreff: Re: PooledConnection#connectUsingDriver, Thread.currentThread().getContextClassLoader() is null


Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <cl...@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 <rm...@gmail.com>>
Gesendet: Donnerstag, 25. Juli 2019 07:30
An: Tomcat Developers List <de...@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 <ma...@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-unsubscribe@tomcat.apache.org<ma...@tomcat.apache.org>
For additional commands, e-mail: mailto:dev-help@tomcat.apache.org<ma...@tomcat.apache.org>

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

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <cl...@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 <rm...@gmail.com>
> Gesendet: Donnerstag, 25. Juli 2019 07:30
> An: Tomcat Developers List <de...@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:
> clemensdev@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-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: mailto:dev-help@tomcat.apache.org
>

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

Posted by Clemens Wyss DEV <cl...@mysign.ch>.
< 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 <rm...@gmail.com> 
Gesendet: Donnerstag, 25. Juli 2019 07:30
An: Tomcat Developers List <de...@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 <ma...@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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: mailto:dev-help@tomcat.apache.org

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

Posted by Romain Manni-Bucau <rm...@gmail.com>.
+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 <cl...@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: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-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>