2012-10-09 14 views
5

Ich habe einen Client und einen Server, den ich mit Ant baue. Der Client ist darauf angewiesen, dass der Server zuerst erstellt wird, bevor er erstellt werden kann. Ich habe alle erforderlichen Bibliotheken mit Ausnahme der Server-Ear-Datei im Client gebündelt.Verknüpfen von Ant-Builddateien

Ich erstellte 3 Ameisen-Dateien build.xml, build-client.xml und build-server.xml. (Klicken Sie auf einen der Dateinamen, um sie zu sehen) Die Dateien build-client.xml und build-server.xml sind in build.xml enthalten, so dass sie Ziele von ihnen ausführen können.

Das Problem, das ich habe, ist, dass die basedir Variable von Build-Datei zu Build-Datei ändert. Wenn ich also Ziele in build-client.xml von build.xml ausführen, ist die Variable basedir relativ zu build.xml.

Wie ändere ich die basedir-Variable mehrmals innerhalb eines Ant-Skripts?

Wenn Sie diese Builddateien betrachten, sehen Sie dann eine bessere Möglichkeit, das zu tun, was ich versuche? Im Moment denke ich, dass ich sowohl den Client-Krieg als auch das Server-Ohr an der gleichen Stelle haben muss, bevor ich das letzte Bündelohr machen kann. Meine Vorstellung davon mag jedoch fehlerhaft sein, weil diese Skripte unnötig komplex erscheinen.

Antwort

5

Die ant documentation für <import> Aufgabe gibt Ihnen Auskunft darüber, wie dies zu erreichen.

Beheben von Dateien gegen die importierte Datei

Ihre Haupt-Build-Datei mit dem Namen Angenommen importing.xml eine Build-Datei imported.xml importiert, die sich irgendwo auf dem Dateisystem, und imported.xml liest eine Reihe von Eigenschaften aus importierten. Eigenschaften:

<!-- importing.xml --> 
<project name="importing" basedir="." default="..."> 
    <import file="${path_to_imported}/imported.xml"/> 
</project> 

<!-- imported.xml --> 
<project name="imported" basedir="." default="..."> 
    <property file="imported.properties"/> 
</project> 

Dieser Code-Schnipsel aber wird imported.properties gegen die basedir von importing.xml lösen, weil die basedir von imported.xml von Ant ignoriert. Der richtige Weg, um importiert zu werden.Eigenschaften sind:

<!-- imported.xml --> 
<project name="imported" basedir="." default="..."> 
    <dirname property="imported.basedir" file="${ant.file.imported}"/> 
    <property file="${imported.basedir}/imported.properties"/> 
</project> 

Wie oben ${ant.file.imported} speichert den Pfad des Build-Skript erklärt, dass das Projekt importiert genannt definiert, (kurz es den Pfad imported.xml speichert) und <dirname> nimmt sein Verzeichnis. Diese Technik ermöglicht auch, dass importierte.xml als eigenständige Datei verwendet werden kann (ohne in ein anderes Projekt importiert zu werden).

Grundsätzlich kann man nicht wirklich nutzen die ${basedir} Variable, noch das basedir="./../GrahamsProjClient" Attribut in Ihrem Projekt-Tag, sondern können Sie es konstruieren:

<!-- build-client.xml --> 
<project name="GPClient" default="dist" > 

    <dirname property="client.root.dir" file="${ant.file.GPClient}"/> 
    <property name="real.basedir" value="${client.root.dir}/../GrahamsProjClient"/> 

    <!-- Then from then on, replace ${basedir} with ${real.basedir} --> 
    ... 
</project> 

Sie können für den Build-Server das gleiche tun. xml, das einzige, worauf zu achten ist, ist, dass der Projektname im Dateiattribut ${ant.file.[project name]} für <dirname /> vorkommt.

0

eine Sache, die ich mit Ameise auffiel, war, dass ich nicht Variablen zu ändern bekommen könnte, wie ich

die Lösung wollte, war von der Kommandozeile ant ausgeführt haben Sie für jedes Ziel tun wollten, so zu tun, anstatt eine Kommandozeilen-Anweisung wie

ant target1 target2

oder

<target name="target1"> 
    <antcall target="target2"> 
</target> 

ich das Ziel, anstatt zu tun hatte, ruft sequ entially von der Kommandozeile ant target1 ant target2

so dass ich auf der Umsetzung dieser Ameise Anrufe in einem Python-Skript entschieden, das macht einfach os.system(""); Anrufe, wo meine Kommandozeilen-Anweisungen in Anführungszeichen sein würde. bash könnte dies auch tun

