开发者

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.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