Different results when setting/getting System prop

2019-07-21 11:11发布

问题:

I'm perplexed by Groovy's behavior here. I've run through the debugger some to try to determine where in the dynamic mixins these code paths may be getting crossed but wondered if anyone could set me straight here.

Basically, in setting a system property with a GString for a value, depending on how I set the property, the property is not always readable back via certain methods.

I have seen Why Map does not work for GString in Groovy? and Why groovy does not see some values in dictionary? but my question specifically applies to map values so not sure those apply or not?

Snippet :

def tdollar='dollar'

System.setProperty('key1', 'value1')
System.setProperty('key2', "value2$tdollar")
// Replace the below with any property setting method other than
// the above with the same results
System.properties['key4']='value4'
System.properties['key5']="value5$tdollar"

println System.hasProperty('key1')
println System.hasProperty('key2')
println System.hasProperty('key4')
println System.hasProperty('key5')
println

println System.getProperty('key1')
println System.getProperty('key2')
println System.getProperty('key4')
println System.getProperty('key5')
println

println System.properties.keySet()
println

println System.properties['key1']
println System.properties['key2']
println System.properties['key4']
println System.properties['key5']

Output:

null
null
null
null

value1
value2dollar
value4
null

[java.runtime.name, sun.boot.library.path, java.vm.version, gopherProxySet, java.vm.vendor, java.vendor.url, path.separator, java.vm.name, file.encoding.pkg, user.country, sun.java.launcher, sun.os.patch.level, program.name, key5, key4, java.vm.specification.name, user.dir, key2, java.runtime.version, key1, java.awt.graphicsenv, java.endorsed.dirs, os.arch, java.io.tmpdir, line.separator, java.vm.specification.vendor, os.name, tools.jar, sun.jnu.encoding, script.name, java.library.path, java.specification.name, java.class.version, sun.management.compiler, os.version, user.home, user.timezone, java.awt.printerjob, file.encoding, java.specification.version, java.class.path, user.name, java.vm.specification.version, sun.java.command, java.home, sun.arch.data.model, user.language, java.specification.vendor, awt.toolkit, java.vm.info, java.version, java.ext.dirs, sun.boot.class.path, java.vendor, file.separator, java.vendor.url.bug, sun.io.unicode.encoding, sun.cpu.endian, groovy.starter.conf, groovy.home, sun.cpu.isalist]

value1
value2dollar
value4
value5dollar

Why, if I don't use System.setProperty(key, value) syntax, is the property not readable via System.getProperty(key), but is still readable via any other method?

Given this behavior, is there a best practice documented regarding System properties in Groovy.

Writing this, I wonder if this is just a general map question. Will test.

回答1:

System.setProperty('key2', "value2$tdollar")

When you operate using this above method, the second argument is implicitly cast to a String from a GString

System.properties['key5']="value5$tdollar"

this use the underlying setProperties method in the System class (not setProperty), and hence gets resolved differently, causing issues. The GString might not be getting cast correctly or not getting converted to a string before being sent to the underlying java class. If you change the value from a GString to a string like this:

System.properties['key5']="value5" + tdollar

the issue disappears