5 Replies Latest reply on May 11, 2006 11:24 AM by esword

    Possible fix for driver class loading issue in LocalManagedC

      I am trying to deploy a fully isolated ear (i.e. all jars that I use are in the ear; no leaking of jars into the main lib directory). However, the app uses a couple of datasource connections, and I am hitting a problem encountered by others over the years. It is best summarized in Jira issue JBAS-1042. The issue is the same in JBoss 4.0.3SP1, which is what I am using.

      I figured out that the exception caused by the strange class loading behavior in DriverManager.getDriver() is actually only thrown the first time you try to access the driver. This is because once the driver is set in LocalManagedConnectionFactory.getDriver() by line 277:

      driver = (Driver)clazz.newInstance();
      

      it is never cleared. So even though an exception is thrown the first time through because isDriverLoadedForURL(url) always returns false, the check for (driver!=null) at the start of the LocalManagedConnectionFactory.getDriver() will return the driver for all future uses.

      It seems like the method should be changed in one of two ways:
      1) Change line 277 to set a local Driver variable rather than the object member variable. That way the member variable is only set by the isDriverLoadedForURL check and it will always fail (thus enforcing always going through the DriverManager). Or,

      2) (My preferred change) After the 3rd call to isDriverLoadedForURL, check if driver != null and, if so, do what DriverManager does and call driver.acceptsURL(url). That way, the (erroneous) exception won't be thrown the first time through at all.

      Is there any reason not to allow this functionality?



        • 1. Re: Possible fix for driver class loading issue in LocalMana
          weston.price

          I am not sure what your issue is. Your link goes nowhere as

          http://www.jboss.com/JBAS-1042

          resolves to nothing.

          What exception are you seeing?

          • 2. Re: Possible fix for driver class loading issue in LocalMana

            My apologies on the link. Not sure how the paste went bad. Here it is:

            http://jira.jboss.com/jira/browse/JBAS-1042

            The exception is that when a Driver class is loaded and registered by an ear-specific class loader, the DriverManager will not return it when DriverManager.getDriver(myURL) is called.

            • 3. Re: Possible fix for driver class loading issue in LocalMana
              weston.price

              So, am I to assume the following:

              You deploy your datasource scoped within an isolated EAR and you want to use this datasource across other deployments in your server?

              • 4. Re: Possible fix for driver class loading issue in LocalMana

                No - I just want it within the ear. The issue is that the LocalManagedConnectionFactory class is loaded with the primary UnifiedClassLoader3, not by my ear's HeirarchicalLoaderRepository3. While the LocalManagedConnectionFactory.getDriver() method properly uses the current thread's class loader to locate the driver class, the DriverManager does not (as Adrian noted in the Jira issue).

                I am just suggesting that the LocalManagedConnectionFactory be modified to use the driver it gets (as it does now after the initial exception) even though the DriverManager isn't smart enough to recognize it.

                • 5. Resolution to driver class loading in LocalManagedConnection

                  Taking a hint from Adrian's comments in that Jira issue, I extracted a copy of jboss-local-jdbc.jar from jboss-local-jdbc.rar and put it in my ear (actually, I put it in a .deployer in my ear that contains all my other jars). This solves the issue. To answer the question that Adrian posed in his comments - reloading the ear appears to work fine.

                  An interesting note - even if the suggestion I made for changing LocalManagedConnectionFactory is adopted, driver loading is not fully isolated unless you have the local copy of the jboss-local-jdbc.jar. If another version of a driver is placed in the central lib directory (e.g. server/default/lib) or in another, not isolated sar or ear, you will get that version of the driver, not the one in your ear. Having your own copy of jboss-local-jdbc.jar appears to be the only full way to isolate drivers from outside interference.

                  Can you tell my app is deployed in environments where I have to be very careful of what other apps are doing? ;-)