Page 1 of 1

About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Jan 21, 2013 3:34 pm
by Ciprian Mihalache
The question is about loading the driver. The answer marked as valid is about getting a connection. The explanation explains that it is no longer necessary to load driver with Class.forName method in JDBC 4.0, but the question statement does not mention a word about the version of JDBC driver.
For me it is very confusing...
I believe the statement of the question should indicate the JDBC version used.
> In case it is 4.0 and above I consider it should be an answer that no additional actions need to be performed in order to get the driver loaded, because it was already loaded at initialization:
When the method getConnection is called, the DriverManager will attempt to locate a suitable driver from amongst those loaded at initialization...
> In case the JDBC version is below 4.0, the second answer should be the correct one

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Jan 21, 2013 4:23 pm
by admin
You are right. But the approach here is that if a version is not specified then you need to assume the version that is relevant for the exam. In this case, the exam is for Java 7 and so, in absence of any version information, you need to assume JDBC 4.1.

In some questions, it specifies the version information if requires you to assume a version less than 4.1.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Sun Sep 15, 2013 2:49 am
by The_Nick
Hi everyone,
What if you have JDBC 4.0 (hence you can load the drivers implicitly) and at the same time use the Class.forName("drivers"); ? Which one gets loaded? The one implicitly loaded or the the one explicitly loaded?
And what if I have for example 2 kinds of suitable drivers in the metainf folder for example mysql5.0 and mysql 5.x, which both would satisfy the application needs. Which one would get chosen? the newest?

Thanks in advance.

The_Nick.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Sun Sep 15, 2013 5:48 am
by admin
Loading multiple drivers is not an issue. You can load as many of them as you want (implicitly or explicitly using Class.forName). While one is used depends on the which one accepts the jdbc url. ConnectionManager basically asks each loaded driver if it understands the connection URL and is willing to provide a connection. The first one to accept it is the one used. I didn't find any mention of the order they are called in the documentation. So if you load mysql 5.0 and mysql 5.x drivers, which will be used is anyone's guess.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Sun Jan 25, 2015 3:33 pm
by Svetopolk

Code: Select all

Connection c = DriverManager.getConnection("jdbc:fandu://localhost:1234/myDB", "user", "pwd");
This code is used to get a connection from the driver. It doesn't load the driver class itself.
Pretty strange explanation.
I guess Driver is implicitly loaded in JDBC 4.0 and this exact row start to do a process in which Driver is loaded. No?

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Sun Jan 25, 2015 9:26 pm
by admin
No, the driver classes are loaded even before this code is ever executed. The JVM checks the jar files in its classpath and based on the information specified in the meta-inf of a driver's jar file, it loads the driver class.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Jan 26, 2015 3:02 am
by Svetopolk
it is hard to believe. I thought java uses lazy class initialization and I don't see any reason why Driver is an exception. Can you prove your words somehow? (sorry for obtrusiveness, but your answer led me into cognitive dissonance)

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Jan 26, 2015 3:21 am
by admin
Well, besides the fact that lazy initialization is not an absolutely inviolable rule that every JVM must follow, here what the Javadoc for DriverManager says:
When the method getConnection is called, the DriverManager will attempt to locate a suitable driver from amongst those loaded at initialization and those loaded explicitly using the same classloader as the current applet or application.
So it is quite clear that loading of driver classes before calling getConnection is to be expected.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Jan 26, 2015 3:34 am
by Svetopolk
Hmmm, Thanks.
How can you explain this:
The DriverManager will try to load as many drivers as it can find and then for any given connection request
http://docs.oracle.com/javase/7/docs/ap ... river.html

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Jan 26, 2015 6:59 am
by admin
I can only guess that it means the JVM will not shut down if a driver class fails to load. One can specify any class name in the meta-inf of a jar file. The jvm will try to load it and if it is unable to load it for whatever reason, it will proceed without loading it.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Wed Jan 20, 2016 12:30 pm
by toolforger
It's not the JVM that loads the classes in META-INF/services/java.sql.Driver, it's DriverManager during class initialization.
Which will typically happen on the first call to DriverManager.getConnection().

Classes that fail to load are simply ignored. There is not even a log message or anything.

No JVM magic here!

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Thu Jan 21, 2016 4:14 am
by admin
Well, all the classes are loaded by the jvm. What triggers the jvm to load the classes is what you are talking about.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Thu Jan 21, 2016 6:11 am
by toolforger
Sure, but earlier you said that "the JVM checks the jar files in its classpath and based on the information specified in the meta-inf of a driver's jar file, it loads the driver class".
Converting the .class file contents to a Class object is indeed done by the JVM. All the other steps before that are done in pure Java code: Enumerating the jar files in the class path, reading the driver class names from META-INF/services/java.sql.Driver files, and retrieving the .class file contents.
Try single-stepping through DriverManager.loadInitialDrivers() if you want to verify that. It will take you a lazy afternoon to get through ServiceLoader and ClassLoader.loadSystemResources(), but you will get there. Been there, done that :-)

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Thu Jan 21, 2016 8:51 am
by admin
ok, I see your point. I agree that it might very well be the DriverManager's initialization code that triggers the loading of the driver class. I was trying to explain that it is not necessarily the DriverManager.getConnection that triggers the loading of the classes because that is just an implementation detail. It could change. What is guaranteed is that if the service providers follow the service provider interface specification, the classes would have been loaded by the time they are needed. It is in that context that I mentioned that the JVM loads the classes. i.e. to disconnect the link between the call to getConnection and the loading of the drivers.

Sorry for the confusion.

HTH,
Paul.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Thu Jan 21, 2016 11:09 am
by toolforger
Agreed with that.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Sat Apr 10, 2021 1:24 pm
by borkutip
Hello,

I have a question regarding the explanation:

The DriverManager methods getConnection and getDrivers have been enhanced to support the Java Standard Edition Service Provider mechanism. JDBC 4.0 Drivers must include the file META-INF/services/java.sql.Driver. This file contains the name of the JDBC drivers implementation of java.sql.Driver. For example, to load the my.sql.Driver class, the META-INF/services/java.sql.Driver file would contain the entry: my.sql.Driver When the method getConnection is called, the DriverManager will attempt to locate a suitable driver from amongst those loaded at initialization and those loaded explicitly using the same classloader as the current applet or application.

For me, it suggests, as if it might be enough to create a custom jdbc driver as a java service, however, in my experience is that it is not enough.
The customized Driver implementation also should register itself with DriverManager.registerDriver method.

Here can be seen:
https://github.com/openjdk/jdk/blob/mas ... .java#L277
That suitable drivers are searched among registeredDrivers, not among loaded drivers.

I created a simple example:
https://github.com/peterborkuti/csv-jdbc-driver

Thank you in advance
Péter

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Sat Apr 10, 2021 10:31 pm
by admin
What you say might be true but how a JDBC driver must be implemented is not in the scope of the exam. For the purpose of the exam, all you need to know is that if you put a version 4+ JDBC driver jar in your classpath, you, as the application developer, do not need to load the driver explicitly using something like Class.forName. From the application developer's perspective, the driver will be loaded automatically when a connection request is made using the JDBC url that the driver supports. The actual time of loading of the driver or the mechanism involved is not relevant here.

Re: About Question enthuware.ocpjp.v7.2.1375 :

Posted: Mon Apr 12, 2021 12:51 pm
by borkutip
Thank you for your answer.

Péter