Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 36 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Sun Apr 22, 2012 5:12 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1812
Location: Austin, TX
What Hibernate does in ClassLoaderService and Class.forName effectively do the same thing: they load the Driver class. The only possible difference I can fathom is a potential difference in which ClassLoader the Driver class is loaded into. But even here, ultimately I would think its the same underlying ClassLoader.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 2:37 am 
Newbie

Joined: Mon Apr 23, 2012 2:34 am
Posts: 1
Are you using an application server? Which application server and which version? Or are you using Hibernate 4.1.2 standalone?

Scott

_________________
http://www.mybagoutlet.com/Monogram-Idy ... ry-14.html


Top
 Profile  
 
 Post subject: 4.1.2 with JDBC 2.x, 3.x should invoke Class.forName
PostPosted: Mon Apr 23, 2012 5:14 am 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
I now strongly suspect that the problem arises from the use of the new Service Provider mechanism in Hibernate 4.1.2 which effectively means that only JDBC 4.0 compliant drivers (which offer support for Service Provider mechanism) can be used with 4.1.2 out of the box. Drivers supporting JDBC 2.0 (my case) or, I think even 3.0 may not work without a call to Class.forName.

I aim to test this proposition over the next day or so using new and old MySql drivers.... I'll report back.

db


Top
 Profile  
 
 Post subject: Re: 4.1.2 with JDBC 2.x, 3.x should invoke Class.forName
PostPosted: Mon Apr 23, 2012 5:28 am 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
bolsover wrote:
I aim to test this proposition over the next day or so using new and old MySql drivers.... I'll report back.


OK - testing done with an 'old' JDBC 2.0 MySql Driver and a 'new' JDBC 4.0 compliant version

JDBC 2.0 driver fails with 4.1.2 unless Class.forName is invoked.

JDBC 4.0 driver works just fine.

I suppose the only remaining questions are:

Has support for JDBC 2.0, and possibly 3.0 drivers been dropped by design? Or was it an accident?

db


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 8:32 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1812
Location: Austin, TX
There is no new information here. Obviously the difference is moving from Class.forName to ClassLoaderService.classForName. The question is why that causes the difference. Both load classes.
* ClassLoaderService.classForName resolves to ClassLoader.loadClass on the numerous ClassLoaders known to Hibernate.
* CLass.forName resolves to an attempt to load the class from just a single ClassLoader. Here it uses the ClassLoadder of the Hibernate classes.

The JDBC 4 version of DriverManager (Java 6 and up) has some code now to check the the ClassLoader of the Driver against the ClassLoader of the calling class (Hibernate). Pretty sure thats all new as part of the JDBC move to service loading. My suspicion is that this is the underlying cause of the problem. Please debug through DriverManager.getConnection(String url, java.util.Properties info, ClassLoader callerCL) method. Specifically look for the code block that looks like:
Code:
       // If the caller does not have permission to load the driver then
       // skip it.
       if ( getCallerClass(callerCL, di.driverClassName ) != di.driverClass ) {
      println("    skipping: " + di);
      continue;
       }


I am assuming this is where it breaks down. Calling Class.forName forces the ClassLoader to be the same as when DriverManager.getConnection is called since both explicitly use the "caller ClassLoader".

Since 4.0 Hibernate requires Java 6, which in turn means JDBC 4.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 10:09 am 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
Hi steve

Not much I can do by way of debugging - I don't have source files for the PervasiveSQL (JDBC 2.0) drivers - which is where MY real problem is vis-a-vis 4.1.2 compatability.

OK so - Since 4.0 Hibernate requires Java 6, which in turn means JDBC 4. - but it is only with the changes in 4.1.2 that this has actually been imposed?

In addition to the changes you note, JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver - I don't know for sure but it looks very much like any driver without this might fail with 4.1.2 - and that includes Oracle 8i and at least some 9i drivers older MySql drivers - and many more - and probably the reason why other users have problems also.

I don't know enough about JDBC drivers or classloaders - but wonder if it is possible to test the driver for compliance with 4.0 before loading using the new 4.1.2 system - if it fails then load via Class.forName?


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 10:38 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1812
Location: Austin, TX
I never said to debug into your Driver. I said to debug into DriverManager, which is a Java class.

JDBC 4 also provides for Drivers to not provide a META-INF/services/java.sql.Driver file.

You said yourself that Hibernate is able to find the class (ClassLoaderService.classForName returns the class). None of this is the issue.

