When causing a makefile to change directory and run ant in that new directory error "JAVA_HOME is not defined correctly" - windows

Even if you have Java and/or ant installed through the windows installers, you still need to set your environment variables. Make sure you are linking your java to a JDK rather than a JRE, my guess as a newbie is that when you are compiling your own code you should always use the JDK as it has all the tools you need.
Original post:
This is all happening on Windows. I call make. It checks out a "code" folder from svn into the directory that makefile is in. Inside "code", is a build.xml. I want my makefile to change to that directory and then run ant on it. I am getting the error in my command prompt:
C:\Users\Ryan\Desktop\maketest>make
svn co (address removed)
Checked out revision 107.
cd code; ant clean compile jar run
uname: not found
basename: not found
dirname: not found
which: not found
Error: JAVA_HOME is not defined correctly.
We cannot execute java
make: *** [runant] Error 1
I checked here http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_5.html#SEC46 and it seems that this should be do-able in my makefile:
runant:
cd code; ant clean compile jar run
as this will open the command in a subshell but it will also run ant in that subshell.
This all works fine if I manually change into the code folder and run ant. I only get this JAVA_HOME not defined correctly error when I try to do this all from a single makefile.
makefile:
commands = checkoutcode checkoutdocs runant
svnCode = https://version-control.adelaide.edu.au/svn/SEPADL15S2UG7/code/
svnDocs = https://version-control.adelaide.edu.au/svn/SEPADL15S2UG7/updateDocs
ifdef version
REVISION = -r$(version)
endif
all: full
full: checkoutcode checkoutdocs runant
# ensure you use a single tab for the commands being run under that name
checkoutcode:
svn co $(svnCode) $(REVISION)
checkoutdocs:
svn co $(svnDocs) $(REVISION)
#change directory into the code folder and compile the code
runant:
cd code; ant clean compile jar run
build.xml:
<project>
<!-- add some property names to be referenced later. first one is lib folder to hold all libraries -->
<property name="lib.dir" value="lib"/>
<!-- images directory used to compile with the images and also add them to the jar -->
<property name="src/images.dir" value="images"/>
<!-- ensure the classpath can see all classes in the lib folder by adding **/*.jar -->
<path id="classpath">
<fileset dir="${lib.dir}" includes="**/*.jar"/>
</path>
<!-- "Target" attribute is what we will write as a parameter to ant in the command prompt or terminal -->
<!-- eg. "ant clean" will run the commands inside the target tags, which is just to delete the directory
"build" -->
<target name="clean">
<delete dir="build"/>
<echo message="Cleaned "/>
</target>
<!-- compile command. creates a directory for the classes to be stored in, instead of the root folder
and then compiles everything in the src folder, using the classpath properties we set earlier -->
<target name="compile">
<mkdir dir="build/classes"/>
<javac includeantruntime="false" srcdir="src" destdir="build/classes" classpathref="classpath"/>
<echo message="Compiled "/>
</target>
<!-- jar command. this creates an executable jar file called Robot.jar which can run the program in full.
it uses the images and it uses the lejos libraries and embeds them into the jar -->
<target name="jar">
<jar destfile="Robot.jar" basedir="build/classes">
<fileset dir="src/images" />
<manifest>
<attribute name="Main-Class" value="Main"/>
</manifest>
<!-- this line adds everything in the lib folder to the classes being added to the jar,
ie. the lejos classes ev3 and pc -->
<zipgroupfileset dir="${lib.dir}" includes="**/*.jar" />
</jar>
<echo message="Created JAR "/>
</target>
<!-- run command. runs the program. Running the program in the command prompt or terminal is good
because it allows you to see any exceptions as they happen, rather than hiding them in eclipse -->
<target name="run">
<java jar="Robot.jar" fork="true"/>
<echo message="Run "/>
</target>
</project>
I am required to run this on different machines without any extra configuration performed, and will not be able to confirm the location of Java on those machines - the only guarantee I will get is that Java is installed and the environment variables work.

Just answering to allow you to mark as solved.
Even if you have installed Java with the oracle installer, you still need to create environements variables.

Even if you have Java and/or ant installed through the windows installers, you still need to set your environment variables. Make sure you are linking your java to a JDK rather than a JRE, my guess as a newbie is that when you are compiling your own code you should always use the JDK as it has all the tools you need.

Related

Setting environment variable through NSIS Envar-plugin

I have a custom installer created through NSIS.
I have the following Ant task doing the same:
<target name="buildNSIS">
<exec executable="D:\NSIS\nsis-binary\makensis.exe" failonerror="true" >
<!-- providing some nsis definitions -->
<arg value="/DPROJECT_NAME=${ant.project.name}"/>
<!-- passing the script -->
<arg value=".\installer\MySetup.nsi"/>
</exec>
</target>
where MySetup.nsi is the script to run through NSIS for the installer.
I want to set an environment variable as part of the install process.
I read that its best to do using: https://nsis.sourceforge.io/EnVar_plug-in
However, the instruction there is confusing. It just says: Just extract the contents to your nsis directory (usually '$PROGRAMFILES\NSIS')
What does it mean?
My D:\NSIS\nsis-binary directory looks like:
So do I unzip Envar_plugin.zip inside Plugins directory above and start using EnVar::AddValue or EnVar::AddValueEx functions inside my MySetup.nsi as mentioned in Envar_plugin examples?
How do I use Envar_plugin so that my resultant custom installer through MySetup.nsi for my software will set environment variables during installation of my software?
Plug-ins have to be installed in the correct plug-in subdirectory inside the NSIS folder. Some plug-ins only have a .DLL file in the root of the .ZIP file and some already have the correct directory tree in the .ZIP. This specific plug-in has the latter and you can just extract the contents to your main NSIS folder.
If you try to execute a plug-in command (name::function) and NSIS cannot find the plug-in then you most likely put the .DLL file in the wrong folder. Recent versions of NSIS will print a list of directories it tried to search when this happens.

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>

Ignoring system environment variables in ant

I set this property in my build.xml script of ant to ignore the system classpath during build, but ant still picks up the system classpath in my java call and merges it with my classpath specified in the build script.
<property name="build.sysclasspath" value="ignore" />
<path id="classpath">
<pathelement path="${buildDir}/classes" />
<fileset dir="${prjdir}">
<include name="lib/*.jar"/>
</fileset>
</path>
<java classname="com.ibm.biginsights.fs.gpfs.LoggingInjector" failonerror="true">
<classpath refid="classpath" />
</java>
If I unset the $CLASSPATH environment variable before calling ant everything works fine. What's the problem?
ANT is itself a java program so it's difficult to prevent tasks from using the same system classpath.
To properly isolate your java build, I'd recommend to setting the following attributes on the javac task:
<javac .... includeAntRuntime="false" includeAntRuntime="false" ...
Similarily, when running java programs, set the fork attribute so that it runs in another VM:
<java ...fork="true" classpathref="class.path.that.i.control"...
This property, AFAIK, is a system property that must be passed to ant (using ant -Dbuild.sysclasspath=ignore). But unsetting the CLASSPATH is probably as easy.
The main problam, IMO, is to use the CLASSPATH environment variable in the first place. I find it preferrable to always use the -cp or -jar option whan using Java, and not to rely on the system CLASSPATH. As soon as you have two Java programs that both rely on the system CLASSPATH, there is a risk of a clash between the dependencies of these two programs.

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