Скомпилируйте селективную часть моего исходного дерева, используя Ant - PullRequest
0 голосов
/ 13 августа 2011

Моя ситуация как-то интересна. Я пытаюсь использовать Ant для создания файла jar. Тем не менее, я не хочу, чтобы каждый отдельный файл Java был скомпилирован. Мой исходный код выглядит примерно так:

src
-Contact.Java
-Contact.hbm.xml
-AnotherClass.Java

Итак, что я хочу иметь в своем jar-файле:

myjar.jar
-com
--me
---Contact.Class
---Contact.hbm.xml

Я не хочу, чтобы там был AnotherClass.Class.

Возможно ли это сделать с помощью Ant?

Лучшее, что я придумаю, таково:

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

Я не думаю, что смогу использовать Ant для решения своей проблемы, так как не могу сказать Ant, что компилировать, а что нет (я могу использовать исключение и включение), но я хочу сказать, что Ant компилирует только файлы, которые имеют * .hbm.xml файл рядом с ними.

Ответы [ 3 ]

1 голос
/ 13 августа 2011

Я не знаю, как этого добиться с помощью встроенных в селекторов Ant .

Однако, если вы не можете обойти это каким-либо другим способом, вы можете реализовать пользовательский селектор , который проверяет, имеет ли файл .java соответствующий файл .hbm.xml, например,

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;
  }
}

Используйте его в вашем build.xml как include

<typedef
  name="correspondinghbmselector"
  classname="CorrespondingHbmSelector"
  classpath="${mydomain.classes}"/>

<javac srcdir="${source.dir}" ...>
  <correspondinghbmselector/>
</javac>

Это всего лишь основная идея.(Я не тестировал код.)

Лучшим способом было бы избежать таких сложных зависимостей в вашей сборке.

0 голосов
/ 13 августа 2011

Предполагая, что Contact.java не зависит от AnotherClass.java, это выполнимо.Для этого используйте подэлементы селектора (связанные в документации Ant в разделе "Концепции и типы") в вашем теге javac.

Вот пример:

    <javac srcdir="${source.dir}" destdir="${hibernate.dir}">
      <filename name="Contact.Java" />
    <javac>

Конечно, вместо селектора <filename> вы также можете напрямую использовать patternset субэлементы и атрибуты:

    <javac srcdir="${source.dir}" destdir="${hibernate.dir}">
      <include name="Contact.Java" />
    <javac>

или

    <javac srcdir="${source.dir}" destdir="${hibernate.dir}"
           includea="Contact.Java" />

Кстати,Соглашение об именах для расширений файлов Java использует только строчные буквы, то есть .java, а не .Java.class).Если вы используете нечувствительную к регистру файловую систему, как и большинство файловых систем Windows, это может не иметь значения, но вы все равно должны это делать, чтобы избежать неожиданностей позже.)

0 голосов
/ 13 августа 2011

Я думаю, вам следует рассмотреть возможность разделения разных типов классов на отдельные проекты.Помимо упрощения процесса упаковки, есть и другие преимущества: разделение, применение односторонних зависимостей времени компиляции и т. Д.

...