1

在java中我们可以使用一些类之间传递值System.setProperty。但是使用System.getProperties()我们可以获得所有系统属性。因此,如果我使用任何第三方 API 的手段,他们也可以访问我的属性,并且他们也可以更改。所以System.setProperty安全吗?

4

4 回答 4

5

这取决于你所说的安全是什么意思。

  1. 好的做法1将 System Properties 对象视为只读,但您不能依赖 3rd-party 库来执行此操作。

  2. 如果您担心“受信任的”第 3 方代码看到或更改您的应用程序的属性,请不要使用系统属性来表示它们。创建您自己的 Properties 对象并将您的属性放在那里。这可能是总体上最简单的方法。

  3. 如果您使用沙盒,则可以防止不受信任的代码访问系统属性……前提是您的代码不会将系统属性对象泄漏给不受信任的代码。(访问检查在System方法中实现......)

  4. Properties 对象是线程安全的……如果您指的是这种安全性。


1 - 有时需要以编程方式修改系统属性。但是,这样做可能会导致应用程序脆弱。系统属性通常用于在初始化期间配置 JVM 服务。如果由于某种原因类初始化的顺序发生了变化,您可能会发现您的应用程序代码现在设置属性为时已晚。如果可能,最好通过-D命令行参数设置属性。

于 2013-02-23T11:26:50.123 回答
2

如果您需要担心库的行为,则需要了解和使用安全策略和SecurityManager。除其他外,这将允许您限制使用System.setProperty.

于 2013-02-23T12:30:04.557 回答
0

根据文档

通常,请注意不要覆盖系统属性。

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' 
于 2013-02-23T12:21:48.377 回答
0

我不会依赖使用系统属性在线程之间共享信息。我尝试在一个线程中创建一个属性,即使经过 10 秒也找不到另一个线程。其他人已经回答了修改线程已经可用的系统属性值的行为。

于 2019-05-15T19:12:24.743 回答