dies ist der einzige Weg, die Ameise, die richtigen Variablen für jedes Ziel verwenden würde, wenn diese Variablen den gleichen Namen hatten

3

Meine normale Regel ist nicht <ant> oder <subant> in einem normalen Build-Prozess zu verwenden, weil es die Abhängigkeitsprüfung bricht. Wir hatten einen Entwickler, der eine build.xml in sieben separate Build-Dateien aufteilte, und aufgrund des ständigen Aufrufs von <ant> Aufgaben, die in anderen Build-Dateien erledigt wurden, führte er dasselbe Ziel bis zu 14 Mal aus. Und dann fragte er sich, warum sein Build so lange gedauert hatte. Das Zusammenfügen der sieben Build-Dateien zu einem einzigen build.xml und das Verwenden des depends-Parameters von <target> verkürzte den Build auf weniger als zwei Minuten.

Was Sie jedoch in diesem Fall haben, sind wirklich zwei separate Projekte und ein build.xml, die Sie verwenden, um diese zwei separaten Projekte aufzurufen. In diesem Fall verwenden Sie besser <ant> und <subant> Anrufe als <import>.

  • Diese Anrufe stören ${basedir} nicht.
  • Mit diesen Aufrufen können Sie angeben, welche Eigenschaften und Ressourcen in diese separaten Dateien eingeschlossen werden sollen. (Wahrscheinliche Antwort ist keine).
  • Sie haben kein Problem mit mehreren Zielen, die denselben Namen haben. Ein kompilieren Ziel in Ihrem Client-Build wird das _compile_ Ziel in Ihrem Server-Build nicht überlappen.

Subant ist leistungsfähiger, aber schwieriger zu implementieren. Mit Subant können Sie nach den build.xml-Dateien suchen lassen. Die meiste Zeit mit <ant> ist einfach einfacher und macht was Sie wollen.


Was ich wirklich empfehlen würde ist Ivy verwenden, um die Abhängigkeitsprobleme zu behandeln. Ivy kann nicht nur die Serverabhängigkeit in Ihrem Client verarbeiten, sondern auch alle JAR-Abhängigkeiten von Drittanbietern. Kein Speichern von JAR-Dateien in Ihren Projekten mehr. Wenn Sie JAR-Dateien in einem Projekt speichern, verlieren Sie Informationen über ihre tatsächliche Version und ihren Verlauf. Sie sehen ein commons-io.jar in Ihrem Projekt, und Sie haben keine Ahnung, welche Version es war oder ob es das offizielle `commons-io.jar ist, oder einer Ihrer Entwickler munged es als einen Punkt.

Das Problem ist, dass Ivy ein wenig Arbeit braucht, um zu implementieren. Sie müssen einen Ivy-Repository-Manager wie Nexus, Artifactory oder Archiva verwenden. (Eigentlich sind dies Maven-Repository-Manager, aber Ivy arbeitet sehr gut mit ihnen zusammen.)

Dann müssen Sie die ivy.jar in Ihr Projekt importieren und die ivysettings.xml Datei auf Ihren Maven Ivy-Repository-Server verweisen.

Wenn Sie Subversion als Versionskontrollsystem verwenden, können Sie folgendes tun:

  • Neues Ivy Projekt, das die ivy.jar enthält, und eine XML-Datei, die alles für dich setzt. Ich habe eine in Github, die Sie anschauen können. Die XML-Datei heißt ivy.tasks.xml.
  • Verwenden Sie dann in Ihrem Projekt svn:externals, um dieses Projekt zu importieren.
  • In Ihrem build.xml, müssen Sie zwei Dinge tun:
    • Fügen Sie den Ivy-Namespace in Ihrer <project> Einheit.
    • Verwenden Sie die Aufgabe <import>, um die Ivy XML-Datei zu importieren, die alles eingerichtet hat.

Der Vorteil ist, dass Ihr Ivy Projekt ändern, werden automatisch alle Projekte ändern, die mit Ivy interagieren. Wenn Sie beispielsweise die URL des Ivy-Servers ändern oder die Ivy-Cache-Verzeichnisse neu definieren müssen.

One Sie das tun, Sie einfach eine ivy.xml Datei erstellen, die Ihre Abhängigkeiten definiert, und verwenden Sie <ivy:cachepath> und <ivy:retrieve> die dritte Partei Gläser müssen Sie abzurufen. Dies würde den Server Jar enthalten, den Ihr Client benötigt.