Compile selective part of my source tree using Ant
My situation is somehow interesting. I am trying to use Ant to make a jar file. However, I don't want every single java file to be compiled. My source code has strcuture something like this:
src
-Contact.Java
-Contact.hbm.xml
-AnotherClass.Java
So, what I want to have in my jar file is as follow:
myjar.jar
-com
--me
---Contact.Class
---Contact.hbm开发者_C百科.xml
I don't want AnotherClass.Class to be there.
Is it possible doint that with Ant ?
The best I come up with is like this:
<target name="condition-hibernate" description="check if there is a java and hbm file then call for compile-hibernate">
<condition property="condition">
<available file="**/*.hbm.xml" />
</condition>
<antcall target="condition-hibernate-part2"/>
</target>
<target name="condition-hibernate-part2" description="check if there is a java and hbm file then call for compile-hibernate">
<javac srcdir="${source.dir}" destdir="${hibernate.dir}">
</target>
I don't think that I can use Ant to solve my problem as I can't tell Ant what to compile and what not (I can using exclude and include) but I want to tell Ant compile only files that have an *.hbm.xml file next to them.
I don't know how to achieve this with Ant's built-in selectors.
However, if you cannot work around this in any other way you could implement a custom selector that checks if the .java
file has a corresponding .hbm.xml
file, e.g.
public class CorrespondingHbmSelector implements FileSelector {
public boolean isSelected(File basedir, final String filename, File f) {
Pattern p = Pattern.compile("^(.+).java$");
Matcher m = p.matcher(filename);
boolean matches = m.matches();
if (!matches) {
return false;
}
final String basename = m.group(1);
String[] foundFiles = basedir.list(new FilenameFilter() {
@Override
boolean accept(File dir, String name) {
return name.startsWith(basename) && name.endsWith(".hbm.xml");
}
});
return foundFiles.length > 0;
}
}
Use it in your build.xml
like an include
<typedef
name="correspondinghbmselector"
classname="CorrespondingHbmSelector"
classpath="${mydomain.classes}"/>
<javac srcdir="${source.dir}" ...>
<correspondinghbmselector/>
</javac>
This is just the basic idea. (I didn't test the code.)
The better way would be to avoid such complex dependencies in your build.
I think you should consider separating the different types of classes into separate projects. Apart from making your packaging process simpler, there are other benefits too: decoupling, enforcing one-way compile-time dependencies etc.
Assuming Contact.java is not depending on AnotherClass.java, it is doable. Use selector sub-elements (linked in the Ant documentation under "concepts and types") in your javac
tag for this.
Here is an example:
<javac srcdir="${source.dir}" destdir="${hibernate.dir}">
<filename name="Contact.Java" />
<javac>
Of course, instead of a <filename>
selector you can also directly use the patternset
subelements and attributes:
<javac srcdir="${source.dir}" destdir="${hibernate.dir}">
<include name="Contact.Java" />
<javac>
or
<javac srcdir="${source.dir}" destdir="${hibernate.dir}"
includea="Contact.Java" />
By the way, the naming convention for Java's file extensions is using only lower case letters, i.e. .java
, not .Java
(and .class
). If you are on a case-insensitive file system like most Windows file systems, this might not matter, but you should still do it, to avoid surprises later.)
精彩评论