Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.setProperty used by a thread impacts other thread in communication to external network elements. How to resolve it?

Tags:

java

sockets

In my application, I have two threads. Each thread communicates to different external entities.

Let us say T1 --> N1 & T2 --> N2 (T1 & T2 are two threads. N1 & N2 are external entities. Communications is SOAP over HTTPS.)

The vendor of N1 requested to use key store file UPCC_client.store for authentication and for the same we have used the following code,

System.setProperty("javax.net.ssl.keyStore", "<file path>");
System.setProperty("javax.net.ssl.keyStorePassword", "<password>");
System.setProperty("javax.net.ssl.trustStore","<file path>");
System.setProperty("javax.net.ssl.trustStorePassword", "<password>");

The application has been restarted with the above properties set in T1 thread with no issues. T2 started getting into trouble, since properties set by T1 are getting used by T2. The main reason behind this is System.setProperty is JVM scope. How to resolve this problem?

like image 245
Hari Avatar asked Mar 06 '12 08:03

Hari


People also ask

How does system setProperty work?

setProperty manages the initialization of the Chrome driver in the first step. The System. setProperty() method forms the basis for test case automation on any browser. Naturally, QAs must understand how to use this fundamental method for all automation purposes in Selenium.

Is setProperty thread safe?

SO is System. setProperty safe ? No. Do not use this.


1 Answers

I suspect you have a design issue to have this requirement however.

The only way around this is I can think of is to make your properties ThreadLocal.

public class ThreadLocalProperties extends Properties {
    private final ThreadLocal<Properties> localProperties = new ThreadLocal<Properties>() {
        @Override
        protected Properties initialValue() {
            return new Properties();
        }
    };

    public ThreadLocalProperties(Properties properties) {
        super(properties);
    }

    @Override
    public String getProperty(String key) {
        String localValue = localProperties.get().getProperty(key);
        return localValue == null ? super.getProperty(key) : localValue;
    }

    @Override
    public Object setProperty(String key, String value) {
        return localProperties.get().setProperty(key, value);
    }
}

// Make the properties thread local from here. This to be done globally once.
System.setProperties(new ThreadLocalProperties(System.getProperties()));

// in each thread.
System.setProperty("javax.net.ssl.keyStore", "my-key-store");

Unless there is any confusion, System.setProperties() doesn't just set properties, it replaces the collection, and its implementation.

// From java.lang.System
 * The argument becomes the current set of system properties for use
 * by the {@link #getProperty(String)} method.

public static void setProperties(Properties props) {
    SecurityManager sm = getSecurityManager();
    if (sm != null) {
        sm.checkPropertiesAccess();
    }
    if (props == null) {
        props = new Properties();
        initProperties(props);
    }
    System.props = props;
}

By using this method the behaviour of System Properties changes to being thread local for calls to setProperty() and getProperty()

like image 53
Peter Lawrey Avatar answered Oct 26 '22 13:10

Peter Lawrey