2
votes

I have a test run via ant which includes a component that checks to make sure a path provided as an argument is a directory, using:

 File dir = new File(path);
 if (!dir.isDirectory()) {
      System.err.println("Invalid directory "+path+".");

When run via the ant task:

    <java
        classname="foo.bar"
        classpath="${classpath}"
    >
        <arg value="-d ${testDir}"/>

Where testDir is a location property containing a relative path, the component fails with the "Invalid directory" message reflecting the absolute (but correct) path.

When run directly from the same location sans ant, using java -cp[yada] foo.bar -d /the/exact/same/absolute/path, there is no such problem.

I am quite new to ant and presume there is some permission I have to grant here?

Note that:

  • ${testDir} is a subdirectory, i.e., it does not lead up out of the project tree.
  • The absolute path of ${testDir} and all the components therein are world readable.
2

2 Answers

1
votes

If testDir is a relative path, it will be resolved using system property user.dir by default. A quick solution is run ant in parent dir.

You can also add dir to specify current directory when java task running.

<java
    classname="foo.bar"
    classpath="${classpath}"
    dir="${parentDir}"
    fork="true"
>
    <arg value="-d ${testDir}"/>

The attribute fork="true" is required if you get following message:

[java] Working directory ignored when same JVM is used.

0
votes

I noticed something interesting looking more closely at the output. The project directory is /home/devel/project/ (but note /home/devel is not a normal home directory; devel is just a group and that directory is world readable, and also writable by the executing user). The ${testDir} is (again) a relative path, test/serverconf, which ant then correctly resolves to `/home/devel/project/test/serverconf.

But here's what I noticed in the error from the component:

Invalid directory  /home/devel/project/test/serverconf.
                 ^^

There are two spaces there, whereas the error message itself only produces one. If I try to run the application java foo.bar.Server -d " /home/devel/project/test/serverconf", of course I get the same error. It's not looking for an absolute path in this case, it's looking for a relative one starting with a space character (if I'd used quotes on the bad arg in the error message, this would have been clear).

However, this is an ant bug in the sense that it explicitly contradicts the documentation, which clearly states under "Examples":

<arg value="-l -a"/>

is a single command-line argument containing a space character, not separate commands "-l" and "-a".

In the build.xml, there is only one space in -d ${testDir}. I tried -d${testdir}, since the command line parser (org.apache.commons.cli) will accept it either way. What it will choke on is -d " /whatever/path".

So ant is resolving ${testDir}, then passing two arguments in, "-d", and " /home/devel/project...". If this were then just a subtlety of how ant substitutes variables, I would say okay, "bug-like" but since there's a potential caveat which provides an exception to the documented example, it's just a gotcha.

But using the literal path instead of a variable:

<arg value="-d test/serverconf">

Leads to the same issue:

Invalid directory  test/serverconf
                 ^^

And to be clear again, the relative path will work fine here when java foo.bar.Server is run from the same directory as ant target. But not if used -d " test/serverconf", because the user should be allowed to use quotes and include spaces that way.

So the statement about arg value in the documentation is false. Ant is not passing it through as "a single command-line argument containing a space". It is passing it through as two arguments and including the space in the second one.

Go figure.