2011-11-30 7 views
9

Guava 10+では、GoogleはFiles.deleteDirectoryContents()を非難しました。 JavaDocとはGuavaでFiles.deleteDirectoryContents()が使用されないのはなぜですか?

廃止されました。この方法では、シンボリックリンクの検出が不十分で、競合が発生するという問題があります。この機能は、 がrm -rfやdel/sなどのオペレーティングシステムコマンドにシェルリングすることによってのみ適切にサポートされます。 この方法は、グアバにグアバから削除される予定です 11.0

を解放し、私は競合状態がある理由について混乱しています。私はこの方法が実際に有用であり、オペレーティングシステムに貧弱な解決策を見つけることができると思います。著者がなぜこの決定をしたのかを共有することはできますか?

+0

もっと明確にするために、競合状態の問題は大きなバグではないと思います。 'ArrayList'のような多くのlibsはスレッドセーフではなく、競合条件を持っていません。 'File.remove'でも同じ問題があります。しかし、それらはすべて文書化されています。だから私は、ドキュメンテーションがなぜそれが非難されたのかを選択した理由について既に述べていることに加えて、答えを聞くことを望んでいた。 –

+1

この競合状態と一般的な非スレッドセーフなクラスの違いは、そのスレッドに対する「修正」がないことです。これに対して、ロックオブジェクトで同期することで、スレッドセーフではないクラスによるJavaスレッド安全性の問題を解決できます。単に人々が期待していることをすることができない方法は悪い方法です。 –

+0

これは良い点です。ありがとう。 –

答えて

5

なぜ競合状態にあるのか混乱しています。

たとえば、あるスレッドがFiles.deleteDirectoryContents()を呼び出し、2番目のスレッド(または外部プロセス)が同時にディレクトリに新しいファイルを作成するとします。

コールから戻ったときに、ディレクトリが空であることに頼ることができますか?いいえ!

とにかく、このメソッドの機能が有用であるとわかったら...その欠陥にもかかわらず、コードのコピーを取って調整してアプリケーションに埋め込むことは自由です。 (Guavaのソースコードライセンスを確認し、それに従っていることを確認してください)

なぜこの決定がなされたのですか?

私は彼らが既に持っていると思います。廃止通知を参照してください。もっと必要な場合は、問題追跡ツールとGuavaディスカッショングループを検索してみてください。ディスカッショングループで丁寧に尋ねてみることもできますが、あなたのアジェンダが自分の心を変えることであれば、あなたが成功するかどうかは疑問です。

+4

OSに砲撃するのは同じだろうか? – anders

+0

+1 OSに砲撃するのは当然ではないでしょうか。ライブラリがスレッドセーフでない場合は、ドキュメント化し、開発者が正しく使用することを確認する必要があります。 –

+0

@Stephen C、私は体の心を変えようとはしていません。なぜこれが推奨されなくなったのかについての正当な理由があると確信しています。私はちょうど、これをすることを余儀なくされた競争条件のほかにおそらく問題があると思った。しかし、競合条件を持つ多くのライブラリがあります。もっと良い理由があるかもしれないと思った。 –

5

競合状態は、「ディレクトリが空ではない可能性があります」よりも悪い可能性があります。これは、シンボリックリンクの検出が不良であることが原因の1つです。このコードスニペットを考えてみましょう:

// Symbolic links will have different canonical and absolute paths 
if (!directory.getCanonicalPath().equals(directory.getAbsolutePath())) { 
    return; 
} 
... delete its contents ... 

directoryがチェック中無地ディレクトリが、その後/へのシンボリックリンクである場合は、deleteDirectoryContentsは喜んでファイルシステム全体を拭くしようとします。

回避方法がありますが、見つからない可能性があります。潜在的なセキュリティバグのための特別な修正を行うことは恐ろしいことです。

1

シンボリックリンクの検出の詳細については、these bugs filed by usersを参照してください。

要するに、そのディレクトリに正規のパスを指定しない限り、ディレクトリを消去することはできません。 /tmp/some/other/directoryへのリンクの場合、deleteDirectoryContents/tmp/mytempdirectoryをワイプできません。おそらく、ここでも回避策が考えられるかもしれませんが、私たちは手を捨てました。

1

あなたは深刻ですか?

たとえば、1つのスレッドがファイルを呼び出すとします。deleteDirectoryContents()と2番目のスレッド(または外部プロセス)が同時にディレクトリに新しいファイルを作成します。 コールから戻ると、ディレクトリが空であることに頼ることができますか?いいえ!

そして、別のプロセスがディレクトリで動作するのはどうですか?それは解決することはできませんし、単純に不可能なのでトランザクションを処理すべきではありません。そして、誰かがルートへのシンボリックリンクを作ってファイルシステム全体を削除するという議論です。ファイルシステムに対するアクセス権はありませんか?そして、あなたがrootのような操作をしているなら、あなたがしていることを知るべきです。ファイルシステムの中でファイルを全く削除しないようにするのはどうですか?危険です!グアバの作者がそのようなばかげた問題を解決するなら、私は別の図書館を使用します。

関連する問題