Как программно добавить зависимости библиотеки Ant для почтовой задачи - PullRequest
8 голосов
/ 07 февраля 2012

Мне было поручено создавать автоматические уведомления для наших скриптов сборки Ant. Это связано с тем, что когда кто-то запускает развертывание, наша команда может автоматически получать по электронной почте сообщение об этом.

Очевидным выбором было использовать Почтовое задание Ant , которое предопределено с помощью Ant:

<target name="notify" description="notify team">
    <mail subject="latest deployment">
        <from address="me@gmail.com" />
        <to address="jimmy@yahoo.com" />
        <message>A new build has been pushed out to prod</message>
    </mail>
</target>

Однако это приводит к следующему исключению времени выполнения:

java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage

Это связано с тем, что почтовая задача Ant зависит от JavaMail и JavaBeans Activation Framework , библиотек, которые, по-видимому, не включены в ее дистрибутив. Почему Ant будет определять задачу, которая зависит от библиотеки, но не включает эту библиотеку, мне неясно.

Эта проблема уже обсуждалась в этом сообщении: Задача ant mail с использованием почты и jar активации во внешнем расположении . Основываясь на ответах, кажется, есть два решения.

Во-первых, вручную поместить эти зависимости библиотеки в путь к муравьям. Это можно сделать с помощью аргумента командной строки -lib или в Eclipse можно использовать Window > Preferences > Ant > Runtime > Global Entries, а затем добавить mail.jar и activation.jar (я почти уверен, что это то же самое, что и -lib, поправьте меня если я ошибаюсь). Но это решение нежелательно для нашей команды, потому что это означало бы, что каждый из нас должен был бы выполнить эти шаги вручную. Я ищу способ просто зафиксировать мой код уведомления, и он должен работать при другой установке Eclipse после обновления SVN.

В другом решении в связанном посте упоминается способ сделать вышеперечисленное программно, вызывая Ant из себя:

<exec executable="ant">
    <arg value="-lib"/>
    <arg value="PATH_TO_MY_LIB"/>
    <arg value="target"/>
</exec>

Проблема в том, что инструмент командной строки Ant, по-видимому, включается только в полную установку, а не в дистрибутив Eclipse. Итак, снова нет способа заставить его работать без каких-либо ручных действий со стороны любого, кто хочет использовать почтовое задание.

Можно ли как-нибудь автоматизировать это, не добавляя еще один раздражающий шаг в настройку проекта? Я действительно не понимаю, почему это так трудно достичь - похоже, если бы почтовое задание не было , предопределенное Ant, это было бы проще. Надеюсь, я что-то упустил.

Ответы [ 5 ]

5 голосов
/ 01 декабря 2012

С примером из этой почтовой ветки Я получил рабочее решение, которое отправляет электронную почту, когда тесты не пройдены.

Вам необходимо скачать ant-classloadertask.jar , и mail.jar из javamail и поместите их в test.libs.dir.

<property name="test.libs.dir" location="${basedir}/lib/unit-test"/>
<property name="test.results.dir" location="${basedir}/test-results/"/>

<path id="project.classpath.tests">
    <pathelement location="${build}"/> 
    <path refid="project.lib.path"/>
</path>

<target name="unit-tests" depends="">
    <mkdir dir="${test.results.dir}"/>
    <junit fork="false" showoutput="yes" includeantruntime="false"
        errorproperty="test.error" failureproperty="test.error" 
        haltonerror="false" haltonfailure="false">
        <classpath refid="project.classpath.tests"/>
        <formatter type="plain" usefile="true" />
        <batchtest fork="no" todir="${test.results.dir}">
            <fileset dir="${build}/test/">
                <include name="package/dir/path/to/tests/TestFile.java"/>
            </fileset>
        </batchtest>
    </junit>
    <antcall target="sendMail"/> 
</target>

<path id="mail.path">
    <pathelement location="${test.libs.dir}/mail.jar"/>
</path>

<!-- http://enitsys.sourceforge.net/ant-classloadertask/ -->
<taskdef name="classloadertask"
    classname="org.apache.tools.ant.taskdefs.ClassloaderTask" 
    classpath="${test.libs.dir}/ant-classloadertask.jar"/>
    <classloadertask classpathRef="mail.path" loader="thread"/> 

