2012-02-07 11 views
8

Sono stato incaricato di creare notifiche automatiche per i nostri script di build Ant. Questo è così che quando qualcuno spinge una distribuzione, il nostro team può ricevere automaticamente un'email a riguardo.Come aggiungere programmaticamente le dipendenze della libreria Ant per l'attività di posta

La scelta più ovvia era quella di utilizzare Ant's mail task, che viene predefinito con 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> 

Tuttavia, questo risultato è la seguente eccezione di runtime:

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

Questo perché compito di posta di Ant dipende JavaMail e JavaBeans Activation Framework, le librerie che apparentemente non sono incluse nella sua distribuzione. Perché Ant definisca un'attività che dipende da una libreria ma non include quella libreria non è chiara per me.

Questo problema è già stato discusso in questo post: ant mail task using mail and activation jar in external location. Sulla base delle risposte sembrano esserci due soluzioni.

Il primo consiste nel mettere manualmente queste dipendenze della libreria sul classpath della formica. Questo può essere fatto usando l'argomento della riga di comando -lib, oppure in eclissi si può usare Window > Preferences > Ant > Runtime > Global Entries, e quindi aggiungere mail.jar e activation.jar (sono abbastanza sicuro che questo equivale allo stesso -lib, correggimi se sbaglio). Ma questa soluzione non è auspicabile per il nostro team perché significherebbe che ognuno di noi dovrebbe eseguire manualmente questi passaggi. Sto cercando un modo per impegnare semplicemente il mio codice di notifica, e dovrebbe funzionare su un'altra installazione di eclissi dopo l'aggiornamento di svn.

L'altra soluzione nel post collegato parla di un modo per fare quanto sopra a livello di codice, chiamando Ant da se stesso:

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

Il problema di questo è che lo strumento da riga di comando della formica è apparentemente solo incluso con il installazione completa, non la distribuzione di eclissi. Quindi, ancora una volta non c'è modo di farlo funzionare senza alcuna azione manuale da parte di chiunque voglia utilizzare l'attività di posta elettronica.

C'è un modo per automatizzare ciò senza aggiungere un altro passaggio fastidioso alla configurazione del progetto? Non capisco davvero perché sia ​​così difficile da raggiungere - sembra che se l'attività di posta elettronica non fosse predefinita da Ant, sarebbe più semplice. Spero che mi manchi qualcosa.

+0

Avete considerato di utilizzare un elemento di configurazione per questo tipo di attività? Vengono con mail e rapporti molto migliorati. I miei voti sono per http://jenkins-ci.org/ – Jayan

risposta

5

La posta è una delle attività facoltative in ANT. Per installare queste librerie aggiuntive ANT 1.7 aggiunto uno script fetch.xml, invocato come segue:

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

Su Windows si potrebbe provare:

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

Per una spiegazione completa, vedere il ANT Manual documentation.


Aggiornamento

Il seguente file ANT ha un install-giare obiettivo che può essere utilizzato per installare i vasi ANT mancanti utilizzati dal compito di posta.

<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> 

ho scoperto che la formica attività Stampa carichi compito è classi che dipendono dal percorso di classe del sistema ANT. Questo significa che la build deve essere eseguito in due fasi:

$ ant install-jars 
$ ant 

maggior parte delle attività ANT consentono di specificare un riferimento classpath. L'attività di posta non lo fa. Cercando di ricerca di questo problema mi ha portato a questo thread mailing list:

La soluzione è complicata e non vale la pena. Raccomanderei di vivere con l'inconveniente ... (Il target install-jars deve essere eseguito solo una volta)

+0

E come potrebbe essere fatto a livello di programmazione attraverso il file di build, in modo che dopo aver eseguito una svn checkout delle modifiche (e dei barattoli) in eclissi funzionerebbe senza alcuna configurazione manuale ? –

+0

@PaulBellora Ho aggiornato la risposta –

+0

Dopo aver visto quanto è insormontabile automatizzare tutto ciò, il mio team e io abbiamo deciso di rinunciare e inghiottire la pillola di installazione manuale di Ant per Eclipse. Il tuo obiettivo di installazione si è avvicinato, +1 per quello e il collegamento - è solo sfortunato che Ant ha bisogno di riavviarsi, ma sembra che non ci sia davvero alcun modo per aggirare questo senza guai nel disordine del classloader. –

1

Con il comando taskdef, è possibile caricare dinamicamente nuove attività e specificare un percorso di classe dal punto in cui sono stati caricati. Lo uso con successo per caricare nuove attività da una libreria esterna che non si trova sul percorso della classe ant. Se funziona anche quando l'attività esiste già, non lo so.

Io probabilmente iniziare con il tentativo di ridefinire il compito di posta con un nuovo nome:

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

forse avete bisogno di includere il percorso originale di classe formica nel percorso di classe qui in modo che la classe del compito di posta può essere trovato.

Se questo non funziona, forse si può prendere il codice sorgente del compito di posta, rinominare la classe, bundle insieme con le classi di mail.jar e activation.jar nel proprio vaso e caricare questa attività dal JAR. Questo dovrebbe funzionare proprio come funziona con qualsiasi attività non fornita con form.

+0

@oers Potresti per favore dare qualche altro dettaglio perché questo non funziona? –

+0

Sry Forse sono stato in fretta, ho interpretato erroneamente la tua risposta come qualcosa che ho provato. Questo approccio potrebbe funzionare. – oers

+2

[Questo sembra possibile] (http: //ant.1045680 .n5.nabble.com/Mail-task-con-mail-jar-amp-activation-jar-out-of-lib-folder-td3347501.html), ma richiede un compito addizionale per la classe a causa di problemi di caricamento della classe – oers

1

È possibile inserire questi vasi come vasi esterni al classpath della configurazione ant run (questo è il mio esempio ftp):

enter image description here

e salvare questa configurazione corsa al progetto (Tab: Common- -> File condiviso, di solito prendo qualcosa come resources/eclipse per quello) e lo impegno in svn.

  1. sarà disponibile per tutti gli sviluppatori che effettuano il check questo progetto fuori da SVN
  2. è necessario fornire i vasi in quel progetto, anche. In modo che essi saranno sempre disponibili
  3. Tutti possono eseguirlo facilmente dal menu Strumenti esterna

Naturalmente si potrebbe write your own mail task, a prendersi cura di questo.

+0

+1 Questo è un suggerimento interessante: alla fine abbiamo deciso di tollerare il setup Ant manuale per installazione. –

5

Con l'esempio da this mail thread ho ricevuto una soluzione funzionante che invia un'email quando i test falliscono.

È necessario scaricare ant-classloadertask.jar, e mail.jar da javamail e inserirli in 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

Con Ant 1.8.2 e ant-classloadertask.jar soluzione menzionata above (da bro) Mi bisogno di cambiare loader attributo classloadertask da:

loader="thread" 

in:

loader="project" 

altrimenti classi activation.jar e mail.jar non sono stati trovati dal classloader.

Problemi correlati