今日は非常に予期しないエラーが発生しましたが、問題全体を解決する方法を見つけることができましたが、それはしました。JDK 8でコンパイルされているが、JRE 7をターゲットにしているConcurrentHashMapアプリケーションがクラッシュする
私が使っているコードはもともとJRE 7をターゲットとしたJDK 7環境で書かれていました。コードではConcurrentHashMap
を使用していましたが、マップ内のキーを反復処理する必要がありました。このため私はmap.keySet()
を使用していましたが、JavaDocsによればSet<K>
が返されます。これは、ビルド環境がJDK8に切り替わるまでうまくいった。
JDK8に移動したとき、私はjavacを呼び出すときに1.7のターゲット/ソースを呼び出していました。だから、地図のキーを反復したいときにコードが正しく機能しなくなったとき、私はかなり驚いていました。エラーはスローされず、例外もなくスレッドが単に停止しました。いくつかの調査を行った後、ConcurrentHashMap
のJava8の実装である.keySet()
メソッドがKeySetView<K,V>
を返すことがわかりました。
map.keySet()
を使用してEnumeration<K>
をmap.keys()
に変更することで問題を解決しました。
私の推測では、JDK8が使用されて以来Java7をターゲットにしてプロジェクトがコンパイルされていましたが、Java8ライブラリが含まれていましたが、ミスマッチが発生したときにエラーまたは例外がスローされませんでした。
としては、ここで尋ねたコードスニペットです:私たちは、Windows 2012サーバ上で1.7のターゲットとjavacでソース1.7を使用してOracle JDK 8ビルド40を使用してコンパイルしている
class MapProcessing
{
private ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<String, Object>();
public MapProcessing()
{
map.put("First",new Object());
map.put("Second",new Object());
map.put("Third",new Object());
}
public void processing()
{
// when calling this type of loop causes a freeze on our system.
for(String key : map.keySet())
{
System.out.println(key);
}
}
public void working()
{
// This is what I had to do to fix the problem.
Enumeration<String> keys = map.keys();
while(keys.hasMoreElements())
{
String key = keys.nextElement();
System.out.println(key);
}
}
}
。
コードは、Windows 2012サーバーで実行されているOracle JVM 7ビルド25を使用して実行されています。古いバージョンをターゲット-source
引数を使用して、より新しいJDKを使用してプロジェクトをビルドするたびに
JDK 8を取り付けた後にクリーニングを試しましたか? –
@sureshビルド環境はJenkinsです。 JDK8に移動すると、ワークスペースが削除され、新しいビルドが実行されました。これはコードがSVNから新しくチェックアウトされてビルドされたことを意味します。私はantで "クリーンな"ターゲットへの標準的な呼び出し以外の方法でそれをクリーニングすることが何を意味するのか分かりません。 – JRSofty
あなたはコードスニペットと正確なJVMバージョンとベンダー+ OSを投稿できますか? KeySetViewはを実装していますので、これは少なくとも実際には問題ではありません。 –
salyh