As I have said before, DriverManagerConnectionProviderImpl is not a supported class. I don't mind making changes to it as long as it does not adversely affect our use of it in the testsuite. However, I have already spent alot of time debugging and supporting this. I pointed you in the code in which I believe the issue lies. I need you to help verify that. If you can't then there is nothing more I can do.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 11:23 am 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
Sorry - misunderstood.

I'm actually using JDK7 - java version 1.7.0_03 (this is a desktop app - and I can distribute the JRE with the app).

// Without c3p0
DriverManager Method where failure occurs is private static Connection getConnection(String url, java.util.Properties info, ClassLoader callerCL).
There is a loop - for(DriverInfo aDriver : registeredDrivers) {....

If I do not make a call to Class.forName, the only driver available in CopyOnWriteArrayList<DriverInfo> registeredDrivers is the JdbcOdbcDriver the method never gets a connection at: Connection con = aDriver.driver.connect(url, info); and throws an
SQLException("No suitable driver found for "+ url, "08001");

// with c3p0
Failure occurs in DriverManager Method public static Driver getDriver(String url) again because the only registered driver is JdbcOdbcDriver.

Making call to Class.forName appears to register the driver correctly and DriverManager.getDriver(String url) returns the driver.

I can test with JDK6... will take a little longer - but don't expect significantly different result.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 11:46 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1812
Location: Austin, TX
Looking back, you list Pervasive as defining a static method that registers itself with the DriverManager. But nothing about loading a class calls into static methods. Does your driver register itself with the DriverManager when its class is loaded (static block) or not? If not, it totally violates the JDBC spec (drivers should either supply a service loader file or regsiter itsself on class load, but it absolutely is supposed to do one or the other).

If it really is regsitering itself with the DriverManager, then we need to find out why that registration is not available later in DriverManager.getDriver/DriverManager.getConnection.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 2:14 pm 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
Yes - it appears to:

Code:

public class Driver implements java.sql.Driver
{
    private static ResourceBundle verBundle;
    static int MAJOR_VERSION;
    static int MINOR_VERSION;
    static String PRODUCT_NAME;
    static String PRODUCT_VERSION;
   
    private static void register() {
   try {
       DriverManager.registerDriver(new Driver());
   } catch (SQLException sqlexception) {
       /* empty */
   }
    }.......
..   
    static {
   register();
   verBundle = null;
   MAJOR_VERSION = 2;
   MINOR_VERSION = 2;
   PRODUCT_NAME = "Pervasive.SQL";
   PRODUCT_VERSION = "";
    }
}


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 2:25 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1812
Location: Austin, TX
So in your debugging session, step into DriverManager.registerDriver and see what happens.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 2:29 pm 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
Just an extra note regarding last post...
I can't be certain about code since the sample was result of decompiler (not a tool I frequently use!!) - but it looked OK.

Also, I went back to some tests I did with an old MySQL JDBC2.0 driver (mysql-connector-java-3.0.11-stable-bin.jar) - so far as I can tell, the failure points (with and without c3p0) are the same as those with the Pervasive Driver.

db


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 2:35 pm 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
steve wrote:
So in your debugging session, step into DriverManager.registerDriver and see what happens.


// with or without c3p0
No Pervasive Driver is registered - only JdbcOdbcDriver - in static loadInitialDrivers()


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 3:17 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1812
Location: Austin, TX
I have tried to help, but this is going nowhere. Yes between your assurance that the driver registers itself and the list of registered drivers in DriverManager not containing it when getDrivers and/or getConnection is called obviously something happens. I'll try to help out more as soon as someone can tell me what that something is.


Top
 Profile  
 
 Post subject: Re: Migration problem 4.1.0 to 4.1.2
PostPosted: Mon Apr 23, 2012 4:09 pm 
Regular
Regular

Joined: Sat Apr 23, 2005 7:28 am
Posts: 52
Steve
Many thanks for your efforts - it really is appreciated.

Naturally I'll help more if I can; in the meanwhile I'll just use Class.forName to sidestep the issue.

I suspect this will only be solved if you are able to reproduce the problem directly - I would not particularly reccomend using PervasiveSQL since it is not exactly mainstream and I doubt worth the effort involved. However, testing with a current MySQL database and an obsolete MySQL JDBC 2.0 driver might help isolate the issue.

My guess is that as more users adopt 4.1.2, you will see more related problems with a wider range of database and drivers.

db


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 36 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.