JPPF Issue Tracker
star_faded.png
Please log in to bookmark issues
bug_report_small.png
CLOSED  Bug report JPPF-523  -  nullpointer in org.jppf.utils.SystemUtils.addOtherSystemProperties
Posted Jan 01, 2018 - updated Jan 04, 2018
icon_info.png This issue has been closed with status "Closed" and resolution "RESOLVED".
Issue details
  • Type of issue
    Bug report
  • Status
     
    Closed
  • Assigned to
     lolo4j
  • Progress
       
  • Type of bug
    Not triaged
  • Likelihood
    Not triaged
  • Effect
    Not triaged
  • Posted by
     subes
  • Owned by
    Not owned by anyone
  • Category
    Client
  • Resolution
    RESOLVED
  • Priority
    High
  • Reproducability
    Always
  • Severity
    Critical
  • Targetted for
    icon_milestones.png JPPF 5.2.9
Issue description
The following NullpointerException is thrown:
2018-01-01 21:46:26,498 [ |JPPF Client-0001   ] ERROR org.jppf.client.balancer.JobManagerClient.addConnection      - Error while adding connection p://invesdwin.de:5532-1[invesdwin.de:5532] : NEW
java.lang.NullPointerException: null
	at java.util.Hashtable.put(Hashtable.java:460)
	at java.util.Properties.setProperty(Properties.java:166)
	at org.jppf.utils.SystemUtils.addOtherSystemProperties(SystemUtils.java:124)
	at org.jppf.utils.SystemUtils.getSystemProperties(SystemUtils.java:101)
	at org.jppf.management.JPPFSystemInformation.populate(JPPFSystemInformation.java:282)
	at org.jppf.management.JPPFSystemInformation.<init>(JPPFSystemInformation.java:107)
	at org.jppf.management.JPPFSystemInformation.<init>(JPPFSystemInformation.java:83)
	at org.jppf.client.balancer.ChannelWrapperRemote.<init>(ChannelWrapperRemote.java:68)
	at org.jppf.client.balancer.JobManagerClient.addConnection(JobManagerClient.java:198)
	at org.jppf.client.balancer.JobManagerClient$3.connectionAdded(JobManagerClient.java:139)
	at org.jppf.client.AbstractJPPFClient.fireConnectionAdded(AbstractJPPFClient.java:307)
	at org.jppf.client.AbstractGenericClient.newConnection(AbstractGenericClient.java:328)
	at org.jppf.client.AbstractGenericClient.submitNewConnection(AbstractGenericClient.java:311)
	at org.jppf.client.AbstractGenericClient$4.run(AbstractGenericClient.java:263)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
This is caused by a system property "jmockit-instrumentation" with value <null>. A proper fix would be to ignore null values when adding other properties:

private static void addOtherSystemProperties(final TypedProperties props) {
    try {
      // run as privileged so we don't have to set write access on all properties in the security policy file.
      Properties sysProps = AccessController.doPrivileged(new PrivilegedAction<Properties>() {
        @Override
        public Properties run() {
          return System.getProperties();
        }
      });
      Enumeration en = sysProps.propertyNames();
      while (en.hasMoreElements()) {
        String name = (String) en.nextElement();
        try {
if (!props.contains(name)) { Object value = System.getProperty(name); if(value != null) { props.setProperty(name, value); } }
        } catch(SecurityException e) {
          if (debugEnabled) log.debug(e.getMessage(), e);
          else log.info(e.getMessage());
        }
      }
    } catch(SecurityException e) {
      if (debugEnabled) log.debug(e.getMessage(), e);
      else log.info(e.getMessage());
    }
  }
Steps to reproduce this issue
Add mockito to the classpath and run jppf.

#2
Comment posted by
 subes
Jan 02, 01:00
I found a workaround for me:

https://github.com/subes/invesdwin-context-integration/blob/master/invesdwin-context-integration-parent/invesdwin-context-integration-jppf/src/main/java/de/invesdwin/integration/jppf/client/ConfiguredClientDriverDiscovery.java

Specifically:

    @Override
    protected void newConnection(final ClientConnectionPoolInfo info) {
        fixSystemProperties();
        super.newConnection(info);
    }


    private void fixSystemProperties() {
        final Properties sysProps = System.getProperties();
        final Enumeration<?> en = sysProps.propertyNames();
        while (en.hasMoreElements()) {
            final String name = (String) en.nextElement();
            final String value = sysProps.getProperty(name);
            if (value == null) {
                sysProps.setProperty(name, "");
            }
        }
    }
#3
Comment posted by
 lolo4j
Jan 02, 10:41
I'm unable to reproduce yet. Adding jmpckito to the classpath is not sufficient. I do not understand how the value of a system property can be null, as this is explicitely documented to not be possible in the javadoc for Hashtable (superclass of Properties). To me this is only possible if the system property is removed while iterating over the keys in addOtherSystemProperties(). This may happen from a client discovery plugin, since it runs in a separate thread.

Furthermore, while reviewing the code of this method, I realized it is completely wrong. The condition if (!props.contains(name)) should be if (!props.containsKey(name)). Also a null check on the result of getProperty(name) is indeed missing.

#6
Comment posted by
 lolo4j
icon_reply.pngJan 03, 08:04, in reply to comment #3
I managed to reproduce with this simple code (no external library involved):
public class TestMain {
  public static void main(final String[] args) {
    for (int i=1; i<=10_000; i++) System.setProperty("test" + i, "123");
    JPPFConfiguration.set(JPPFProperties.REMOTE_EXECUTION_ENABLED, false);
    try (JPPFClient client = new JPPFClient()) {
      client.addDriverDiscovery(new SimpleDiscovery());
      Thread.sleep(1L);
      for (int i=1; i<=10_000; i++) System.getProperties().remove("test" + i);
      Thread.sleep(1000L);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
 
  private static class SimpleDiscovery extends ClientDriverDiscovery {
    @Override
    public void discover() throws InterruptedException {
      newConnection(new ClientConnectionPoolInfo("myDriver", false, "localhost", 11111));
    }
  }
}
However, the NPE does not occur systematically, but around twice out of 3 times. The idea is to be removing properties from System.getProperties() while in parallel SystemUtils.addOtherSystemProperties() is iterating over the system properties. This is the only way System.getProperty(String) can return null, since, according to the Javadoc for Hashtable, null keys or values are not supported:
This class implements a hash table, which maps keys to values. '''Any non-null object can be used as a key or as a value'''.
#7
Comment posted by
 lolo4j
Jan 04, 13:37
Fixed in: