Community
Participate
Working Groups
Build Identifier: The problem is caused by the call to toString() for properties with null value ... for (Map.Entry<String, ? extends Object> entry : ctx.getProperties().entrySet()) props.put(entry.getKey(), entry.getValue().toString()); ... instead of toString() String.valueOf(entry.getValue()) should be used. Reproducible: Always
to reproduce it: 1. create a plugin with a valueVariables extension: <plugin> <extension point="org.eclipse.core.variables.valueVariables"> <variable initializerClass="bla.MyInitializer" name="envtest.variable" readOnly="true"> </variable> </extension> </plugin> 2. read an undefined env-variable in the initializer: public class MyInitializer implements IValueVariableInitializer { @Override public void initialize(IValueVariable variable) { variable.setValue(System.getenv("MY_HOME")); } } 3. create a buckminster ant-action in cspex of your plugin: <actions> <public actor="ant" name="myaction"> <actorProperties> <property key="buildFile" value="build/ant.xml"/> <property key="targets" value="myaction"/> </actorProperties> </public> </actions> 4. read the variable in ant-file abt.xml of the action: <project> <target name="myaction"> <echo>VAR=${envtest.variable}</echo> </target> </project> 5. invoke the ant-action "myaction" and you'll run into NPE in AntActor#internalPerform() line 236.
(In reply to comment #0) > The problem is caused by the call to toString() for properties with null value > ... > for (Map.Entry<String, ? extends Object> entry : > ctx.getProperties().entrySet()) > props.put(entry.getKey(), entry.getValue().toString()); > ... > > > instead of toString() String.valueOf(entry.getValue()) should be used. > The String.valueOf(null) returns the string "null" so perhaps this is better: for (Map.Entry<String, ? extends Object> entry : ctx.getProperties().entrySet()) { Object val = entry.getValue(); props.put(entry.getKey(), val == null ? null : val.toString()); } Another alternative is to simply skip a null property. I.e.: for (Map.Entry<String, ? extends Object> entry : ctx.getProperties().entrySet()) { Object val = entry.getValue(); if(val != null) props.put(entry.getKey(), val.toString()); } What would be most appropriate for your use case?
(In reply to comment #2) > The String.valueOf(null) returns the string "null" so perhaps this is better: > > for (Map.Entry<String, ? extends Object> entry : > ctx.getProperties().entrySet()) { > Object val = entry.getValue(); > props.put(entry.getKey(), val == null ? null : val.toString()); > } > I think this is a good solution. But i don't know exactly what happens in ant if a property is requested whose value is null. (hopefully a understandable error message :) ) > > for (Map.Entry<String, ? extends Object> entry : > ctx.getProperties().entrySet()) { > Object val = entry.getValue(); > if(val != null) > props.put(entry.getKey(), val.toString()); > } > In this case a property is skipped and a user might wonder why. I think it's neccessary to know that the property is null. => So in our case the first solution whould be the better one.
I also prefer the first solution. It's now released to helios-maintenance, rev 11517.
.