2012-02-07 33 views
8

我的任务是为我们的Ant构建脚本创建自动通知。这样当有人推出部署时,我们的团队可以自动收到有关它的电子邮件。如何以编程方式为邮件任务添加Ant库依赖关系

最明显的选择是使用Ant's mail task,这与Ant预定义:

<target name="notify" description="notify team"> 
    <mail subject="latest deployment"> 
     <from address="[email protected]" /> 
     <to address="[email protected]" /> 
     <message>A new build has been pushed out to prod</message> 
    </mail> 
</target> 

然而,这将导致以下运行时异常:

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

这是因为蚂蚁的邮件任务取决于JavaMailJavaBeans Activation Framework,这些库显然不包含在其发行版中。为什么Ant会定义一个依赖于图书馆的任务,但不包括那个图书馆对我来说还不清楚。

此问题已经讨论过此问题:ant mail task using mail and activation jar in external location。根据答案,似乎有两个解决方案。

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

中的链接后另一种解决方案中提到一种以编程方式做以上,从自身调用蚂蚁:

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

这样做的问题是,Ant命令行工具显然只包含在完全安装,而不是eclipse发行版。如果没有任何人想要使用邮件任务,那么再也无法使其工作。

有没有什么办法可以自动执行此操作,而无需在项目设置中添加另一个烦人的步骤?我真的不明白为什么这很难实现 - 看起来如果邮件任务不是由Ant预定义的,这将更容易。希望我错过了一些东西。

+0

您是否考虑过使用CI来完成这类任务?他们附带邮件和更多改进的报告。我的投票是http://jenkins-ci.org/ – Jayan 2012-02-08 09:25:21

回答

5

邮件是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文件具有安装-罐目标,可用于安装由邮件任务使用的失踪ANT罐子。

<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="[email protected]" /> 
      <to address="[email protected]" /> 
      <message>A new build has been pushed out to prod</message> 
     </mail> 
    </target> 

</project> 

我发现ANT邮件任务任务从ANT系统类路径加载它的依赖类。这意味着构建必须分两步进行:

$ ant install-jars 
$ ant 

大多数ANT任务允许您指定类路径引用。邮件任务没有。试图研究这个问题使我下面的邮件列表线程:

的解决方案是令人费解的,不值得。我建议生活带来不便...(安装jar目标只需要运行一次)

+0

而这又怎么可能通过构建文件以编程方式完成,以便在执行svn检出eclipse中的更改(和jars)之后,它将在没有任何手动设置的情况下工作? – 2012-02-08 01:44:09

+0

@PaulBellora我已经更新了答案 – 2012-02-08 21:58:02

+0

在看到如何不可逾越的真正自动操作之后,我和我的团队决定放弃并吞下手动设置每次安装Ant的药片。你的安装目标已经接近,+1和链接 - 这只是不幸的Ant需要重新启动,但似乎没有涉及到类加载器的混乱,真的没有办法。 – 2012-02-10 00:42:19

1

使用taskdef命令,您可以动态加载新任务并从加载它们的位置指定一个类路径。我成功地使用它来从不在ant类路径中的外部库加载新任务。当这个任务已经存在时它是否也有效,我不知道。

我可能会与尝试用新名称重新定义邮件任务开始:

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

也许你需要在这里包括在类路径的原始蚂蚁类路径,使类的邮件任务可以找到。

如果这不起作用,或许你可以把邮件任务的源代码,命名类,从mail.jaractivation.jar类捆绑在一起,它变成你自己的罐子,从JAR加载此任务。这应该可以像任何未附带ant的任务一样工作。

+0

@oers能否给我一些更详细的信息为什么这是行不通的? – 2012-02-08 09:01:05

+0

Sry我可能一直很仓促,我错误地将你的答案看作是我试过的东西,这种方法可能会起作用 – oers 2012-02-08 09:18:06

+2

[这似乎是可能的](http://ant.1045680 .n5.nabble.com /邮件任务与邮件-JAR放大器激活-JAR-外的LIB文件夹-td3347501.html),但需要产生额外蚂蚁的任务,由于类加载的问题。 – oers 2012-02-08 09:43:34

1

你可以把这些罐子外部罐子蚂蚁运行配置的类路径(这是我的FTP为例):

enter image description here

,并保存这个运行配置的项目(表:共 - >共享文件,我通常采取像这样的resources/eclipse),并将其提交给svn。

  1. 这将可谁签这个项目出从SVN
  2. 所有的开发人员,你必须提供在该项目的罐子了。于是,他们将始终可用
  3. 每个人都可以从外部工具菜单

你当然可以write your own mail task,要采取照顾很容易地运行它。

+0

+1这是一个有趣的建议 - 最终我们决定只容忍每次安装的手动Ant设置。 – 2012-02-10 00:45:26

5

this mail thread为例,我得到了一个可以在测试失败时发送电子邮件的工作解决方案。

您需要从javamail下载ant-classloadertask.jar, 和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> 
1

With Ant 1.8。2和ant-classloadertask.jar溶液提到above(由bro)我需要改变从装载机属性的classloadertask

loader="thread" 

成:

loader="project" 

否则班的activation.jarmail.jar未被类加载器找到。

相关问题