2011-08-12 2 views
0

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

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

Итак, что я хочу, чтобы в моем файле фляга выглядит следующим образом:

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 для компиляции, а что нет (я можно использовать exclude и include), но я хочу сказать, что Ant компилирует только файлы с файлом * .hbm.xml рядом с ними.

+1

Возможно, вам стоит немного перефразировать ваш вопрос. Скажем, что вам нужны только классы Java, которые имеют соответствующий файл .hbm.xml. – migu

ответ

1

Я не знаю, как это сделать с помощью встроенного в Ant's selectors.

Однако, если вы не можете обойти это каким-либо другим способом, вы можете реализовать custom selector, который проверяет, имеет ли файл .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

Ах, я не понял из вопроса, что он хочет только тех, у кого есть соответствующий файл .hbm.xml. Но имеет смысл. –

+0

Я считаю, что это было бы лучшим решением, если я не хочу трогать сложность кода. – sheidaei

0

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

+0

Я окончательно отделил файлы, так что работал для меня. – sheidaei

+0

Приятно слышать :) –

0

Предполагая, что Contact.java не зависит от AnotherClass.java, это выполнимо. Используйте selector sub-elements (связанный в документации 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

Я предположил, что для компиляции существует произвольное количество .java-файлов, которые неизвестны во время сборки. Или, по крайней мере, shahin не захочет перечислить все из них в файле сборки. – migu

+0

Было бы более одного класса, такого как Contact.java. Прошу прощения, если я не объясню это полностью. Таким образом, единственным критерием для проверки будет совместный существующий класс с разным расширением, но с тем же именем. Вы правы насчет заглавных букв, это была моя ошибка, набрав структуру. Это все в порядке. – sheidaei