Java 如何以编程方式为邮件任务添加Ant库依赖项

Java 如何以编程方式为邮件任务添加Ant库依赖项,java,eclipse,ant,jakarta-mail,Java,Eclipse,Ant,Jakarta Mail,我的任务是为我们的Ant构建脚本创建自动通知。这样,当有人推出部署时,我们的团队可以自动收到一封关于它的电子邮件 显而易见的选择是使用Ant预定义的: <target name="notify" description="notify team"> <mail subject="latest deployment"> <from address="me@gmail.com" /> <to address="jimm

我的任务是为我们的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>
这是因为Ant的邮件任务依赖于和库,而这些库显然不包括在其发行版中。我不清楚为什么Ant会定义一个依赖于库但不包括该库的任务

此帖子已讨论此问题:。根据答案,似乎有两种解决方案

第一种方法是手动将这些库依赖项放在ant类路径上。这可以使用
-lib
命令行参数来完成,或者在eclipse中可以使用
Window>Preferences>Ant>Runtime>Global Entries
,然后添加
mail.jar
activation.jar
(我很确定这与
-lib
是一样的,如果我错了请纠正我)。但这种解决方案对我们的团队来说是不可取的,因为这意味着我们每个人都必须手动执行这些步骤。我正在寻找一种简单提交通知代码的方法,它应该可以在svn更新之后在另一个eclipse安装上运行

链接帖子中的另一个解决方案提到了一种以编程方式执行上述操作的方法,即从自身调用Ant:

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

问题是Ant命令行工具显然只包含在完整安装中,而不是eclipse发行版中。因此,如果没有任何想要使用邮件任务的人的一些手动操作,就无法使其工作

<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 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文件有一个安装jars目标,可用于安装邮件任务使用的缺少的ANT JAR

<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任务允许您指定类路径引用。邮件任务不存在。尝试研究此问题会使我找到以下邮件列表线程:


这个解决方案很复杂,不值得付出努力。我建议你带着不便生活。。。(install jars目标只需运行一次)

使用
taskdef
命令,您可以动态加载新任务并指定从何处加载任务的类路径。我成功地使用它从不在ant类路径上的外部库加载新任务。当任务已经存在时,它是否也起作用,我不知道

我可能会首先尝试用一个新名称重新定义邮件任务:

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

也许您需要在这里的类路径中包含原始的ant类路径,以便可以找到邮件任务的类


如果这不起作用,也许您可以将邮件任务的源代码,重命名该类,将其与
mail.jar
activation.jar
中的类绑定到您自己的jar中,并从jar加载该任务。这应该与ant未附带的任何任务一样有效。

您可以将这些JAR作为外部JAR放到ant运行配置的类路径中(这是我的ftp示例):

并将此运行配置保存到项目中(选项卡:Common-->共享文件,我通常使用类似于
resources/eclipse
的内容)并将其提交给svn

  • 它将为所有从svn签出此项目的开发人员提供
  • 你也必须在那个项目中交付罐子。这样他们就可以随时使用
  • 每个人都可以从外部工具菜单轻松运行它
  • 当然,你可以这样做。

    以我的例子,我得到了一个有效的解决方案,在测试失败时发送电子邮件

    你需要下载, 和javamail中的mail.jar,并将它们放在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>
    
    
    
    使用Ant 1.8.2和(作者)提到的解决方案,我需要将classloadertask的loader属性更改为:

    loader="thread"
    
    进入:


    否则类加载器找不到activation.jarmail.jar中的类。

    如何通过构建文件以编程方式完成此操作,以便在对更改(和jar)执行svn签出后在eclipse中,它不需要任何手动设置就可以工作?在看到真正实现自动化是多么难以克服之后,我的团队和我决定放弃并吞下每次eclipse安装手动设置Ant的药丸。你的安装目标很接近,+1表示这一点和链接-不幸的是,Ant需要重新启动,但似乎真的没有办法不陷入类加载器混乱。@PaulBellora还有一个想法,你可以检查文件是否存在,如果不存在,只运行install JAR。这将在您的工作流程中透明地集成这些步骤。@我曾想过检查类(而不是文件)的存在,但这并不能避免必须运行ANT两次。。。。这就是我放弃的原因:-(这里的根本原因是一个不支持classpathref属性的旧ANT任务。相比之下,破解ANT类加载器似乎太笨拙了,我们也拒绝了这个选项(使用标准ANT)@能不能请你再详细说明一下为什么这不起作用?我可能是太仓促了。我把你的答案误读成了某种东西
    loader="thread"
    
    loader="project"