我的任务是为Ant构建脚本创建自动通知。这样,当有人推出部署时,我们的团队可以自动收到有关它的电子邮件。
显而易见的选择是使用Ant's mail task,它是使用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 task using mail and activation jar in external location。根据答案,似乎有两种解决方案。
第一种是手动将这些库依赖项放在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发行版。因此,如果没有任何人想要使用邮件任务的手动操作,就无法使其工作。
有没有什么方法可以自动化这个,而不会给项目设置添加另一个恼人的步骤?我真的不明白为什么这么难实现 - 似乎如果邮件任务不是预定义的,这将更容易。希望我错过了什么。
答案 0 :(得分:5)
Mail是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 Manual documentation。
以下ANT文件有一个 install-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邮件任务任务从ANT系统类路径加载它的依赖类。这意味着构建必须分两步运行:
$ ant install-jars
$ ant
大多数ANT任务允许您指定类路径引用。邮件任务没有。试图研究这个问题让我看到以下邮件列表主题:
解决方案令人费解,不值得付出努力。我建议生活带来不便......(安装罐子目标只需要运行一次)
答案 1 :(得分:5)
使用this mail thread中的示例,我得到了一个可以在测试失败时发送电子邮件的工作解决方案。
您需要下载ant-classloadertask.jar, 来自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>
答案 2 :(得分:1)
使用taskdef
命令,您可以动态加载新任务并指定加载它们的类路径。我成功地使用它来从不在ant类路径上的外部库加载新任务。当任务已经存在时它是否也有效,我不知道。
我可能会尝试使用新名称重新定义邮件任务:
<taskdef name="mymail" classname="class.of.mail.task" classpath="mail.jar;activation.jar">
也许您需要在类路径中包含原始的ant类路径,以便可以找到邮件任务的类。
如果这不起作用,也许您可以获取邮件任务的源代码,重命名该类,将其与mail.jar
和activation.jar
中的类一起捆绑到您自己的jar中并加载来自JAR的这项任务。这应该适用于任何未附带ant的任务。
答案 3 :(得分:1)
您可以将这些jar作为外部jar放到ant run config的类路径中(这是我的ftp示例):
并将此运行配置保存到项目中(Tab:Common - &gt; Shared File,我通常采用resources/eclipse
之类的东西)并将其提交给svn。
当然你可以write your own mail task来照顾它。
答案 4 :(得分:1)
使用Ant 1.8.2和ant-classloadertask.jar解决方案提到above(bro)我需要更改 classloadertask loader 属性>来自:
loader="thread"
成:
loader="project"
否则类加载器找不到 activation.jar 和 mail.jar 中的类。