Использование Java 7 CommonDataSource с Scala - PullRequest
1 голос
/ 22 марта 2012

Кажется, что есть проблема при компиляции кода Scala, который использует более старые (Java 6) драйверы JDBC DataSource с Java 7 JVM и Scala.

В Java 7 Oracle добавил новый метод, Logger getParentLogger(),к интерфейсу CommonDataSource.Старые классы, построенные на Java 6, которые реализуют CommonDataSource, не собираются реализовывать этот метод (например, PGConnectionPoolDataSource и SQLServerDataSource).Когда код компилируется с помощью компилятора Scala, он жалуется, что конкретный класс не реализует абстрактный метод getParentLogger.

. Я не знаю, происходит ли это с компилятором Java, но я подозреваю, что нет, так какон должен был быть обнаружен модульным тестированием.

Я уверен, что эта проблема возникнет с любым интерфейсом, который добавляет новые объявления методов.

Есть ли обходные пути для Scala для этой проблемы?Является ли единственным решением вернуться к JDK 6?У меня нет исходного кода для драйвера SQL Server, поэтому я не могу решить проблему самостоятельно (я знаю, что у open-source нет этой проблемы, но я вынужден использовать этот драйвер по другим причинам).

1 Ответ

1 голос
/ 23 марта 2012

Реализуйте отсутствующий метод в вашем анонимном подклассе.

new SQLServerDataSource {
  def getParentLogger: Logger = null
  // other stuff
}

Эта небольшая странность на самом деле является хорошей особенностью JVM, позволяющей обеспечить некоторую степень обратной совместимости при добавлении методов к интерфейсам. Я полагаю, что у вас будет такое же поведение с Java, как и у Scala. Похоже, Java немного более терпимо относится к отсутствующим определениям методов в этих случаях. Я не совсем уверен, почему, но я предполагаю, что это может быть связано с тем, как реализованы черты.

Добавление метода к интерфейсу является своего рода изменением, которое двоично совместимо, но несовместимо с источником . Вот почему вы можете создавать экземпляры SQLServerDataSource напрямую. Если вы попытались вызвать getParentLogger для этого экземпляра, компилятор позволит вам это сделать, но вы получите AbstractMethodError во время выполнения.

Чтобы создать экземпляр вашего анонимного внутреннего класса, он должен реализовать все абстрактные методы, чтобы стать конкретным классом. Поскольку SQLServerDataSource не обеспечивает реализацию getParentLogger, вы должны это сделать в своем подклассе.

...