BTM
  1. BTM
  2. BTM-123

Implement java.io.Closable (Java 7) on bitronix.tm.resource.jdbc.PoolingDataSource

    Details

    • Type: Improvement Improvement
    • Status: Resolved Resolved
    • Priority: Major Major
    • Resolution: Not A Bug
    • Affects Version/s: 3.0.0
    • Fix Version/s: 3.0.0
    • Labels:
    • Environment:
      Java 7 / MacOS X
    • Number of attachments :
      0

      Description

      If PoolingDataSource would implement the interface mentioned, it would be possible to close the datasource within a try/close statement like this

      try (PoolingDataSource ds = new PoolingDataSource())

      { // Do some cool stuff; possibly multi-threaded }

        Activity

        Hide
        Brett Wooldridge added a comment - - edited

        The proxies in the upcoming 3.0 release implement all interfaces defined within the JVM environment under which Bitronix is executing.

        For example, if Bitronix is run in a Java 7 environment, the proxy for java.sql.Connection will implement the java.sql.Connection, java.lang.AutoClosable, and java.sql.Wrapper interfaces. If Bitronix is run is a Java 6 environment where the java.lang.AutoClosable is not present, the proxy will obviously not implement that interface.

        Having said that, there are two minor errors in this formal improvement request. The interface in question is actually java.lang.AutoClosable, not java.io.Closable. Though Closable actually extends AutoClosable, it is actually AutoClosable that java.sql classes implement.

        The other minor error is that PoolingDataSource itself is not an implementer of AutoClosable. The example above should read:

        try (Connection c = ds.getConnection())

        { // Do some cool stuff; possible multi-threaded }

        It is Connection that is AutoClosable, not the DataSource itself.

        Show
        Brett Wooldridge added a comment - - edited The proxies in the upcoming 3.0 release implement all interfaces defined within the JVM environment under which Bitronix is executing. For example, if Bitronix is run in a Java 7 environment, the proxy for java.sql.Connection will implement the java.sql.Connection, java.lang.AutoClosable, and java.sql.Wrapper interfaces. If Bitronix is run is a Java 6 environment where the java.lang.AutoClosable is not present, the proxy will obviously not implement that interface. Having said that, there are two minor errors in this formal improvement request. The interface in question is actually java.lang.AutoClosable, not java.io.Closable. Though Closable actually extends AutoClosable, it is actually AutoClosable that java.sql classes implement. The other minor error is that PoolingDataSource itself is not an implementer of AutoClosable. The example above should read: try (Connection c = ds.getConnection()) { // Do some cool stuff; possible multi-threaded } It is Connection that is AutoClosable, not the DataSource itself.
        Hide
        Roland Hauser added a comment - - edited

        Hi Brett

        Yes your right it's AutoClosable; cool approach to support different Java Versions with proxies! The second minor error isn't an mistake in my opinion because following reason (suppose an OSGi environment where you have three datasource related bundles):
        1. Oracle Datasource Bundle, makes the physical connection to the database.
        2. Bundle which manages the Bitronix Transaction Manager, uses bundle 1)
        3. Bundle with Persistence-Manager, uses bundles 2)

        The OSGi enterprise specification defines the interface org.osgi.service.jdbc.DataSourceFactory (see http://www.osgi.org/javadoc/r4v42/org/osgi/service/jdbc/DataSourceFactory.html) which standardizes the way how to instantiate DataSource instances within an OSGi environment. That means, that bundle 1) and 2) export such a datasource-factory as service which makes it possible to other bundles to instantiate a datasource. Well, the problem now raises because the dynamic nature of OSGi. If bundle 3) shall be restarted there is no possibility to destroy the datasource created through bundle 2) because the bundle is still running. In fact, the only bundle which can reliably close the PoolingDataSource instance is currently bundle 2) because it nows the concrete type PoolingDataSource which, in turn, defines a close method. For bundle 3) that means, that the connection pool facaded by the datasource instance will remain open in case bundle 2) won't be restarted. If the exported PoolingDataSource instance would implement the Close/AutoClose interface we could dynamically check all registered datasources in bundle 3) if they are closable, and, could close them in case the bundle gets stopped/restarted.

        Show
        Roland Hauser added a comment - - edited Hi Brett Yes your right it's AutoClosable; cool approach to support different Java Versions with proxies! The second minor error isn't an mistake in my opinion because following reason (suppose an OSGi environment where you have three datasource related bundles): 1. Oracle Datasource Bundle, makes the physical connection to the database. 2. Bundle which manages the Bitronix Transaction Manager, uses bundle 1) 3. Bundle with Persistence-Manager, uses bundles 2) The OSGi enterprise specification defines the interface org.osgi.service.jdbc.DataSourceFactory (see http://www.osgi.org/javadoc/r4v42/org/osgi/service/jdbc/DataSourceFactory.html ) which standardizes the way how to instantiate DataSource instances within an OSGi environment. That means, that bundle 1) and 2) export such a datasource-factory as service which makes it possible to other bundles to instantiate a datasource. Well, the problem now raises because the dynamic nature of OSGi. If bundle 3) shall be restarted there is no possibility to destroy the datasource created through bundle 2) because the bundle is still running. In fact, the only bundle which can reliably close the PoolingDataSource instance is currently bundle 2) because it nows the concrete type PoolingDataSource which, in turn, defines a close method. For bundle 3) that means, that the connection pool facaded by the datasource instance will remain open in case bundle 2) won't be restarted. If the exported PoolingDataSource instance would implement the Close/AutoClose interface we could dynamically check all registered datasources in bundle 3) if they are closable, and, could close them in case the bundle gets stopped/restarted.
        Hide
        Brett Wooldridge added a comment -

        I'm not sure what you're advocating here. PoolingDataSource implements the javax.sql.DataSource interface which is not AutoClosable. I think it would be odd for Bitronix to unilaterally decide to have our DataSource also implement AutoClosable when the architects of Java 7's AutoClosable interface did not see fit to have DataSource implement it. Even if we did so, there would be no way for a user to take advantage of it without tying their code to Bitronix, because no other connection pool or transaction manager would support it.

        With respect to OSGi, we could debate all day about the correct way to handle inter-bundle dependencies, as I used to participate in Equinox OSGi. Without engaging in that debate, I would say that the design of OSGi, the Service Registry, and ServiceTrackers are exactly for this purpose. In your example, restarting bundle 3 is exactly the easiest case. Bundle 3 should acquire a service reference in it's BundleActivator start() method, and release the reference in the stop() method. Bundle 3 is restartable with no need to close the DataSource registered by Bundle 2. The difficult case is actually restarting Bundle 2 or Bundle 1. In which case Bundle 3 needs a ServiceTracker to watch for the disappearance (de-registration) and reappearance of Bundle 2's DataSource and should reacquire it appropriately.

        Either way, this is not the forum for debating OSGi design patterns. But to the original point, I don't think our PoolingDataSource should be defining AutoClosable behavior over and above the current language specification. If and when javax.sql.DataSource is changed to extend java.lang.AutoClosable is when Bitronix will support it.

        Show
        Brett Wooldridge added a comment - I'm not sure what you're advocating here. PoolingDataSource implements the javax.sql.DataSource interface which is not AutoClosable. I think it would be odd for Bitronix to unilaterally decide to have our DataSource also implement AutoClosable when the architects of Java 7's AutoClosable interface did not see fit to have DataSource implement it. Even if we did so, there would be no way for a user to take advantage of it without tying their code to Bitronix, because no other connection pool or transaction manager would support it. With respect to OSGi, we could debate all day about the correct way to handle inter-bundle dependencies, as I used to participate in Equinox OSGi. Without engaging in that debate, I would say that the design of OSGi, the Service Registry, and ServiceTrackers are exactly for this purpose. In your example, restarting bundle 3 is exactly the easiest case. Bundle 3 should acquire a service reference in it's BundleActivator start() method, and release the reference in the stop() method. Bundle 3 is restartable with no need to close the DataSource registered by Bundle 2. The difficult case is actually restarting Bundle 2 or Bundle 1. In which case Bundle 3 needs a ServiceTracker to watch for the disappearance (de-registration) and reappearance of Bundle 2's DataSource and should reacquire it appropriately. Either way, this is not the forum for debating OSGi design patterns. But to the original point, I don't think our PoolingDataSource should be defining AutoClosable behavior over and above the current language specification. If and when javax.sql.DataSource is changed to extend java.lang.AutoClosable is when Bitronix will support it.
        Hide
        Brett Wooldridge added a comment -

        Closing as not a bug. Bitronix JDBC proxies and DataSources implement exactly those interfaces specified by Java and nothing more.

        Show
        Brett Wooldridge added a comment - Closing as not a bug. Bitronix JDBC proxies and DataSources implement exactly those interfaces specified by Java and nothing more.

          People

          • Assignee:
            Ludovic Orban
            Reporter:
            Roland Hauser
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: