I am pretty new to ant (I came from Maven and Ant is a nightmare for me !!!)
I have this target:
<target name="linuxdriver"
description="Linux Driver">
<copy file="${deps.linuxdriver.dir}/${deps.linuxdriver.name}" tofile="${project.datadir}/${deps.linuxdriver.name}"/>
<copy file="${deps.linuxdriver.dir}/${deps.linuxdriver.name}" tofile="${project.deploy}/data/${deps.linuxdriver.name}"/>
<chmod perm="+x" file="${project.datadir}/${deps.linuxdriver.name}"/>
<chmod perm="+x" file="${project.deploy}/data/${deps.linuxdriver.name}"/>
</target>
and I have also a property file in which there is definied the "variable" (are named variable?) used in the previous ant code, specifically I have:
project.datadir = ${basedir}/data
project.deploy.dir = Release
project.deploy = ${basedir}/../${project.deploy.dir}
And now I have some doubts:
1) What represents ${basedir}? A specific directory? What?
2) Using the previous information what exactly are the two destination folder in which the files are copied (using the "copy file...to file" tag)?
That concept of basedir is described in the ANT manual:
Built-in properties
Writing a simple Buildfile
It's normally set to be the directory from where you run the build (can be overridden).
If you need to see how properties are resolved, consider running your build in debug mode
Related
I am trying to write an ant target that will create a jar based on a bunch of java files and some properties files, but am having trouble including the properties files the way the project is set up currently.
These are the ant targets I have:
1 - Compile the java souce files from the "myjar.src" folder and put the resulting classes into a "myjar.classes" folder. Once this is done copy all non .java files from "myjar.src" to "myjar.classes".
2 - Create the jar using the "jar" command using basedir = ${myjar.classes} and tell it to include everything.
These are the ant targets I want:
1 - Compile the java souce files and put the resulting classes into a "myjar.classes" folder. Only .java files are included
2 - Create the jars using the "jar" command using basedir = ${myjar.classes.location} but also include the .properties and .xml files from "myjar.src."
The key difference is I want the properties and xml files from "myjar.src" to be included when I package up the classes in "myjar.classes" using basedir = ${myjar.classes} - How do I include these fies when they are not underneath "myjar.classes"?
This is the ant target I want to modify:
<CreateManifest title="myjar classes etc"/>
<jar
destfile="${myProject.build.jars.dir}\ta_test_driver.jar"
basedir="${myjar.classes}"
manifest="${manifest}">
<include name="**"/>
</jar>
The reason I am not just using a directory one level up for basedir is that none of the other jar creation calls in the project do that, and I am hesitant to change that for just this one. I did try to do that, but had trouble specifying the right directory. (There are other jars that use a similar directory structure, and I don't want to interfere with them either now or in the future.) I was just wondering if these is a better way to do this? Thanks very much.
I managed to figure this out from here: How to include file in Jar through Ant at specific location
This was my modified ant call in the end:
<CreateManifest title="myjar classes etc"/>
<jar
destfile="${myProject.build.jars.dir}\ta_test_driver.jar"
basedir="${myProject.classes}\ta_test_driver"
manifest="${manifest}">
<include name="**"/>
<zipfileset dir="${myjar.src}"
includes="**/*.xml, **/*.properties, **/*.gif"
/>
</jar>
Notice the zipfileset tag.
This question already has an answer here:
Some clarification about how ant copy some files into a folder?
(1 answer)
Closed 8 years ago.
I am pretty new to ant (I came from Maven and Ant is a nightmare for me !!!)
I have this target:
<target name="linuxdriver"
description="Linux Driver">
<copy file="${deps.linuxdriver.dir}/${deps.linuxdriver.name}"
tofile="${project.datadir}/${deps.linuxdriver.name}"/>
<copy file="${deps.linuxdriver.dir}/${deps.linuxdriver.name}"
tofile="${project.deploy}/data/${deps.linuxdriver.name}"/>
<chmod perm="+x" file="${project.datadir}/${deps.linuxdriver.name}"/>
<chmod perm="+x" file="${project.deploy}/data/${deps.linuxdriver.name}"/>
</target>
and I have also a property file in which there is definied the "variable" (are named variable?) used in the previous ant code, specifically I have:
project.datadir = ${basedir}/data
project.deploy.dir = Release
project.deploy = ${basedir}/../${project.deploy.dir}
deps.linuxdriver.name = atmosfs
And now I have some doubts:
1) What represents ${basedir}? A specific directory? What? Reading on the ant manual (http://ant.apache.org/manual/properties.html) say that this is: the absolute path of the project's basedir (as set with the basedir attribute of ).
So, is it the absolute path of my project in the Eclipse workspace?
2) Using the previous information what exactly are the two destination folder in which the files are copied (using the "copy file...to file" tag)?
1) What represents ${basedir}? A specific directory?
Yes. ${basedir} is the directory where you either started Ant, or the directory specified in the <project> entity on the top of your Ant file. Normally, it is set to "." which makes it the same directory as the directory that contains your Ant build file.
2) Using the previous information what exactly are the two destination folder in which the files are copied (using the "copy file...to file" tag)?
You didn't list your whole Ant file, and your whole properties file. I'm not even sure if your properties file is read in (You need a <property file="xxxx.properties"/> near the top of your Ant file).
Assuming that you are executing this in the same directory as your Ant file, and your ${basedir} is the same directory as your Ant file:
<copy file="${basedir}/atmosfs/atmostfs"
verbose="true"
tofile="${basedir}/Release/atmosfs"/>
<copy file="${basedir}/atmofs/atmofs"
verbose="true"
tofile="${basedir}/../Release/data/atmofs"/>
Again, I am assuming ${basedir} is the directory where your Antfile is stored, and that you are executing the script from that directory.
Notice I have verbose="true" in the <copy>. I recommend you make that change. This will show you what file is being copied and where when <copy> is executed. It's probably the best way to handle this.
By the way, one rule I have is that all action takes place in the project tree. Your last tofile is being written outside of the project directory (where I assume your Ant file is located). Imagine someone checking out the project, and finding out that the build process wrote a file outside of the checked out directory and onto his computer in a random place. Doing this is just considered impolite.
Even more polite is to write all files and do all build processing under a subdirectory. Some people use build, I prefer target because that's a Maven standard. THe idea is that I can clean up the entire build process by simply deleting that one directory.
I am trying to write ant build for compiling source folder here is my script target for compiling.
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${classes.dir}" debug="true">
<classpath refid="master-classpath"/>
</javac>
</target>
In my project I have near about 1000 .java files. When ever a single .java file is changed above target tends to compile all .java files. Which make development very slow. I just want to know is there any way or code to change the behavior of task to compile only modified or changed .java file rather than all .java file.
Please help me.
As I understand, compiling only the modified java files is the default behavior of ant javac task. Ant uses the timestamp of a .java file and its corresponding .class file to determine if the a Java file needs to be recompiled. I have used it in many projects and never have issues.
Here are a few things you can check
Is your source tree directory structure matching your Java package
structure? Please see Why does ant always recompile all my Java
files?. This is probably the number 1 reason since it is in the FAQ.
I see your compile target depends on init target? What does the init target do? Does it depends on any clean target or does it cleanup the .class files?
What is your ant version? Can you try a different ant version to see if you still have the same problem?
If none of the above fixes your issue, after the compilation, can you manually check the .class file timestamp and compare it with the timestamp of the corresponding .java file?
So if you are not deleting the classes directory in any dependent task say 'clean' the javac task inherently compiles only the changed java files. It is an out of the box feature that javac task provides. Hope it helps.
I just whipped up a medium-sized utilities JAR to be used by many other Eclipse projects. I spent a good deal of time writing tedious javadocs so that it would be pretty obvious how to use the API.
I used Ant to throw everything in a JAR, and I am now adding that JAR to the build path of a new project. But low and behold...when I mouseover any of my utility classes/methods, the tool tip that pops up says:
Note: this element neither has attached source nor attached Javadoc
and hence no Javadoc can be found.
What is going on here? What's the solution? Here is the dist Ant target that JARs up my utilities project:
<target name="dist" depends="compile">
<jar jarfile="dist/testing-utils.jar">
<fileset dir="bin/main" />
<fileset dir="src/main/config" />
</jar>
</target>
What else do I need to configure?!? Thanks in advance!
The java compile task, which I assume you're using in the "compile" target, generates bytecode from your Java source. This bytecode will not include comments by design and thus your distribution jar will not include comments.
What you are probably looking for is to attach the source in Eclipse to get access to the Javadocs. You can attach source to your library jars by right clicking on the target jar, selecting properties, select Java Source Attachment and provide the location of the source jar. You can also provide a folder location, if you want to reference your project directly.
To generate a Jar that includes javadocs and source, you may use the following in ant:
<target description="bundle sources in a jar" name="package-sources">
<jar basedir="src" destfile="build/release/${ant.project.name}-${project.version}-sources.jar"/>
</target>
Reference
If you do want to ship sources then johncarl's answer is probably correct; it is the first of the two options offered by eclipse -- attached sources. If you don't want to ship sources then you need to generate javadocs, see the ant javadoc task. With that approach, you would have two jars, one containing the compiled classes and another containing documentation. In eclipse, your users will add the class jar to project and then attach to it the javadoc jar.
How do you add a folder (e.g. a resource folder containing arts) to the classpath of a netbeans project? I managed to do that manually via editing the NB generated jar file of the project (that is its MANIFEST.MF file + copying the resources manually), but there should be a way to tell netbeans as well to mind the resources, no?
The folder structure looks like this:
/project/art/
/project/dist/lib/
/project/dist/art/
/project/dist/project.jar
/project/lib/
/project/src/
I don't want to package the art into the jar because I'd like the art to be easily exchangeable. If I add the art folder to the src folder then NB compiles fine, but the art resources end up in the jar.
Adding the art folder to the netbeans project libraries (Properties -> Libraries -> Add JAR/Folder) seemed not to work, because then I ended up with an error '...\project\art is a directory or can't be read. Not copying the libraries.' which in turn prevents even the real libraries folder from being copied.
Any ideas?
Best regards
Chris
2 Observations made, based on the comments from gpeche:
a) Rather specifying the additional resources folder in the "Run" tab than in the "Compile" tab of the project properties -> Libraries doesn't seem to make a lot of difference in Netbeans (I'm currently using 6.9.1). The output (and thus error) stays the same, that is nothing gets copied at all:
Created dir: C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\dist
C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\art is a directory or can't be read. Not copying the libraries.
Not copying the libraries.
Building jar: C:\Users\Chrisi\Desktop\vocabulary\VocabularyTrainer\dist\VocabularyTrainer.jar
Another interesting aspect is that in the help menu of the Libraries panel nothing is explicitly mentioned regarding folders as libraries. Could it be possible, that the button in Netbeans is falsely named, that is only real jar's are allowed?
b) Adding the resources folder to the Libraries list does have the impact though, to add another entry to the MANIFEST.MF. While - and that's the smaller issue - the classpath entry seems to be always expecting the resource folder to be a subfolder of the library folder (e.g. "lib/arts") the major problem is that there seems to be a slash missing.
As mentioned the NB generated entry in the MANIFEST.MF will look like this "lib/arts" (which does not work for me), while (manually set) "lib/arts/" does?!
The way I use resources from the folder is something like this:
URL resource = getClass().getResource("/gui/refresh.png");
ImageIcon tmp = new ImageIcon(resource);
Edit:
Based on Tushars comment and this posting I found the following solution to be an acceptable tradeoff between functionality and comfort.
I override the ANT target from the auto generated 'build-impl.xml' file which creates the Class-Path in the MANIFEST.MF file in the basic 'build.xml' file of the Netbeans project. The code which goes to the 'build.xml' file looks like this:
<property name="art.classpath" value="art/" />
<target name="-post-jar">
<mkdir dir="${dist.dir}/art"/>
<copy todir="${dist.dir}/art">
<fileset dir="${basedir}/art">
<!-- <exclude name="**/!source/**"/> if you want to exclude something... -->
</fileset>
</copy>
</target>
<target name="-init-macrodef-copylibs">
<macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
<element name="customize" optional="true"/>
<sequential>
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="jar.classpath">
<path path="${run.classpath.without.build.classes.dir}"/>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="lib/*"/>
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}"/>
<manifest>
<attribute name="Class-Path" value="${jar.classpath} ${art.classpath}"/>
<customize/>
</manifest>
</copylibs>
</sequential>
</macrodef>
</target>
The tradeoff is that for development in Netbeans I still have to add the resource folder (e.g. 'art') to the libraries list to make the project run in Netbeans. This will cause an additional entry in the MANIFEST.MF file ('lib/art') along with the effect that the libraries will not get automatically copied to the 'dist' folder, with the message
...\art is a directory or can't be read. Not copying the libraries.
Not copying the libraries.
This behavor is - afaik - intended (to force everything to be bundled up in a jar), even though there are discussions about it going on. To make a real distribution bundle I'd have to take away the resource folder(s) from the library list in NB and rebuild.
Ideas about a more streamlined setup without any tradeoffs are of course still welcome. :)
Adding resource folder to classpath:
When you Clean-&-Build a NetBeans Ant Based Project it creates a manifest.mf file in the root directory of the project. This file gets included in the JAR file also. Modify this file and add entry like follows:
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build
Class-Path: arts/
slash is important after arts in the class path.
Including the arts resource folder in the distribution
Either copy this folder in the dist folder after the build or add a ANT target to copy the required resources in the dist folder.
Add the target like as follows in the build.xml file:
<target name="-post-jar">
<mkdir dir="${dist.dir}/resources"/>
<copy todir="${dist.dir}/resources">
<fileset dir="${basedir}/resources" />
</copy>
</target>
Code to access such resources:
The code needed to access such resource files shall be as follows: (This will not work in design time but surely from the JAR file)
// pay attention to relative path
URL resource = ClassLoader.getSystemResource("gui/refresh.png");
ImageIcon tmp = new ImageIcon(resource);
NOTE: The files manifest.mf and build.xml located in the root directory of the project are accessible from the Files Panel in NetBeans IDE
Using NetBeans 8.0.2:
Right-click the project.
Select Properties.
Select Sources.
Click Add Folder for the Source Package Folders.
Select the the directory where the resources exist.
Click Open on the directory name.
Click OK to close the Project Properties dialog.
The resources are added to the project.
You'll see the directory added in your Navigation pane as well
In the other project, the resources are now available. For example, to read an image:
BufferedImage zero = ImageIO.read(OCR.class.getResourceAsStream("/0.bmp"));
In order to remove the lib/art from Class-Path and not get "is a directory or can't be read" need delete lib/art from path:
<pathconvert property="run.classpath.without.build.classes.dir">
<path path="${run.classpath}"/>
<map from="${build.classes.dir.resolved}" to=""/>
**<map from="${basedir}/art" to=""/> <!-- remove art from lib -->**
</pathconvert>