Java では、いくつかのクラス間で値を渡すためにSystem.setProperty
. しかし、 を使用System.getProperties()
すると、すべてのシステム プロパティを取得できます。したがって、サードパーティの API を使用すると、サードパーティの API も私のプロパティにアクセスでき、変更することもできます。SOはSystem.setProperty
安全ですか?
4 に答える
安全とは何を意味するかによって異なります。
システム プロパティ オブジェクトを読み取り専用として扱うことをお勧めしますが、それをサードパーティのライブラリに依存することはできません。
「信頼できる」サードパーティ コードがアプリケーションのプロパティを参照または変更することを懸念している場合は、システム プロパティを使用してそれらを表現しないでください。独自の Properties オブジェクトを作成し、そこにプロパティを配置します。これはおそらく、全体的に最も単純なアプローチです。
サンドボックスを使用すると、信頼されていないコードがシステム プロパティにアクセスするのを防ぐことができます。コードが信頼されていないコードにシステム プロパティ オブジェクトを漏らさない限りは。(アクセスチェックは
System
メソッドに実装されています...)Properties オブジェクトはスレッドセーフです...その種の安全性を参照している場合。
1 - システム プロパティをプログラムで変更する必要がある場合があります。ただし、これを行うと、壊れやすいアプリケーションになる可能性があります。通常、システム プロパティは、初期化中に JVM サービスを構成するために使用されます。なんらかの理由でクラスの初期化の順序が変更された場合、アプリケーション コードによるプロパティの設定が遅すぎることがわかります。可能であれば、-D
コマンド ライン パラメータを使用してプロパティを設定することをお勧めします。
ライブラリの動作について心配する必要がある場合は、セキュリティ ポリシーとSecurityManagerについて学び、使用する必要があります。とりわけ、これにより の使用を制限できますSystem.setProperty
。
ドキュメントによると
一般に、システムプロパティを上書きしないように注意してください。
setPropertiesメソッドは、現在実行中のアプリケーションのシステムプロパティのセットを変更します。これらの変更は永続的ではありません。つまり、アプリケーション内でシステムプロパティを変更しても、このアプリケーションまたは他のアプリケーションに対するJavaインタープリターの今後の呼び出しには影響しません。ランタイムシステムは、起動するたびにシステムプロパティを再初期化します。システムプロパティへの変更を永続化する場合、アプリケーションは終了する前に値をファイルに書き込み、起動時に再度読み込む必要があります。
一部のサードパーティライブラリがアプリが使用しているプロパティを上書きする可能性があるという懸念は正しいです。プロパティファイルで定義されたキーを区別するために、いくつかの命名規則を使用することは常に良い習慣です。
問題の非常に単純なシミュレーション
public class TestApp {
public static void main(String args[]) throws InterruptedException {
TestApp app = new TestApp();
app.new ThirdPartyLib("thirdParty").start();
while (true) {
Thread.currentThread().sleep(500);
System.setProperty("test", "orignalProperty");
System.out
.format("Thread Name '%s' setting the property with value '%s' \n ",
Thread.currentThread().getName(),
System.getProperty("test"));
}
}
class ThirdPartyLib extends Thread {
public ThirdPartyLib(String threadName) {
super(threadName);
}
@Override
public void run() {
super.run();
while (true) {
Thread.currentThread();
try {
Thread.sleep(400);
System.setProperty("test", "modifiedProperty");
System.out
.format("Thread Name '%s' setting the property with value '%s' \n ",
Thread.currentThread().getName(),
System.getProperty("test"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
以下の出力になります-これは意図したものではない可能性があり、デバッグも難しいと思います
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'main' setting the property with value 'orignalProperty'
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'main' setting the property with value 'orignalProperty'
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'thirdParty' setting the property with value 'modifiedProperty'
Thread Name 'main' setting the property with value 'orignalProperty'