Community
Participate
Working Groups
Build 2.0.1 When I try to run an ANT target which contains a space in its name I get a NPE! Test case: ================ <?xml version="1.0" ?> <project name="ANT Tests" default="" basedir = "."> <target name = "Test.One"> <echo message = "'Test.One' is running!"/> </target> <target name = "Test Two"> <echo message = "'Test Two' is running!"/> </target> </project> ================ The 2 targets I recognizes by the UI but when I try to run "Test Two" I got the NPE. Thanks Philippe
Created attachment 1921 [details] stack trace
Created attachment 1922 [details] stack trace (with line numbers)
Note that this problem did not occur in 2.0.
Note this works ok in the 2.1 stream builds. Am in the process of verifying changes.
org.eclipse.ui.externaltools.internal.core.DefaultRunnerContext.getAntTargets() This method returns an empty String array when it should have a single item which is the name of the target. (with the space in it) Debugging the code, it looks like #argStringToArrayList(String) is creating a StringTokenizer on spaces and quotes on the following string arg "${ant_target:Test Two}". Moving to Platform/UI [ExternalTools] for further investigation. Created bug 23350 for putting NPE protection code around the area which failed in org.eclipse.ant.core.
The problem is the code to split the argument string into individual argument items did not handle the case of variables whose content contain spaces. It should treat variables as one unit not try to process any space or double quote it may contain. For the 2.0.1 stream, the method DefaultRunnerContext.argStringToArrayList should now be the following code: /** * Parses the given string into an ArrayList of arguments. * * @return the ArrayList of arguments */ private ArrayList argStringToArrayList(String s) { ArrayList list = new ArrayList(10); if (s == null) return list; boolean inQuotes = false; boolean inVar = false; int start = 0; int end = s.length(); StringBuffer arg = new StringBuffer(end); while (start < end) { char ch = s.charAt(start); start++; switch (ch) { case ' ' : //$NON-NLS-1$ if (inQuotes || inVar) { arg.append(ch); } else { if (arg.length() > 0) { list.add(arg.toString ()); arg.setLength(0); } } break; case '"' : //$NON-NLS-1$ if (inVar) { arg.append(ch); } else { if (start < end) { if (s.charAt(start) == '"') { //$NON-NLS-1$ // Two quotes together represents one quote arg.append(ch); start++; } else { inQuotes = ! inQuotes; } } else { // A lone quote at the end, just drop it. inQuotes = false; } } break; case '$' : //$NON-NLS-1$ arg.append(ch); if (!inVar && start < end) { if (s.charAt(start) == '{') { // $NON-NLS-1$ arg.append('{'); //$NON- NLS-1$ inVar = true; start++; } } break; case '}' : //$NON-NLS-1$ arg.append(ch); inVar = false; break; default : arg.append(ch); break; } } if (arg.length() > 0) list.add(arg.toString()); return list; }
Released in the R2_0_1 stream and ported to the 2.1 stream also.