Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

New method added in javax.sql.CommonDataSource in 1.7

Tags:

Trying to compile my app against java 1.7 I found what there was a new method added in javax.sql.CommonDataSource (and so in j.s.DataSource) -- .getParentLogger(). You can compare CommonDataSource:1.7 with CommonDataSource:1.6

For me this change definitely breaks backward compatibility. For example, my app (which contains implementations of DataSource) even doesn't compile against 1.7 without changes in code.

By my opinion, it should be very strong reasons for doing this -- but I can't google even one. Can somebody explain the reasoning behind this change? How it's supposed to deal with it correctly -- for me it's a first time I've met with backward uncompatibility with java, so I do not have any "best practices" here...

like image 318
BegemoT Avatar asked Dec 14 '11 10:12

BegemoT


2 Answers

If you're not ready to support compiling your application for Java 7, you can still compile for Java 1.6 using the Java 7 compiler. You will need a Java 1.6 runtime environment (or SDK) installed. If you try compiling a MyDataSource.java class that implements a stubbed DataSource using a Java 7 compiler, you might see the following:

$ java -version  java version "1.7.0" Java(TM) SE Runtime Environment (build 1.7.0-b147) Java HotSpot(TM) Server VM (build 21.0-b17, mixed mode) $ javac -version javac 1.7.0 $ javac MyDataSource.java  MyDataSource.java:7: error: MyDataSource is not abstract and does not override abstract method getParentLogger() in CommonDataSource public class MyDataSource implements DataSource {        ^ 1 error 

You need to tell the compiler that you want to use source files written for Java 1.6, produce Java 1.6 bytecode and where to find the Java 1.6 runtime JAR:

$ javac -source 1.6 -target 1.6 -bootclasspath <path to Java 1.6 JRE>/lib/rt.jar MyDataSource.java  $ file MyDataSource.class  MyDataSource.class: compiled Java class data, version 50.0 (Java 1.6) $ javap MyDataSource Compiled from "MyDataSource.java" public class MyDataSource implements javax.sql.DataSource {   public MyDataSource();   public java.io.PrintWriter getLogWriter() throws java.sql.SQLException;   public void setLogWriter(java.io.PrintWriter) throws java.sql.SQLException;   public void setLoginTimeout(int) throws java.sql.SQLException;   public int getLoginTimeout() throws java.sql.SQLException;   public <T extends java/lang/Object> T unwrap(java.lang.Class<T>) throws java.sql.SQLException;   public boolean isWrapperFor(java.lang.Class<?>) throws java.sql.SQLException;   public java.sql.Connection getConnection() throws java.sql.SQLException;   public java.sql.Connection getConnection(java.lang.String, java.lang.String) throws java.sql.SQLException; } 
like image 158
Dan Cruz Avatar answered Oct 15 '22 09:10

Dan Cruz


First add the requested new method(s) without the @Override annotation.

If you don't mind supporting the new methods simply throw SQLFeatureNotSupportedException.

If you are wrapping another DataSource and want to support 6 and 7, use reflection to call the methods if they exists.

like image 34
eskatos Avatar answered Oct 15 '22 10:10

eskatos