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 <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 <rmannibu...@gmail.com>
> *Gesendet:* Donnerstag, 25. Juli 2019 08:06
> *An:* Tomcat Developers List <dev@tomcat.apache.org>
> *Betreff:* Re: PooledConnection#connectUsingDriver,
> Thread.currentThread().getContextClassLoader() is null
>
>
>
>
>
> Le jeu. 25 juil. 2019 à 07:46, Clemens Wyss DEV <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 <rmannibu...@gmail.com>
> Gesendet: Donnerstag, 25. Juli 2019 07:30
> An: Tomcat Developers List <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> 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
>
>

Reply via email to