Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
> Grzegorz Grzybek : > Hello > I added a comment to > https://github.com/pgjdbc/pgjdbc/issues/1476#issuecomment-497635922 Thanks for working on this! (I've worked around this by using a karaf feature to load the PostgreSQL JDBC driver, because then I can avoid reloading the PostgreSQL JDBC bundle when loading a new application needing it... most of the time...:-) ) -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/ops4j/864l59ksbm.fsf%40dod.no. For more options, visit https://groups.google.com/d/optout.
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
Hello I added a comment to https://github.com/pgjdbc/pgjdbc/issues/1476#issuecomment-497635922 regards Grzegorz Grzybek pt., 31 maj 2019 o 10:48 Grzegorz Grzybek napisał(a): > Hello > > Interesting case. I did some work in pax-jdbc and was especially happy > with how PostgreSQL driver natively registers > org.osgi.service.jdbc.DataSourceFactory OSGi service. But tbh, even if I > did lot of pooling/non-pooling, XA/non-XA tests (under or without several > TX managers), I never tried (shame!) restarting postgresql driver bundle!. > > With this etc/org.ops4j.datasource-postgres.cfg configuration: > > osgi.jdbc.driver.class=org.postgresql.Driver > dataSourceName=postgres > dataSourceType=DataSource > jdbc.url=jdbc:postgresql://localhost:5432/reportdb > jdbc.user=xxx > jdbc.password=xxx > > pool=dbcp2 > # dbcp2 specific configuration of > org.apache.commons.pool2.impl.GenericObjectPoolConfig > pool.minIdle = 10 > pool.maxTotal = 100 > pool.blockWhenExhausted = true > pool.maxWaitMillis = 2000 > pool.testOnBorrow = true > pool.testWhileIdle = false > pool.timeBetweenEvictionRunsMillis = 12 > pool.evictionPolicyClassName = > org.apache.commons.pool2.impl.DefaultEvictionPolicy > > # dbcp2 specific configuration of > org.apache.commons.dbcp2.PoolableConnectionFactory > factory.maxConnLifetimeMillis = 3 > factory.validationQuery = select schema_name from > information_schema.schemata > factory.validationQueryTimeout = 2 > > I also had this problem: > > java.sql.SQLException: No suitable driver found for > jdbc:postgresql://localhost:5432/reportdb?loglevel[…] > at java.sql.DriverManager.getConnection(DriverManager.java:689) ~[?:?] > at java.sql.DriverManager.getConnection(DriverManager.java:247) ~[?:?] > at > org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:86) > ~[?:?] > at > org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:71) > ~[?:?] > at > org.apache.commons.dbcp2.DataSourceConnectionFactory.createConnection(DataSourceConnectionFactory.java:44) > ~[?:?] > at > org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:256) > ~[?:?] > at > org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:889) > ~[?:?] > at > org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:433) > ~[?:?] > at > org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:362) > ~[?:?] > at > org.apache.commons.dbcp2.PoolingDataSource.getConnection(PoolingDataSource.java:134) > ~[?:?] > at > org.apache.karaf.jdbc.internal.JdbcConnector.connect(JdbcConnector.java:49) > ~[?:?] > at > org.apache.karaf.jdbc.internal.JdbcConnector.createStatement(JdbcConnector.java:61) > ~[?:?] > at > org.apache.karaf.jdbc.internal.JdbcServiceImpl.query(JdbcServiceImpl.java:139) > ~[?:?] > at > org.apache.karaf.jdbc.command.QueryCommand.execute(QueryCommand.java:50) > ~[?:?] > ... > > because, underneath there's always java.sql.DriverManager.getConnection() > call. And postgresql driver unregisters the driver when bundle stops, but > never registers it again when it starts (because the registration was in > static{} block, not in BundleActivator.start(). > > simply refreshing postgresql driver bundle after restarting did the trick > (new classloader → static{} block invoked again). > > I'll switch to https://github.com/pgjdbc/pgjdbc/issues/1476 to continue > the thread. > > regards > Grzegorz Grzybek > > czw., 2 maj 2019 o 07:15 'Christoph Läubrich' via OPS4J < > ops4j@googlegroups.com> napisał(a): > >> Correctly, the PGDataSourceFactory should simply instatiate the required >> class directly, no need for using the DriverManager at all! >> See [1] line 131 or [2] line 40, 47, 54 for example. >> >> The problem with DataSourceFactory is that it does not support dynmics >> or different class-loader spaces very well. >> >> [1] >> >> https://github.com/MariaDB/mariadb-connector-j/blob/1d831664f7d871ccd871fb9b2137ce3cd3421c4d/src/main/java/org/mariadb/jdbc/internal/osgi/MariaDbDataSourceFactory.java >> >> [2] >> >> https://github.com/Microsoft/mssql-jdbc/blob/dev/src/main/java/com/microsoft/sqlserver/jdbc/osgi/SQLServerDataSourceFactory.java >> >> Am 01.05.19 um 16:49 schrieb Steinar Bang: >> >> 'Christoph Läubrich' via OPS4J > jypxa39uh5tlh3mboc...@public.gmane.org>: >> > >> >> DriverManger.register/unregister can't work reliable in OSGi >> >> (especially with static insitilizer), thus always the >> >> DataSourceFactory should be used instead! >> > >> > PGDataSourceFactory is currently implemented using the regular PG JDBC >> > driver, ie. the Driver class, which in turn uses the DriverManager in >> > rt.jar. >> > >> > So the fix should be to change the implementation of PGDataSourceFactory >> > to not use the Driver class via DriverManager? Maybe >> > PGDataSourceFactory should create and own a Driver instance? >> > >> >> -- >> -- >> -- >> OPS4J - http://www.ops4j.org -
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
Hello Interesting case. I did some work in pax-jdbc and was especially happy with how PostgreSQL driver natively registers org.osgi.service.jdbc.DataSourceFactory OSGi service. But tbh, even if I did lot of pooling/non-pooling, XA/non-XA tests (under or without several TX managers), I never tried (shame!) restarting postgresql driver bundle!. With this etc/org.ops4j.datasource-postgres.cfg configuration: osgi.jdbc.driver.class=org.postgresql.Driver dataSourceName=postgres dataSourceType=DataSource jdbc.url=jdbc:postgresql://localhost:5432/reportdb jdbc.user=xxx jdbc.password=xxx pool=dbcp2 # dbcp2 specific configuration of org.apache.commons.pool2.impl.GenericObjectPoolConfig pool.minIdle = 10 pool.maxTotal = 100 pool.blockWhenExhausted = true pool.maxWaitMillis = 2000 pool.testOnBorrow = true pool.testWhileIdle = false pool.timeBetweenEvictionRunsMillis = 12 pool.evictionPolicyClassName = org.apache.commons.pool2.impl.DefaultEvictionPolicy # dbcp2 specific configuration of org.apache.commons.dbcp2.PoolableConnectionFactory factory.maxConnLifetimeMillis = 3 factory.validationQuery = select schema_name from information_schema.schemata factory.validationQueryTimeout = 2 I also had this problem: java.sql.SQLException: No suitable driver found for jdbc:postgresql://localhost:5432/reportdb?loglevel[…] at java.sql.DriverManager.getConnection(DriverManager.java:689) ~[?:?] at java.sql.DriverManager.getConnection(DriverManager.java:247) ~[?:?] at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:86) ~[?:?] at org.postgresql.ds.common.BaseDataSource.getConnection(BaseDataSource.java:71) ~[?:?] at org.apache.commons.dbcp2.DataSourceConnectionFactory.createConnection(DataSourceConnectionFactory.java:44) ~[?:?] at org.apache.commons.dbcp2.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:256) ~[?:?] at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:889) ~[?:?] at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:433) ~[?:?] at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:362) ~[?:?] at org.apache.commons.dbcp2.PoolingDataSource.getConnection(PoolingDataSource.java:134) ~[?:?] at org.apache.karaf.jdbc.internal.JdbcConnector.connect(JdbcConnector.java:49) ~[?:?] at org.apache.karaf.jdbc.internal.JdbcConnector.createStatement(JdbcConnector.java:61) ~[?:?] at org.apache.karaf.jdbc.internal.JdbcServiceImpl.query(JdbcServiceImpl.java:139) ~[?:?] at org.apache.karaf.jdbc.command.QueryCommand.execute(QueryCommand.java:50) ~[?:?] ... because, underneath there's always java.sql.DriverManager.getConnection() call. And postgresql driver unregisters the driver when bundle stops, but never registers it again when it starts (because the registration was in static{} block, not in BundleActivator.start(). simply refreshing postgresql driver bundle after restarting did the trick (new classloader → static{} block invoked again). I'll switch to https://github.com/pgjdbc/pgjdbc/issues/1476 to continue the thread. regards Grzegorz Grzybek czw., 2 maj 2019 o 07:15 'Christoph Läubrich' via OPS4J < ops4j@googlegroups.com> napisał(a): > Correctly, the PGDataSourceFactory should simply instatiate the required > class directly, no need for using the DriverManager at all! > See [1] line 131 or [2] line 40, 47, 54 for example. > > The problem with DataSourceFactory is that it does not support dynmics > or different class-loader spaces very well. > > [1] > > https://github.com/MariaDB/mariadb-connector-j/blob/1d831664f7d871ccd871fb9b2137ce3cd3421c4d/src/main/java/org/mariadb/jdbc/internal/osgi/MariaDbDataSourceFactory.java > > [2] > > https://github.com/Microsoft/mssql-jdbc/blob/dev/src/main/java/com/microsoft/sqlserver/jdbc/osgi/SQLServerDataSourceFactory.java > > Am 01.05.19 um 16:49 schrieb Steinar Bang: > >> 'Christoph Läubrich' via OPS4J jypxa39uh5tlh3mboc...@public.gmane.org>: > > > >> DriverManger.register/unregister can't work reliable in OSGi > >> (especially with static insitilizer), thus always the > >> DataSourceFactory should be used instead! > > > > PGDataSourceFactory is currently implemented using the regular PG JDBC > > driver, ie. the Driver class, which in turn uses the DriverManager in > > rt.jar. > > > > So the fix should be to change the implementation of PGDataSourceFactory > > to not use the Driver class via DriverManager? Maybe > > PGDataSourceFactory should create and own a Driver instance? > > > > -- > -- > -- > OPS4J - http://www.ops4j.org - ops4j@googlegroups.com > > --- > You received this message because you are subscribed to the Google Groups > "OPS4J" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to ops4j+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com ---
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
Correctly, the PGDataSourceFactory should simply instatiate the required class directly, no need for using the DriverManager at all! See [1] line 131 or [2] line 40, 47, 54 for example. The problem with DataSourceFactory is that it does not support dynmics or different class-loader spaces very well. [1] https://github.com/MariaDB/mariadb-connector-j/blob/1d831664f7d871ccd871fb9b2137ce3cd3421c4d/src/main/java/org/mariadb/jdbc/internal/osgi/MariaDbDataSourceFactory.java [2] https://github.com/Microsoft/mssql-jdbc/blob/dev/src/main/java/com/microsoft/sqlserver/jdbc/osgi/SQLServerDataSourceFactory.java Am 01.05.19 um 16:49 schrieb Steinar Bang: 'Christoph Läubrich' via OPS4J : DriverManger.register/unregister can't work reliable in OSGi (especially with static insitilizer), thus always the DataSourceFactory should be used instead! PGDataSourceFactory is currently implemented using the regular PG JDBC driver, ie. the Driver class, which in turn uses the DriverManager in rt.jar. So the fix should be to change the implementation of PGDataSourceFactory to not use the Driver class via DriverManager? Maybe PGDataSourceFactory should create and own a Driver instance? -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
> 'Christoph Läubrich' via OPS4J > : > DriverManger.register/unregister can't work reliable in OSGi > (especially with static insitilizer), thus always the > DataSourceFactory should be used instead! PGDataSourceFactory is currently implemented using the regular PG JDBC driver, ie. the Driver class, which in turn uses the DriverManager in rt.jar. So the fix should be to change the implementation of PGDataSourceFactory to not use the Driver class via DriverManager? Maybe PGDataSourceFactory should create and own a Driver instance? -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
DriverManger.register/unregister can't work reliable in OSGi (especially with static insitilizer), thus always the DataSourceFactory should be used instead! Am 30.04.19 um 19:43 schrieb Steinar Bang: Christian Schneider : I see no calls to DriverManager in https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/osgi/PGBundleActivator.java The DriverManager isn't called directly from the PGBundleActivator. 1. DriverManager.registerDriver() is called from Driver.register() https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/Driver.java#L720 2. Driver.register() is called from a static initializer in the Driver class https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/Driver.java#L72 3. DriverManager.deregisterDriver() is called from Driver.deregister() https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/Driver.java#L737 4. Driver.deregister() is called from the PGBundleActivator.stop() method https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/osgi/PGBundleActivator.java#L56 It only registers and unregisters the DataSourceFactory service which looks correct. Yes, that bit is correct, and populates to my DS components that has @Reference to DatasourceFactory (the old service is unbound and the activate methods are called using the new service). Not sure about the call to Driver.deregister though. This might cause the issue. See comment in the issue https://github.com/pgjdbc/pgjdbc/issues/1476#issuecomment-487370634 -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
> Christian Schneider > : > I see no calls to DriverManager in > https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/osgi/PGBundleActivator.java The DriverManager isn't called directly from the PGBundleActivator. 1. DriverManager.registerDriver() is called from Driver.register() https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/Driver.java#L720 2. Driver.register() is called from a static initializer in the Driver class https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/Driver.java#L72 3. DriverManager.deregisterDriver() is called from Driver.deregister() https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/Driver.java#L737 4. Driver.deregister() is called from the PGBundleActivator.stop() method https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/osgi/PGBundleActivator.java#L56 > It only registers and unregisters the DataSourceFactory service which looks > correct. Yes, that bit is correct, and populates to my DS components that has @Reference to DatasourceFactory (the old service is unbound and the activate methods are called using the new service). > Not sure about the call to Driver.deregister though. > This might cause the issue. See comment in the issue https://github.com/pgjdbc/pgjdbc/issues/1476#issuecomment-487370634 -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
I see no calls to DriverManager in https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/osgi/PGBundleActivator.java It only registers and unregisters the DataSourceFactory service which looks correct. Not sure about the call to Driver.deregister though. This might cause the issue. Christian Am Mo., 29. Apr. 2019 um 18:58 Uhr schrieb Steinar Bang : > I ran into a problem with the PostgreSQL JDBC driver running as an OSGi > bundle in karaf: > https://github.com/pgjdbc/pgjdbc/issues/1476 > > In short: the bundle works before restart, but after restart > DataSouce.getConnection() is unable to find the JDBC driver. > > I've debugged through what happens, and the PGBundleActivator() seems to > do the right thing: > 1. Call DriverManager.registerDriver() on bundle start > 2. Call DriverManagerderegisterDriver() on bundle stop > 3. Call DriverManager.registerDriver() again when the bundle restarts > (all of these in rt.jar) > > However, after the second DriverManager.registerDriver() the > DriverManager.getConnection(String url, java.util.Properties info, > Class caller) > method fails because DriverManager.isDriverAllowed(Driver driver, > ClassLoader classLoader) > fails (all of these in rt.jar). > > And what fails in the isDriverAllowed() method is the comparison between > driver.getClass() and Class.forName(driver.getClass().getName()) fails. > > Sounds like an OSGi classloader issue...? > > How does the pax-jdbc bundles providing a DataSourceFactory handle JDBC > driver registration and unregistration? > > Thanks! > > > - Steinar > > -- > -- > -- > OPS4J - http://www.ops4j.org - ops4j@googlegroups.com > > --- > You received this message because you are subscribed to the Google Groups > "OPS4J" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to ops4j+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- -- Christian Schneider http://www.liquid-reality.de Computer Scientist http://www.adobe.com -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Question to pax-jdbc devs: how do you handle DataSourceFactory bundle restart?
I ran into a problem with the PostgreSQL JDBC driver running as an OSGi bundle in karaf: https://github.com/pgjdbc/pgjdbc/issues/1476 In short: the bundle works before restart, but after restart DataSouce.getConnection() is unable to find the JDBC driver. I've debugged through what happens, and the PGBundleActivator() seems to do the right thing: 1. Call DriverManager.registerDriver() on bundle start 2. Call DriverManagerderegisterDriver() on bundle stop 3. Call DriverManager.registerDriver() again when the bundle restarts (all of these in rt.jar) However, after the second DriverManager.registerDriver() the DriverManager.getConnection(String url, java.util.Properties info, Class caller) method fails because DriverManager.isDriverAllowed(Driver driver, ClassLoader classLoader) fails (all of these in rt.jar). And what fails in the isDriverAllowed() method is the comparison between driver.getClass() and Class.forName(driver.getClass().getName()) fails. Sounds like an OSGi classloader issue...? How does the pax-jdbc bundles providing a DataSourceFactory handle JDBC driver registration and unregistration? Thanks! - Steinar -- -- -- OPS4J - http://www.ops4j.org - ops4j@googlegroups.com --- You received this message because you are subscribed to the Google Groups "OPS4J" group. To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.