ant java task with space issue - windows

I was trying to execute a jar file via ant script. Like this
<java jar="${jar.file}" fork="true" failonerror="true">
<arg line="${jar.args}"/>
</java>
jar.file has full path to the jar file and contains some space in it.
When I executed that on Linux, there was no problem. But when I do the same on Windows I got error. java task couldn't locate the jar! I've tried all different variations like wrapping the file path with quote ("), replaced space with ", tried escaping with backslash, etc. Non works!
Did anyone come across this issue? Just wondering if this is Ant's limitation or I missed something.
P.S Sorry for not providing the full error message I got. I'm away of my Windows PC right now. As a workaround, I decided to copy the jar to C:\ and used that instead.

The recommended way to handle space problems within properties is to put them in
extra '', which should work in most cases, even better to use a path without spaces
<java jar="'${jar.file}'" fork="true" failonerror="true">
<arg line="${jar.args}"/>
</java>
should work, as already mentioned in my comment.
edit
you're right it won't work because of the relative path with only jar attribute
in fact i thought of something like :
<project>
<property name="jar.file" value="foobar.jar"/>
<property name="jar.dir" value="/home/rosebud/temp/path with blanks"/>
<java
dir="${jar.dir}"
jar="${jar.dir}/${jar.file}"
fork="true"
failonerror="true"
>
<arg value="..." />
</java>
</project>
and it works unexpectedly also with spaces in path as f.e. in the snippet above
thought the standard way to handle space problems would fit in as in other cases :
"'${property with blanks}'"
but it doesn't.

Related

javah cannot find dependent classes from spring-context-3.0.3.jar file

Am usning ANT tasks to compile java classes and then generate .h files using
javah [ version "1.7.0_55" ] on windows 7
following is the code snippet from my build.xml
...
<property name="build.dir" value="./main/test_target"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="external.lib.dir" value="./externalJars"/> <!-- contains spring-context-3.0.3.jar file -->
<property name="jni.output.dir" value="${build.dir}/jniHeaders"/>
..
...
<target name="compile-header" depends="build">
<exec executable="javah">
<arg line="-classpath ${classes.dir};${external.lib.dir} -o ${jni.output.dir}/MyNativeImpl.h -verbose -force examples.MyNativeImpl"/>
</exec>
</target>
...
..
But I am not able to generate the .h files and get the following ERROR
Error: Class org.springframework.context.MessageSource could not be found.
even though I have added "spring-context-3.0.3.jar" to externalJars dir => ${external.lib.dir}
My java file MyNativeImpl.java uses package "import org.springframework.context.MessageSource; "
Java file compilation goes fine using ${external.lib.dir} and MyNativeImpl.class also generated under ${classes.dir}
Not sure what am I doing wrong!!
Almost spend 1 day searching on SS but could find a specific solution.
I have many such dependent jars from spring framework to compile my app fully under ${external.lib.dir} hence wanted to know how could this be resolved so than JAVAH could find classes within .jar files !!
Surprisingly I have a work-around which is:
1. unzip the contents of pring-context-3.0.3.jar to CLASSES DIR ${classes.dir}
2. now my ${classes.dir} has following contents
a. examples/MyNativeImpl.class
b. org/springframework/context/MessageSource.class ( and other classes )
3. Now JAVAH doesn't complain and generate my MyNativeImpl.h
But I am now sure why it doesn't find the same MessageSource.class when I use spring-context-3.0.3.jar ??
Is there something I am missing or this is the only way :-( any help is highly appreciated.
Thanks in Advance
Regards,
Vivek
When specifying jars on a classpath, you must list each jar. The directory containing the jar is not enough, that only works for classes, explaining why your work-around works.
I suggest something like:
<path id="javah.path">
<pathelement location="${classes.dir}"/>
<fileset dir="${external.lib.dir}" includes="*.jar"/>
</path>
<pathconvert property="javah.classpath" refid="javah.path"/>
<exec executable="javah">
<arg line="-classpath ${javah.classpath} -o ... />
</exec>
PS
Why don't you use the javah ANT task?

In eclipse executing Sass with ANT task. Why have I to set 'executable' to 'sass.bat' instead of 'sass'?

I have this ANT task to execute Sass in an eclipse project:
<project basedir="." default="sass">
<target name="sass">
<apply dest="www/styles" executable="sass">
<srcfile/>
<targetfile/>
<fileset dir="styles" includes="*.scss"/>
<mapper from="*.scss" to="*.css" type="glob"/>
</apply>
</target>
</project>
It works fine in Ubuntu. In Windows 7 I have to set the executable as sass.bat.
This is the error:
Buildfile: D:\my_workspace\my_project\build.xml
sass:
BUILD FAILED
D:\my_workspace\my_project\build.xml:3: Execute failed: java.io.IOException:
Cannot run program "sass" (in directory "D:\my_workspace\my_project"):
CreateProcess error=2, The system cannot find the file specified
Total time: 326 milliseconds
Both, sass and sass.bat can be invoked from the command line so as the Ruby/bin folder is in system PATH variable.
I don't want to mantain two versions of this file for different OS.
How can I solve this?
[not an answer-but too big for comment ]
Windows shell understand how to expand pathext. Ant does not interpret - it only try .exe, not others.
See comments for Windows Users
The task delegates to Runtime.exec which in turn apparently
calls ::CreateProcess. It is the latter Win32 function that defines
the exact semantics of the call. In particular, if you do not put a
file extension on the executable, only ".EXE" files are looked for,
not ".COM", ".CMD" or other file types listed in the environment
variable PATHEXT. That is only used by the shell.
Note that .bat files cannot in general by executed directly. One
normally needs to execute the command shell executable cmd using the
/c switch.
A common problem is not having the executable on the PATH. In case you get an error message
Cannot run program "...":CreateProcess error=2. The system cannot find
the path specified. have a look at your PATH variable. Just type the
command directly on the command line and if Windows finds it, Ant
should do it too. (Otherwise ask on the user mailinglist for help.) If
Windows can not execute the program add the directory of the program
to the PATH (set PATH=%PATH%;dirOfProgram) or specify the absolute
path in the executable attribute in your buildfile.
I've solved it by adding the conditional variable exec_file with value sass.bat for Windows family OS and sass for other.
<project basedir="." default="sass">
<condition property="exec_file" value="sass.bat" else="sass" >
<os family="windows" />
</condition>
<target name="sass">
<apply dest="www/styles" executable="${exec_file}">
<srcfile/>
<targetfile/>
<fileset dir="styles" includes="*.scss"/>
<mapper from="*.scss" to="*.css" type="glob"/>
</apply>
</target>
</project>

Ant file set using path with spaces in it

I'm making someone else's ant build work with a source path that contains a space. Most of it has been basic shell script stuff, adding double-quotes around paths, but this one has me stumped:
(from build.xml):
<path id="headers">
<fileset dir="${source.main.dir}">
<include name="**/*.h"/>
</fileset>
</path>
source.main.dir is a path containing spaces. It's prepended to each of the include file names found by the pattern. How do I get this to happen with quotes around each one?
In case it matters, I'm running the build from the command line on OS X Lion 10.7.4.
I think I got it! I changed:
<pathconvert pathsep=" " property="doc.files.list" refid="headers" />
to
<pathconvert pathsep=" " property="doc.files.list" refid="headers">
<map from='${source.main.dir}' to='"${source.main.dir}"' />
</pathconvert>
And it seems to be working now.

Generate Checksum for directories using Ant build command

I tried to generate the checksum for directory using ant.
I have tried the below command, but it generates recursively inside each folder for each file.
<target name="default" depends="">
<echo message="Generating Checksum for each environment" />
<checksum todir="${target.output.dir}" format="MD5SUM" >
<fileset dir="${target.output.dir}" />
</checksum>
</target>
I just want to generate one checksum for particular directory using Ant command.
How do I do that?
You want to use the totalproperty attribute. As per the documentation this property will hold a checksum of all the checksums and file paths.
e.g.
<target name="hash">
<checksum todir="x" format="MD5SUM" totalproperty="sum.of.all">
<fileset dir="x"/>
</checksum>
<echo>${sum.of.all}</echo>
</target>
Some other general notes.
This is not idempotent. Each time you run it you will get a new value because it includes the previous hash file in the new hash (and then writes a new hash file). I suggest that you change the todir attribute to point elsewhere
It's a good idea to name your targets meaningfully. See this great article by Martin Fowler for some naming ideas
You don't need the depends attribute if there's no dependency.

Apache ant deleting directories no matter what

How do I get Apache Ant to delete a directory no matter what. I want it to be deleted even if there are locks or usages of the directory on windows.
I am using a continuous integration remote agent on a Windows box which fails to delete the build directory and as a result fails the build. This is extremely annoying and is disruptive to the statistics.
There is nothing actively using the directory, and the antivirus is disabled.
I just want to delete the directory no matter what. How can I achieve that on Windows with Apache Ant?
I think you will need external program to do this.
check this one:
_http://www.codeguru.com/cpp/w-p/files/fileio/article.php/c1287
here you have comparison of unlocking tools.Check this with command line interface:
_http://ccollomb.free.fr/unlocker/
If you know what process is holding your folder you can just call taskkill...(you can even kill explorer.exe but and you can start it again)
and if your folder is shared you can use net delete command
The best you can do in Ant is to set the parameters: quiet="true" and includeemptydirs="true" in order to prevent the build halting when the directory is missing or when a lock exists and to delete the top level directory even if it is empty. Eg:
<delete quiet="true" includeEmptyDirs="true">
<fileset dir="stubbornDir"/>
</delete>
You can also make sure that the resources you are attempting to delete are not read only, so include something like this in your script before your <delete> task:
<!-- The following only works on UNIX -->
<chmod perm="a+w">
<fileset dir="${dist.dir}">
<include name="**/*.jar"/>
<exclude name="${app.context.path}"/>
</fileset>
</chmod>
<!-- Win NT alternative -->
<echo message=" To permit file deletion, execute attrib.exe to change read permissions on: ${dist.dir}"/>
<exec dir="${dist.dir}" executable="attrib.exe" os="Windows NT,Windows 2000,Windows XP">
<arg line="-R **/*.jar"/>
</exec>
But, to answer your question, I'm afraid, using Ant, it is not possible to delete files or directories when a lock exists.
However, also be aware, if you have used the <javac> task earlier in your script, then unless you have set fork="true", the task will lock all files in your classpath and keep them locked during the entirety of your build.
Hope this helps!

Resources