Say I have my sources in my src/ tree (and possibly in my test/ tree). Say I would like to compile only part of that tree. The reasons why I might want to do that are various. Just as an example, I might want to create the smallest possible jar (without including certain classes), or I might want the fastest compile time for what I am compiling. I absolutely want to compile all the dependencies, though!
This can be easily achieved from the command line with:
javac -d build/ -cp whatever -sourcepath src src/path/to/MyClass.java
Now, how can you do that with ant? The javac ant task compiles everything:
The source and destination directory will be recursively scanned for Java source files to compile.
One can use the excludes
and includes
parameters, but they are problematic for this purpose. In fact, it seems that one has to explicitly setup all the includes
(not automatic dependency lookup), and even worst that excludes has priority on includes:
When both inclusion and exclusion are used, only files/directories that match at least one of the include patterns and don't match any of the exclude patterns are used.
Thus, you cannot use
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath"
excludes="**/*.java" includes="src/path/to/MyClass.java" />
Because it will not compile anything :-(
Is there any way of achieving that simple command line javac
with ant?
EDITED: Thank you for your answer, Sadie, I'm accepting it, because it does work in the way I was wondering in this question. But I have a couple of comments (too long to be in the comment field of your answer):
1) I did read the documentation (see links above), but it's unclear that with just includes
you are actually also excluding everything else
2) When you just includes
ant logs something like
[javac] Compiling 1 source file to /my/path/to/build
even if the dependencies make it compiling (much) more than just one source file.
Why are you excluding as well as including? If you have at least one include, then files are only compiled if they're explicitly included. So this should work:
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath"
includes="src/path/to/MyClass.java" />
Or more flexibly:
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath">
<include name="src/path/to/MyClass.java"/>
<include name="src/path/to/AnotherClass.java"/>
</javac>
To include only certain packages or classes in a jar, use a fileset attribute
<jar jarfile="${outlib}/something.jar">
<fileset dir="${build.dir}">
<include name='src/path/to/classes' />
</fileset>
</jar>
Again, you can use multiple includes to combine separate packages. Experiment with includes and read the documentation and you're sure to find the answer you need.
Old question, but I was struggling with the same problem and found a a more elegant solution. So here it is, for future reference:
According to the ant docs the <javac>
element is an implicit <fileset>
and as such can take Selectors like <filename name="**/MyClass.java"/>
, so this would only compile MyClass.java:
<javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="classpath">
<filename name="**/path/to/MyClass.java"/>
</javac>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With