Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 490890 - Setting system properties to clone of themselves causes exitcode to be stuck at zero
Summary: Setting system properties to clone of themselves causes exitcode to be stuck ...
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Launcher (show other bugs)
Version: 4.5.0 Mars   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: Neon M7   Edit
Assignee: Thomas Watson CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 319679 490589 (view as bug list)
Depends on:
Blocks: 490589
  Show dependency tree
 
Reported: 2016-04-01 06:29 EDT by Andreas Sewe CLA
Modified: 2019-10-22 09:25 EDT (History)
2 users (show)

See Also:


Attachments
Trivial application demonstrating the problem (2.51 KB, application/zip)
2016-04-01 06:29 EDT, Andreas Sewe CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Sewe CLA 2016-04-01 06:29:56 EDT
Created attachment 260660 [details]
Trivial application demonstrating the problem

This bug started its life as Tycho Bug 490589, but I have managed to distill it down to a minimal example (attached) using a trivial org.eclipse.equinox.app.IApplication:

  public class Application implements IApplication {

    public Object start(IApplicationContext context) throws Exception {
      Properties original = System.getProperties();
      Properties clone = (Properties) original.clone();
      final Properties replacement;
      replacement = clone; // (1) Causes the exit code of 255 to be ignored
//    replacement = new Properties(original); // (2) Not ignored
//    replacement = new Properties(clone); // (3) Ignored

      System.err.println(replacement.equals(original));
      System.err.println(replacement.hashCode() == original.hashCode());

      System.setProperties(replacement);
    }

    public void stop() {
    }
  }

For some reason, replacing the system properties with a clone of themselves (see Bug 490866 comment 9 for why one may want to do this) causes the return value of IApplication.start to be ignored; the exit code of the JVM is always 0.

Just changing the identity of the system properties (case (2)) doesn't have this effect, so it's something about the cloning that causes the problem (note that Properties implements Cloneable), not about the change in object identity.

BTW, the attached trivial application also implements a fourth alternative that uses Properties.load/store rather then Object.clone to create a replacement copy; this alternative also sees the exit code stuck at 0, even though this copy (like the clone) is equal to (and has the same hashCode as) the original.
Comment 1 Eclipse Genie CLA 2016-04-01 10:59:47 EDT
New Gerrit change created: https://git.eclipse.org/r/69731
Comment 2 Thomas Watson CLA 2016-04-01 12:33:03 EDT
(In reply to Eclipse Genie from comment #1)
> New Gerrit change created: https://git.eclipse.org/r/69731

I have a gerrit review going to resolve this issue.  The issue is that the framework obtains the system properties object (from System.getProperties()) and holds onto that properties object for use later.  This is done only when osgi.framework.useSystemProperties=true which is set by default when using the Equinox launcher.

When using the new Properties(original); copy it "works" because that properties object will use the original properties object as defaults.  So when we set property values on the original properties object that we hold in the framework it effectively sets the default value used by the copy you set.

But if you clone or manually copy the values into a new Properties object that Properties object no longer delegates to the original to get the default values.

To work around this in your tests I would create a copy of the system properties key->values at the start and do not replace the properties object.  Then on test exit I would call System.getProperties().clear(); System.getProperties.putAll(origCopiedEntries);
Comment 4 Thomas Watson CLA 2016-04-01 16:40:01 EDT
Fixed in master.
Comment 5 Andreas Sewe CLA 2016-04-04 03:10:10 EDT
(In reply to Thomas Watson from comment #2)
> (In reply to Eclipse Genie from comment #1)
> > New Gerrit change created: https://git.eclipse.org/r/69731
> 
> I have a gerrit review going to resolve this issue.  The issue is that the
> framework obtains the system properties object (from System.getProperties())
> and holds onto that properties object for use later.  This is done only when
> osgi.framework.useSystemProperties=true which is set by default when using
> the Equinox launcher.
> 
> When using the new Properties(original); copy it "works" because that
> properties object will use the original properties object as defaults.  So
> when we set property values on the original properties object that we hold
> in the framework it effectively sets the default value used by the copy you
> set.
> 
> But if you clone or manually copy the values into a new Properties object
> that Properties object no longer delegates to the original to get the
> default values.

Yes, that's why I had the different alternatives in my example IApplication: to test whether object identity is an issue (it is) and what object exactly the framework holds a reference to.

> To work around this in your tests I would create a copy of the system
> properties key->values at the start and do not replace the properties
> object.  Then on test exit I would call System.getProperties().clear();
> System.getProperties.putAll(origCopiedEntries);

Yes, that will work (and even preserve the defaults, as clear and putAll don't touch them). I'll make that change in the meantime, while the Equinox fix trickles downstream.

Thank you very much for the fix.
Comment 6 Jan Sievers CLA 2016-04-04 11:41:21 EDT
*** Bug 490589 has been marked as a duplicate of this bug. ***
Comment 7 Thomas Watson CLA 2019-10-22 09:25:26 EDT
*** Bug 319679 has been marked as a duplicate of this bug. ***