2012-03-22 10 views
1

Java 7のJVMとScalaで古い(Java 6)JDBC DataSourceドライバを使用するScalaコードをコンパイルする際に問題があるようです。Java 7のCommonDataSourceをScalaで使用する

Java 7の場合、OracleはCommonDataSourceインタフェースに新しいメソッドLogger getParentLogger()を追加しました。 CommonDataSourceを実装するJava 6で構築された古いクラスは、このメソッドを実装しません(例:PGConnectionPoolDataSourceおよびSQLServerDataSource)。コードがScalaコンパイラでコンパイルされると、具体的なクラスが抽象メソッドgetParentLoggerを実装していないと訴えます。

これはJavaコンパイラで発生するかどうかはわかりませんが、単体テストでは検出されているはずです。

新しいメソッド宣言を追加するインターフェイスでこの問題が発生することは確かです。

この問題に対してScalaの回避策はありますか? JDK 6に戻す唯一のソリューションですか?私はSQL Serverドライバのソースコードを持っていないので、自分で問題を解決することはできません(オープンソースにはこの問題はありませんが、他の理由でそのドライバを使用する必要があります)。

+0

どのようなコードが文句を言うのですか?あなたは 'SQLServerDataSource'をインスタンス化しようとしていますか、それを拡張していますか、何か他のことをしていますか? – leedm777

+0

'new SQLServerDataSource {...}'匿名サブクラスとして拡張しようとしています(中括弧の中などにホストなどを設定しています)。私はまた、インスタンスを作成し、次にプロパティを初期化しようとしました**と**働いた。 – Ralph

答えて

1

匿名サブクラスで欠落したメソッドを実装します。

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

実際には、JVMの優れた機能であり、インターフェイスにメソッドを追加するときに下位互換性がある程度可能です。 私はあなたがScalaで見ているのと同じ動作をJavaで行うと信じています。 Java のように見えますが、これらのケースではメソッド定義が少し寛容です。なぜ私は正確にはわかりませんが、私の推測は、それがどのように形質が実装されているかに関係しているかもしれないということです。

インターフェイスにメソッドを追加すると、変更の種類がbinary compatibly but source incompatibleになります。このため、SQLServerDataSourceのインスタンスを直接作成することができます。そのインスタンスでgetParentLoggerを呼び出そうとした場合、コンパイラで実行できるようになりますが、実行時にはAbstractMethodErrorになります。

匿名の内部クラスをインスタンス化するには、具体的なクラスになるためにすべての抽象メソッドを実装する必要があります。 SQLServerDataSourcegetParentLoggerの実装を提供していないため、サブクラスに登録する必要があります。

+0

具体的なメソッド定義がないと、同じことがJavaで動作するのはなぜですか? Javaは、事前コンパイルされたクラスの抽象メソッドが欠けていることをより許容しますか? – Ralph

+0

私は詳細を提供するために私の答えを編集しました。基本的にバイナリ互換性とソース互換性の違いです。 – leedm777

関連する問題