Bug 23273 - Java task interprets it's arguments incorrectly if terminated with \\
Summary: Java task interprets it's arguments incorrectly if terminated with \\
Status: NEW
Alias: None
Product: Ant
Classification: Unclassified
Component: Core tasks (show other bugs)
Version: 1.5.4
Hardware: PC All
: P3 normal (vote)
Target Milestone: ---
Assignee: Ant Notifications List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-09-19 15:55 UTC by Roger
Modified: 2013-02-12 06:54 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Roger 2003-09-19 15:55:37 UTC
Consider the following ANT task :

        <java classname="MyClass" failonerror="true" fork="true">
            <arg value="Some text\\"/>
            <arg value="Second argument" />
        </java>
 
Which is used to invoke the following Java class :

    public final class MyClass
    {
        public static void main( String[] args )
        {
            int loop = -1;
            while ( ++loop != args.length )
            {
                System.out.println ( loop + ")\t" + args[ loop ] );
            }
        }
    }
 
 
 
The expected output would be:
 
     [java] 0)  Some text\\
     [java] 1)  Second argument
 
 
What actually happens is
 
     [java] 0)  Some text\" Second
     [java] 1)  argument
 
  
 
The first argument has a trailing double back-slash character. This has been 
replaced by a single back slash and a double quote character.

ANT has then broken the second argument into two parts, as separated by a space 
character. The first part of this argument has been concatenated with the first 
argument! If there had been no space character in the second argument, then it 
would have been completely concatenated with the first argument.
Comment 1 Stefan Bodewig 2003-09-22 15:28:17 UTC
Does ant -verbose geve any extra hint?

This is what I get on Linux using 1.5.4

Buildfile: /tmp/java.xml

java:
0)	Some text\\
1)	Second argument

BUILD SUCCESSFUL
Total time: 2 seconds
Comment 2 Roger 2003-09-22 15:39:56 UTC
I couldn't say if this works under Linux - I'm using Winodes 2000.

The -verbose trace looks Ok (see below)

     [java] Executing 'C:\jre\bin\java.exe' with arguments:
     [java] '-classpath'
     [java] '-classpath'
     [java] 'C:\ant\ant.jar;C:\jre\lib\rt.jar;C:\log4j\log4j.jar
     [java] 'myClass'
     [java] 'Some text\\'
     [java] 'Second argument'

Java -version reports the following

java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

Comment 3 peter reilly 2003-11-21 13:16:33 UTC
The problem is most likely in java's Exec code for Windows.
There has been a change between 1.4 and 1.4.2 in handling of \ at
the end of a parameter. (java.lang.Win32Process).

Please test with 1.4.2
Comment 4 peter reilly 2003-11-21 13:17:31 UTC
Opps that should be Please test with java 1.4.2
Comment 5 Roger 2003-11-21 14:05:22 UTC
Tested with java version 1.4.2. It fails as descibed above.

:-(
Comment 6 Stefan Bodewig 2008-07-10 06:07:21 UTC
can confirm that it still fails with Ant 1.7.1 and JDK 6 Update 7 on Windows.
Comment 7 Dumitru Postoronca 2008-12-19 02:23:35 UTC
(In reply to comment #6)
> can confirm that it still fails with Ant 1.7.1 and JDK 6 Update 7 on Windows.
> 

This seems to be a JVM issue as there are a lot of bug reports on bugs.sun.com related to using Runtime.exec() method in Windows and command line parsing.

I wrote a simple program that uses Runtime.exec() and I got the same (bad) results as shown in the bug report so it's not ant-related (though it would be nice if ant had a work-around for this).

====
	public static void main(String[] args) throws IOException, InterruptedException {
		Process p =  Runtime.getRuntime().exec(new String[] {"java.exe", "MyClass", "a \\", "222" }, null, null);
		//p.waitFor();
		
		BufferedReader in  = new BufferedReader(new InputStreamReader(p.getInputStream()));

		String s;
		while((s = in.readLine()) != null) {
			System.out.println(s);
		}
		
	}
====
Comment 8 Vincent Belaïche 2013-02-12 06:54:16 UTC
Please have look at the bug which I filed #54285 (please note that the description of the bug is entered with Jira markup, this is because I initially did a mistake and filed the bug on ivy jira).

The root problem is the way how MSWindows escapes double quotes: to escape a double quote you have to do this way:

Let N be the number of backslash(es) preceding the double quote to be escaped (with N>=0), then replace the N backslash(es) by 2*N+1 backslash(es) and your double quote gets escaped.

Now, the thing is that a group of N tailing backslahes, N>=1, is to be considered as followed by a double quote --- that double-quote that is part of the whole argument quoting --- so they must also be replaced by 2*N+1 backslashes.

The problem is that I could not find that this escaping technique is documented anywhere except in some discussion forum. Furthermore you can also quote one double quotes by replacing by 3 consecutive double quotes, and that works when there are no backslash --- so some people do that and everybody gets confused.

Now the question is whether this is a problem of Ant, or a problem of the JVM. I would tend to think that this is not a problem of the JVM, and that you have to pass to the JVM a command line that is correctly formatted for the underlying platform --- just like in a GNU Makefile shell commands have to follow the shell syntax. This means that you need some class to do platform dependent command-line formatting --- this is what is missing in the standard JAVA libraries. Then this standard class could be deployed differently depending on the platform. So, in my opinion this is more an issue of standard JAVA library than of pure JVM implementation --- well one could also consider that the JVM comprises a set of standard libraries, but I think that this is not correct wording.

I proposed some code to do the escaping for one argument. I think one has to see what is the intention on the JVM/Standard library side before to take any decision. Maybe they do something new that would solve the problem more easily. But then there should also be some way to keep Ant executable on older JVM deployments. So maybe the temporary solution is to do the platform escaping job by some Ant own code.

Anyway, I suggest to mark this bug as duplicate with #54285