24

If I specify a system property multiple times when invoking the JVM which value will I actually get when I retrieve the property? e.g.

java -Dprop=A -Dprop=B -jar my.jar

What will be the result when I call System.getProperty("prop");?

The Java documentation on this does not really tell me anything useful on this front.

In my non-scientific testing on a couple of machines running different JVMs it seems like the last value is the one returned (which is actually the behavior I need) but I wondered if this behavior is actually defined officially anywhere or can it vary between JVMs?

RobV
  • 28,022
  • 11
  • 77
  • 119
  • IMHO, specifying this would be a bit like warning about not putting your cat in the microwave. why would you specify the same system property twice, except if you really like problems? – JB Nizet Jun 08 '12 at 22:24
  • 2
    In this case there are some shell scripts invoking the JVM with some default settings but users should be able to specify system properties which get passed through the script to the JVM. – RobV Jun 08 '12 at 22:37
  • Ah, OK. Fair enough. I didn't think about this use-case. – JB Nizet Jun 08 '12 at 22:39
  • 1
    I am now desperately trying to think of a use-case for putting a cat in a microwave. – Russell Jun 09 '12 at 00:13

3 Answers3

16

There's nothing like writing a little class to see how it works.

public class PropTest {

  public static void main(String[] args) {
    System.out.println(System.getProperty("prop"));
  }

}

Which when compiled and ran with the command line

java -Dprop=A -Dprop=B -Dprop=C PropTest

yeilds the output

C

Which would imply that the values are put into the table left to right, with the last value overwriting previous values.

Just to make a note of the environment, Fedora 16, Linux 3.3.7, 64 bit

> java -version

java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.1) (fedora-65.1.11.1.fc16-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • 2
    **Which would imply that the values are put into the table left to right, with the last value overwriting previous values.** One might make that assumption, but OP already tried this kind of example and found the same results. Is there anything that actually prescribes this, though? Would *depending* on this behavior make sense, or is this just an implementation detail? – Joshua Taylor Oct 06 '15 at 12:50
  • @JoshuaTaylor Generally the specifications don't cover such corner cases. Just because you have an implication how it is being processed today often doesn't mean you can assume it will be handled that way in the future. Spec writers have a hard enough time detailing the desired behavior without detailing how a person who sets on atom of desired behavior two or three times will be handled :) – Edwin Buck Oct 06 '15 at 20:50
  • Spec writers are often very good at handling specific details. It can simplify and help standardize the implementation process. E.g., in Common Lisp, which supports named arguments (keyword arguments), so that you can have a call like `(print 52 :radix 10 :radix 8)`, the standard [specifies](http://www.lispworks.com/documentation/HyperSpec/Body/03_dad.htm) that 'If more than one such argument pair matches, the leftmost argument pair is used." – Joshua Taylor Oct 06 '15 at 21:13
  • 1
    I think that these specifications are actually pretty important for command line and argument list processing, because it's often the case that users/programmers *do* want to be able to override, e.g., by doing something like `program ${EXTRA_OPTIONS} -o default-o -f default-f`. If leftmost options override those to the right, then that code lets users override defaults by defining EXTRA_OPTIONS. This seems like a fairly reasonable thing for spec writers to make well-defined. – Joshua Taylor Oct 06 '15 at 21:15
  • @JoshuaTaylor It is ok to think that specifications are important. If you set the maximum heap size, and the JVM uses that value as the maximum heap size, then odds are the desired behavior was used, and likely it was used according to the spec. Now if you set the maximum heap size three times, I don't think the spec should cover which one is the winner in the competition for setting the maximum heap size. If anything, I would have made the second setting a failure; but that's disruptive. Many would just be happy it was using one of the many specified values, but few would argue which one. – Edwin Buck Oct 07 '15 at 04:25
  • 3
    **"if you set the maximum heap size three times,"** That's just it, though; I don't think that anyone's claiming, or desiring, or expecting the heap size to be set three times. I think people are expecting it to be set just once. The question is whether the behavior of `java -Dheap=A -Dheap=B -Dheap=C` is specified and whether heap would have an unambiguous (single) value. As far as I can see, it's not specified. It wouldn't have been difficult for the spec writers to say "the rightmost setting is used", but it doesn't appear that they did. – Joshua Taylor Oct 07 '15 at 04:39
  • For what it's worth, I only gave the example that I did in [my earlier comment](http://stackoverflow.com/questions/10956676/if-i-specify-a-system-property-multiple-times-when-invoking-jvm-which-value-is-u/10958164?noredirect=1#comment53785233_10958164), because I think the use case is similar to [the one that RobV](http://stackoverflow.com/questions/10956676/if-i-specify-a-system-property-multiple-times-when-invoking-jvm-which-value-is-u/10958164?noredirect=1#comment14302923_10956676) mentioned. It's nice to be able to wrap APIs/CLIs and give users an easy way to flexibly override settings. – Joshua Taylor Oct 07 '15 at 04:41
  • @JoshuaTaylor The question is all about setting the same property multiple times, so while it doesn't make a lot of sense, Yes, it is about "java -Dheap=A -Dheap=B -Dheap=C" and which one will the heap really be set to? The real answer is the one I gave. I don't know, but here's how you test it. My findings are X and I suggest that if it really matters, you test it in your environment. Neither one of the two comments you linked to really is "the same thing" as this issue. Wanting the spec to be better is fine, but few write a spec that defines an outcome for irrational behavior. – Edwin Buck Oct 07 '15 at 04:55
9

The java.util.System class is backed by a Properties class, which is just an extension of Hashtable. Assuming the values are read in order when passing as arguments to the JVM, then the last value assigned will be the final value.

tjg184
  • 4,508
  • 1
  • 27
  • 54
4

I'm not sure if there's anything documented for Oracle.

According to IBM JRE documents:

The sequence of the Java options on the command line defines which options take precedence during startup. Rightmost options have precedence over leftmost options.

RobV
  • 28,022
  • 11
  • 77
  • 119
MotiNK
  • 421
  • 2
  • 12