Netbeans - adding resource files to jar file with Ant - java

I want add some resource files (non-code text-based files) to the jar file in a Java project using Netbeans 6.9, I'd expect using Ant. I had thought that this would be reasonably simple...but after quite a bit of searching I can't find how to do it..! Any pointers in the right direction?

The answer I think I was looking for is as follows:
In the build.xml file (as per trashgod's answer) you can use the hooks already in the ant build script to add the following:
<target name="-post-jar">
<echo>Adding files to jar...</echo>
<jar destfile="dist/jarFileName.jar" update="true">
<fileset dir="${basedir}">
<include name="files/*"/>
</fileset>
</jar>
</target>
This adds the files directory and any files under it directly to the jar file.

If you choose File > Project Properties > Build > Packaging, you'll see a dialog that lets you exclude artifacts from the build; everything else is the source tree is included. The source of TreeIconDemo is a concrete example that inlcudes html files.
For more advanced tasks, examine the default build.xml generated for a freshly created project; it identifies various hooks into the predefined tasks. For example,
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
Addendum: As an example, this target overrides -post-compile to print some statistics.
<project name="TreeIconDemo" default="default" basedir=".">
<import file="nbproject/build-impl.xml"/>
<target name="-post-compile">
<echo>build.dir: ${build.dir}</echo>
<length mode="all" property="build.size">
<fileset dir="${build.dir}">
<include name="**/*"/>
</fileset>
</length>
<echo>build.size: ${build.size}</echo>
</target>
</project>
Output:
$ ant compile
Buildfile: build.xml
...
-post-compile:
[echo] build.dir: build
[echo] build.size: 11992
compile:
BUILD SUCCESSFUL

Related

include text file in dist folder

Is there any way that in the dist folder (when doing clean and built) I include a text file necessary for the program to work in netbeans? It's because I'm forced to copy it by hand every time I generate the dist folder when building. I want the text file to be added to the root of the project. I am using "apache netbeans ide 14" and using ant. And this is the code of the build.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="pesca1.6" default="default" basedir=".">
<description>Builds, tests, and runs the project pesca1.6.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="pesca1.6-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>
I need the text file, necessary for the program to work, to be automatically added to the root of the dist folder when I build the project.
Text file in dist folder looks very strange, IMHO.
I would recommend you to check nbproject folder, especially build-impl.xml file. This file describes how exactly build process is going.

I need to fail the build when a package imports from another package within the same project. How can I do so cleanly?

For a variety of reasons (regardless of whether or not this is a wise idea) we have a project with several packages (say one, two, three) that are similar in structure. There is one additional common package.
I want the build to fail when something in each of those packages imports something that isn't in common, e.g. because you accidentally accepted the wrong import completion, or because Eclipse silently brought over the wrong imports while copy-pasting bug fixes from one into two.
What works is copying all the source files, except for each package, over to a temporary folder and attempting to build the result:
<target name="enforce-no-cross-imports">
<phony-build without="one"/>
<phony-build without="two"/>
<phony-build without="three"/>
</target>
<macrodef name="phony-build">
<attribute name="without" />
<sequential>
<echo message="Checking there are no cross imports to the #{without} package." />
<mkdir dir="${java.io.tmpdir}/my-awesome-project/phony-build-#{without}/src" />
<mkdir dir="${java.io.tmpdir}/my-awesome-project/phony-build-#{without}/bin" />
<copy todir="${java.io.tmpdir}/my-awesome-project/phony-build-#{without}/src">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
<exclude name="**/#{without}/"/>
</fileset>
</copy>
<javac srcdir="${java.io.tmpdir}/my-awesome-project/phony-build-#{without}/src"
destdir="${java.io.tmpdir}/my-awesome-project/phony-build-#{without}/bin"
classpathref="classpath" encoding="UTF-8" nowarn="on"/>
<delete dir="${java.io.tmpdir}/my-awesome-project" />
</sequential>
</macrodef>
However, when the build DOES break, the error obviously occurs inside ${java.io.tmpdir}.
enforce-no-cross-imports:
[echo] Checking there are no cross imports to the one package.
[mkdir] Created dir: C:\Users\me\AppData\Local\Temp\my-awesome-project\phony-build-one\src
[mkdir] Created dir: C:\Users\me\AppData\Local\Temp\my-awesome-project\phony-build-one\bin
[copy] Copying 47 files to C:\Users\me\AppData\Local\Temp\my-awesome-project\phony-build-one\src
[javac] Compiling 47 source files to C:\Users\me\AppData\Local\Temp\my-awesome-project\phony-build-one\bin
[javac] C:\Users\me\AppData\Local\Temp\my-awesome-project\phony-build-one\src\my\awesome\project\two\very\long\path\SomeController.java:43: package my.awesome.project.one.very.long.path.SomeConstantsClass does not exist
[javac] public static final String TEST = my.awesome.project.one.very.long.path.SomeConstantsClass.TEST;
As a result I can't click on the file name to jump directly to the issue. This adds way too much friction to the compilation process: it's bad enough that I'm effectively tripling the project build times.
What I thought I could do instead is not copy the files over and use the excludes attribute on the javac task instead:
excludes: Comma- or space-separated list of files (may be specified using wildcard patterns) that must be excluded; no files (except default excludes) are excluded when omitted.
...except this does not cause the build to break. What happens is that javac will not compile the other packages, but it will still look at them for confirmation. Turning on verbose shows this log line:
[javac] [checking my.awesome.project.one.very.long.path.SomeConstantsClass]
includeDestClasses seemed like another helpful flag, but setting it to false didn't help. <compilerarg value="-implicit:none"/> also was not helpful.
How can I tell javac that it really positively does need to exclude those files from the build, even if they are right there?
Alternatively, how can I take the output of javac and run find-replace on it so that the console output shows the correct path instead?
You could use the compilewithwalls or verifydesign tasks of ant-contrib, but the safest way to enforce separation like this is to isolate the modules into separate source directories and compile them independently. You'd first build the common module, then build each of the other modules with the compiled classes of "common" on their classpaths but not the classes of any of the other modules. This is the default approach when you're building with a higher level build tool like Maven. If you have a directory structure like this:
build.xml
lib
library JAR files
common
src
classes
one
src
classes
two
src
classes
then you could structure the build as
<macrodef name="compile-module">
<attribute name="module" />
<element name="depends" implicit="true" optional="true"/>
<sequential>
<javac srcDir="#{module}/src" destDir="#{module}/classes"
encoding="UTF-8" nowarn="on">
<classpath>
<path refid="classpath" />
<depends/>
</classpath>
</javac>
</sequential>
</macrodef>
<compile-module name="common" />
<compile-module name="one">
<pathelement location="common/classes" />
</compile-module>
<compile-module name="two">
<pathelement location="common/classes" />
</compile-module>
<compile-module name="three">
<pathelement location="common/classes" />
</compile-module>
You mention Eclipse in the question, so you'd need to do something similar there. Eclipse allows the root of one project to be inside another, so you could create one main Eclipse project "myapp-common" pointed at your project root with just common/src as its source directory (and common/classes as the corresponding output directory), then create separate "myapp-one", "myapp-two" etc. projects rooted at the one, two, etc. folders, each depending on the "myapp-common" project. That way you would never get Eclipse offering the "wrong" auto-completion, as project one simply cannot see project two or vice versa.

Java: How can I compile an entire directory structure of code in command prompt? [duplicate]

This question already has answers here:
javac option to compile all java files under a given directory recursively
(10 answers)
Closed 8 years ago.
I'm using Eclipse & Tomcat7 in window7 platform, I have configured project in eclipse also. Usually we run the single java file using CMD.
But I want to compile and run the entire java code through command prompt.
I've a many structures in single src folder like E:\proj\src\com\mycode.Inside mycode folder there are 7 sub-folder are available & each sub-folder have many .java files & inner-sub-folders.
For Example:
E:\proj\src\com\mycode\dto\mail.java,E:\proj\src\com\mycode\dto\sms.java
E:\proj\src\com\mycode\dto\security\securityFile.java
The above same pattern other folders have java files.so I need to compile & run entire java files including sub-folders & inner-sub-folders USING COMMAND PROMPT.
thanks in advance,
I'll make some (hopefully reasonably safe) assumptions about how your code is structured:
you have a main program (I call it com.mycode.dto.Main below),
it has compile-time dependencies on the other files (you're not using reflection or whatever),
your source files match the package structure (com.foo.Bar is in E:\proj\src\com\foo\Bar.java).
In that case you can do:
javac -d <destination> -sourcepath E:\proj\src E:\proj\src\com\mycode\dto\Main.java
and then the compiler will traverse the file dependencies automatically and output the class files to destination.
If you have sources in multiple hierarchical directory, you may use ant.
create a build.xml file in the root of your project directory.
<project name="MyProject" default="dist" basedir=".">
<description>
simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
<!-- Create the time stamp -->
<tstamp/>
<!-- Create the build directory structure used by compile -->
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init"
description="compile the source " >
<!-- Compile the java code from ${src} into ${build} -->
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile"
description="generate the distribution" >
<!-- Create the distribution directory -->
<mkdir dir="${dist}/lib"/>
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
</project>
Install ant on your machine, be sure to have its bin directory in your path, then you can just run
ant -f build.xml
Of course this is just a starting point (ant offers several interesting options and let you finetune all the aspects of your build/packaging).
the sample build.xml file was taken from here
Try using wildcard:
javac *.java
You could use various parameters as per need basis that comes in handy with javac:
Usage: javac <options> <source files>
where possible options include:
-g Generate all debugging info
-g:none Generate no debugging info
-g:{lines,vars,source} Generate only some debugging info
-nowarn Generate no warnings
-verbose Output messages about what the compiler is doing
-deprecation Output source locations where deprecated APIs are used
-classpath <path> Specify where to find user class files and annotation processors
-cp <path> Specify where to find user class files and annotation processors
-sourcepath <path> Specify where to find input source files
-bootclasspath <path> Override location of bootstrap class files
-extdirs <dirs> Override location of installed extensions
-endorseddirs <dirs> Override location of endorsed standards path
-proc:{none,only} Control whether annotation processing and/or compilation is done.
-processor <class1>[,<class2>,<class3>...]Names of the annotation processors to run; bypasses default discovery process
-processorpath <path> Specify where to find annotation processors
-d <directory> Specify where to place generated class files
-s <directory> Specify where to place generated source files
-implicit:{none,class} Specify whether or not to generate class files for implicitly referenced files
-encoding <encoding> Specify character encoding used by source files
-source <release> Provide source compatibility with specified release
-target <release> Generate class files for specific VM version
-version Version information
-help Print a synopsis of standard options
-Akey[=value] Options to pass to annotation processors
-X Print a synopsis of nonstandard options
-J<flag> Pass <flag> directly to the runtime system

Apache Ant {Compile javac srcdir} does not exist

I am new to apache ant and I am currently working on an apache Ant project. I Just started out, imported the project into workspace and tried to run the build.xml. I added all the libraries that come with the original project to the build path. I am having the following problem. Please someone else wrote the code and I am supposed to improve it. The directories this is all about exist in the project directory.
BUILD FAILED
C:\workspace\MyApp\build.xml:83: srcdir "C:\workspace\MyApp\${compile.javac.srcdir}" does not exist!
The error code is referencing the following part of the build.xml file
<target name="compile.default" depends="init">
<javac fork="yes" srcdir="${compile.javac.srcdir}" destdir="${compile.javac.destdir}" includes="${compile.javac.include}" excludes="${compile.javac.exclude}" classpath="${compile.javac.classpath}" debug="${compile.javac.debug}" optimize="${compile.javac.optimize}" deprecation="${compile.javac.deprecation}" verbose="${compile.javac.verbose}">
</javac>
<copy todir="${compile.javac.destdir}">
<fileset dir="${compile.javac.srcdir}" includes="${compile.copy.include}" excludes="${compile.copy.exclude}"/>
</copy>
</target>
<target name="compile" depends="init,compile.default" description="Compile all java source">
</target>
<!--+++++++++++++++-->
<!-- lib target(s) -->
<!--+++++++++++++++-->
<target name="lib.default" depends="init,compile">
<xmlbean schema="config/schemas/validate/1.0/validate.xsd" destfile="lib/glx-beans.jar" classpath="lib/xbean.jar:lib/jsr173_1.0_api.jar" />
<jar jarfile="${lib.filename}">
<fileset dir="${lib.srcdir}" excludes="${lib.exclude}" />
</jar>
</target>
<target name="lib" depends="init,compile,lib.default" description="Create all Project Libraries">
</target>
Would you please tell me what I am missing?
The ${compile.javac.srcdir} isn't defined. There are a few possibilities:
This is defined not in the build.xml, but in some sort of properties file. See if you have something like <property file="..."/> in your build script. My recommendation is to have all properties defined in the build.xml file, and use a properties file to override those settings. This way, the only build file that a developer needs in the build.xml file and doesn't have to worry about setting up a separate build.porperties file.
This is defined in the build.xml file under a particular task, but you forgot to say that your target where you use thisis dependent upon this task.
One of the things you can do is use the -d parameter when running Ant. I run the following command when running Ant with the -d parameter:
$ and -d 2>&1 | tee ant.out
I can then look at ant.out and see if somehow I didn't define that particular property. Maybe I had the wrong capitalization or misspelled the property name. For example, it's very likely I'll define the property as copmile.javac.srcdir because I don't know how to spell. Looking at the -d output can quickly point these types of errors out.
By the way, you shouldn't have all of your tasks dependent upon init since they're dependent upon compile.default anyway:
<target name="compile.default" depends="init">
....
</target>
<target name="compile" depends="compile.default">
....
</target>
<target name="lib" depends="compile,lib.default">
....
</target>
If I run the target lib, it will see compile is dependent upon compile.default which is dependent upon init. Thus, your build will run init, then compile.default, then compile, then 'lib.defaultand finallylib`.
If the init task is just setting up properties, you can do that outside of any task. Then, these properties will be setup before any task is executed. This way, they're not forgotten. If your init is also creating directories, you may want to move those <mkdir/> tasks in front of the task where that directory is used. For example, you may want to make the destdir uses in javac before the <javac/> task.
I find assigning default properties outside of any task, and creating directories before they are needed to simplify the build.xml. Plus, you're not creating a whole flock of unused directories if the user is merely compiling and not packaging the jar/war/etc.

copy a file in ant based on condition

I have to copy a file if a property is set in ant target, but I always get an error for this code:
<condition property="component.is.x">
<equals arg1="${COMPONENT_ID}" arg2="x" />
</condition>
<target name="copyschemaparamsfile" if="sql.file.present" >
<if>
<equals arg1="${component.is.x}" arg2="true" />
<then>
<copy file="${in.root}/schema/${COMPONENT_ID}-schema.sql"
tofile="${tmp.dir}/${COMPONENT_ID}/x/schema/schema.sql"
failonerror="false" />
</then>
<else>
<copy file="${inf.root}/schema/${COMPONENT_ID}-schema.sql"
tofile="${tmp.dir}/${COMPONENT_ID}/${COMPONENT_ID}/schema/schema.sql" failonerror="false" />
</else>
</if>
</target>
Error is:
Ant could not find the task or a class this task relies upon.
This is common and has a number of causes; the usual
solutions are to read the manual pages then download and
install needed JAR files, or fix the build file:
- You have misspelt 'if'.
Fix: check your spelling.
- The task needs an external JAR file to execute
and this is not found at the right place in the classpath.
Fix: check the documentation for dependencies.
Fix: declare the task.
- The task is an Ant optional task and the JAR file and/or libraries
implementing the functionality were not found at the time you
yourself built your installation of Ant from the Ant sources.
Fix: Look in the ANT_HOME/lib for the 'ant-' JAR corresponding to the
task and make sure it contains more than merely a META-INF/MANIFEST.MF.
If all it contains is the manifest, then rebuild Ant with the needed
libraries present in ${ant.home}/lib/optional/ , or alternatively,
download a pre-built release version from apache.org
- The build file was written for a later version of Ant
Fix: upgrade to at least the latest release version of Ant
- The task is not an Ant core or optional task
and needs to be declared using <taskdef>.
- You are attempting to use a task defined using
<presetdef> or <macrodef> but have spelt wrong or not
defined it at the point of use
Remember that for JAR files to be visible to Ant tasks implemented
in ANT_HOME/lib, the files must be in the same directory or on the
classpath
I am always getting above error when I execute. Can someone please suggest how to check for a parameter and copy from one directory to other within an ant target?
Ant <if/> is part of Ant-Contrib. To use, follow the directions on the Ant-Contrib Tasks installation page:
(1) Copy ant-contrib-0.3.jar to the lib directory of your Ant
installation. If you want to use one of the tasks in your own project,
add the lines
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
to your build file.
(2) Keep ant-contrib-0.3.jar in a separate location. You now have to
tell Ant explicitly where to find it (say in /usr/share/java/lib):
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="/usr/share/java/lib/ant-contrib-0.3.jar"/>
</classpath>
</taskdef>

Categories

Resources