I have a c3p0.ComboPooledDataSource, managed by Spring, managing my database connections. When I grab a PreparedStatement instance from a connection, I find that C3P0 is actually returning me an instance of the NewProxyPreparedStatement class which implements the PreparedStatement Interface. Fine.
However, when I call some of the methods defined as part of this contract I get the following RuntimeException java.lang.AbstractMethodError: com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.isClosed()Z
Looking at the source code, I can see that this class does not provide a number of methods which are outlined as part of the Statement and PreparedStatement contract. This code shouldn't compile. I feel like I am missing something important, but quite advanced here. How is it possible that this is shipped as part of a library?
I was hoping to use the PreparedStatement.isClosed method, is the actual underlying problem that I should just be leaving the management of these Objects to Spring?
Upgrade to the latest pre-release of c3p0-0.9.5, which supports all JDBC4 api. The version you are using supports only JDBC3. If you like managed dependencies, use groupId: com.mchange, artifactId: c3p0, version: 0.9.5-pre5. Otherwise binary distributions are on sourceforge.
Related
a quote from java.sql.DriverPropertyInfo javadoc:
The DriverPropertyInfo class is of interest only to advanced programmers who need to interact with a Driver via the method getDriverProperties to discover and supply properties for connections.
Is there an error in the jdbc javadoc since ever? (Cannot believe)
Seems copied from very early versions of jdbc, and even shows up in android environment
I find the method java.sql.Driver.getPropertyInfo, but no method called getDriverProperties
I searched Driver, Connection, DataSource. what am I missing?
This seems to be an error in the documentation. You need to use Driver.getPropertyInfo​(String url, Properties info). Likely the name was changed during development of JDBC 1 and this part of the documentation was missed when renaming (or something like that).
I'll bring it up in the JDBC Expert Group and see if it can be changed in a future JDBC maintenance release. However, as this error has existed for 21 years, it probably won't be a priority.
The DriverPropertyInfo is rather an obscure JDBC feature, and I'm not sure how faithfully drivers implementations update it when adding new properties. I wouldn't rely on it too much.
I'm having a Maven Web Application on a Tomcat 8 connecting to a SQL Server 2012 Database.
For logging purposes I wanted to use the getClientConnectionID.
Due to the policies of Microsoft it's quite a pain to make their driver work with Maven (I know it's possible and I did it for a while, but in my case it lead to several problems after migrating/sharing the project).
Unfortunately the JTDS-Driver refuses to work with the Database server for unknown reasons.
So right now I've just put the sqljdbc4-4.0.jar into the lib folder of Tomcat and the META-INF/services of the project and since then everything is fine.
Yet after doing more with the database I'm unsure if it's worth to switch and tried to get some information what the actual differences between com.microsoft.sqlserver.jdbc.SQLServerConnection and java.sql.Connection are and if it would make sense to change.
So far I couldn't find useful information. Most pages just refer how to solve issues with each type...
Is there any difference in performance, behaviour or other possibilities which would actually justify switching back?
java.sql.Connection is an interface where com.microsoft.sqlserver.jdbc.SQLServerConnection is an implementation for MS-SQL , you can't compare their performance because the first is just an interface that does nothing where the other is the actual implementation. So you use Connection to maintain abstraction in your code, but effectively you will be using the implementation you provide, which is com.microsoft.sqlserver.jdbc.SQLServerConnection in this case. People usually add those as runtime dependencies so they don't get a polluted namespace.
java.sql.Connection is the interface which is implemented by com.microsoft.sqlserver.jdbc.SQLServerConnection.
Normally you would only program against the interface to be independent of the specific implementation. Then - if you don't rely on some implementation specific behaviour - you can simply exchange the jar with the JDBC driver and your code should still work without any changes.
For some time I am struggling to get an arquillian test case running. This test involves classes rooted in JSF classes and it ran into an ClassFormatError: Absent Code as the implementation for the javax.faces.model.DataModel could not be found.
My assumption was that I need to provide my test with a JSF implementation, but the implementations I found (for example the one bundled with JBoss) do not have the javax.faces package, only com.sun, and I could find no trace of the DataModel class.
Where am I misunderstanding the way it works here? Why doesn't the impl actually implement the api?
The API:
the public types to which consumers can write code to
The implementation:
private types consumers should not rely on
implementation details including things like markup (e.g. HTML) and container (e.g. servlet)
This separation isn't as clean as it should be, but this is largely the intent. Separation into these two jars are how the developers chose to organise the code but you'll need both to utilize the library in most contexts.
I'm developing a jar library for utility use.
I want to significantly reduce the dependencies on external jars/libraries, but provide native support for such a library if it exists in the class path.
For instance, I want the library to provide routines that work with hibernate; however I don't want the application to die with an error if the hibernate jars are not present.
Is there a way to implement this, without having to bundle the hibernate jars with my library?
During your initialization, you could use Class.forName to look up one of the Hibernate classes, and if it throws a ClassNotFoundException catch it and you know Hibernate isn't in the environment — set a flag so that you know not to do Hibernate-specific things.
Note, though, that if any of your classes refers to Hibernate classes statically (e.g., via import), those classes won't load if Hibernate isn't in the class path. The usual way to deal with that is:
Create an interface to your Hibernate-specific stuff, e.g. HibernateStuff.
Only refer to the interface from your main code, and don't refer to any Hibernate classes in your main code via import.
Have your Hibernate-specific stuff in a class implementing that interface, e.g., HibernateStuffImpl. That class can import Hibernate stuff.
Once you've determined that Hibernate is in the classpath (via Class.forName), use Class.forName to load your HibernateStuffImpl and then use Class#newInstance to create an instance of it, assigning it to a variable of type HibernateStuff.
Use that variable to call into your Hibernate-specific stuff.
You might have a HibernateStuffStub class that implements the interface by doing nothing, and use that when Hibernate isn't loaded, so your code isn't peppered with conditional statements. (The JVM is very quick at no-op calls.)
...and of course, all of the above applies to anything, not just Hibernate.
Say. jdbc driver need Class.forName to exec static block of a class.
Why not just run it as a class field?
Class.forName() is guaranteed to initialize the class at the time you call it. How would you propose to do it? Could you just declare a local variable without assigning it, like com.foo.Driver d;? What about a making it a member variable instead? Would you have to actually assign it? What does the spec say about how and when a class has to be loaded? Do you really want to have to think about that, or just call Class.forName()?
On a related note, it's no longer necessary to do this with many JDBC drivers. The DriverManager now uses the ServiceLoader mechanism to identify and load conforming driver classes.
The whole idea of JDBC is to not be dependant on one specific driver or implementation. The idea is you can use JDBC and configure at runtime any driver which is available. To do this you need to load the driver by name and use the JDBC methods. Unfortunately JDBC doesn't abstract away all the differences between databases like error codes, and switching to a database you haven't tested may not be a good idea.
You could take the view that for all of your libraries, you have them available at compile time and you wouldn't change the database on a wim, without a minimum re-testing and re-deploying your application. In this case linking to a specific driver (instead of using Class.forName) might be a good thing because it would force you (or whomever does this) to put more thought into the change and follow your testing procedures.
It's impractical to use technique for loading JDBC drivers other than reflection.
(Though there are different ways to do it). There's a lot of JDBC drivers and the implementation code may not be available to the app.