<target name="sendMail" if="test.error">
    <mail mailhost="smtp.gmail.com"
        mailport="587"
        user=""
        password=""
        ssl="yes"
        failonerror="true"
        from=""
        tolist=""
        subject="Unit tests have failed"/>
</target>
5 голосов
/ 08 февраля 2012

Почта - одна из дополнительных задач в ANT.Для установки этих дополнительных библиотек в ANT 1.7 добавлен скрипт fetch.xml, который вызывается следующим образом:

ant -f $ANT_HOME/fetch.xml -Ddest=user -Dm2.url=http://repo1.maven.org/maven2 

В Windows вы можете попробовать:

ant -f %ANT_HOME%/fetch.xml -Ddest=user -Dm2.url=http://repo1.maven.org/maven2 

Подробное описание см. В ANT Ручная документация .


Обновление

В следующем файле ANT есть цель install-jars , которую можно использовать для установки отсутствующего ANTjar-файлы, используемые почтовой задачей.

<project name="demo" default="notify">

    <target name="install-jars" description="Install ANT optional jars">
        <mkdir dir="${user.home}/.ant/lib"/>
        <get dest="${user.home}/.ant/lib/mail.jar"       src="http://search.maven.org/remotecontent?filepath=javax/mail/mail/1.4.4/mail-1.4.4.jar"/>
        <get dest="${user.home}/.ant/lib/activation.jar" src="http://search.maven.org/remotecontent?filepath=javax/activation/activation/1.1/activation-1.1.jar"/>
    </target>

    <target name="notify" description="notify team">
        <mail subject="latest deployment">
            <from address="me@gmail.com" />
            <to address="jimmy@yahoo.com" />
            <message>A new build has been pushed out to prod</message>
        </mail>
    </target>

</project>

Я обнаружил, что почтовая задача ANT загружает свои зависимые классы из системного пути ANT-класса.Это означает, что сборка должна выполняться в два этапа:

$ ant install-jars
$ ant

Большинство задач ANT позволяют указывать ссылку на путь к классу.Почта задача не выполняет.Попытка исследовать эту проблему привела меня к следующей ветке списка рассылки:

Решение запутанное и не стоит усилий.Я бы порекомендовал жить с неудобствами ... (Цель install-jars нужно запускать только один раз)

1 голос
/ 27 мая 2013

С Ant 1.8.2 и ant-classloadertask.jar упомянутое решение выше ( bro ) Мне нужно было изменить loader атрибут classloadertask из:

loader="thread"

в:

loader="project"

в противном случае классы в активации.jar и mail.jar не найдены загрузчиком классов.

1 голос
/ 08 февраля 2012

Вы можете поместить эти jar как внешние jar в classpath конфигурации ant run (это мой пример ftp):

enter image description here

и сохраните эту конфигурацию запуска в проекте (Tab: Common -> Shared File, для этого я обычно беру что-то вроде resources/eclipse) и передайте его в svn.

  1. это будет доступно для всех разработчиков, которые проверят этот проект из svn
  2. Вы должны доставить банки и в этом проекте. Так что они всегда будут доступны
  3. Каждый может легко запустить его из меню внешних инструментов

Конечно, вы могли бы написать собственное почтовое задание , чтобы позаботиться об этом.

1 голос
/ 08 февраля 2012

С помощью команды taskdef вы можете динамически загружать новые задачи и указывать путь к классам, откуда они загружаются. Я успешно использую это для загрузки новых задач из внешней библиотеки, которая не находится на пути класса муравья. Работает ли это и тогда, когда задача уже существует, я не знаю.

Вероятно, я бы начал с попытки переопределить почтовое задание с новым именем:

<taskdef name="mymail" classname="class.of.mail.task" classpath="mail.jar;activation.jar">

Возможно, вам нужно включить исходный путь к муравейному классу в путь к классу, чтобы можно было найти класс почтовой задачи.

Если это не сработает, возможно, вы можете взять исходный код почтового задания, переименовать класс, связать его вместе с классами mail.jar и activation.jar в свой собственный jar и загрузить это задание из JAR. Это должно работать так же, как и с любой задачей, не поставляемой с муравьем.

...