Новый метод добавлен в javax.sql.CommonDataSource в 1.7

Попытка скомпилировать мое приложение против java 1.7. Я обнаружил, что был добавлен новый метод в javax.sql.CommonDataSource(и так в j.s.DataSource) -. getParentLogger(). Вы можете сравнить CommonDataSource: 1.7 с CommonDataSource: 1.6

Для меня это изменение однозначно нарушает обратную совместимость. Например, мое приложение (которое содержит реализации DataSource) даже не компилируется с 1.7 без изменений кода.

По моему мнению, это должны быть очень веские причины для этого - но я не могу даже Google. Может кто-нибудь объяснить причины этого изменения? Как он должен иметь дело с этим правильно - для меня это в первый раз, когда я встретился с обратной совместимостью с java, поэтому у меня нет никаких "лучших практик" здесь...

Ответ 1

Если вы не готовы поддерживать компиляцию своего приложения для Java 7, вы все равно можете скомпилировать Java 1.6 с использованием компилятора Java 7. Вам понадобится среда выполнения Java 1.6 (или SDK). Если вы попытаетесь скомпилировать класс MyDataSource.java, который реализует stubbed DataSource с использованием компилятора Java 7, вы можете увидеть следующее:

$ 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

Вам нужно сообщить компилятору, что вы хотите использовать исходные файлы, написанные для Java 1.6, создать байт-код Java 1.6 и найти JAR-версию Java 1.6:

$ 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;
}

Ответ 2

Сначала добавьте запрошенный новый метод без аннотации @Override.

Если вы не возражаете поддерживать новые методы, просто выкините SQLFeatureNotSupportedException.

Если вы обертываете другой DataSource и хотите поддерживать 6 и 7, используйте отражение, чтобы вызвать методы, если они существуют.

Ответ 3

Другой способ справиться с этим - изменить переменные среды PATH и JAVA_HOME

Вот способ справиться с этим на Mac:

export JAVA_HOME =/Система/Library/Рамки/JavaVM.framework/Версии/1.6.0/Домашняя страница

export PATH =/System/Library/Frameworks/JavaVM.framework/Версии/1.6.0/Главная/bin/: $PATH