# Versionierung von Servlet



## DarkGuardian (9. Jun 2009)

Hallo zusammen

Ich habe ein Problem, zu dem es bestimmt schon Lösungen gibt. Damit ich mir nicht auch noch eine überlegen muss, frage ich lieber hier nach.

Ich habe ein Servlet, welches ich mit ant erzeugen kann. Die einzelnen Klassen liegen in CVS unter Versionskontrolle. Nun habe ich aber das Problem, dass ich zwar in CVS tags anlegen kann, um bestimmte Stände zu markieren. Aber ich kann ein erzeugtes WAR nicht einem Tag zuordnen. Welche Mechanismen gibt es für sowas und welcher ist zu empfehlen?

Achso, im laufenden System sollte erkennbar sein, welche Version genutzt wird. Daher benötige ich entweder einen Abruf der Version irgendwie über das Tomcatinterface oder über die vom Servlet generierten HTML-Seiten.

Ich hoffe, dass ihr mir dazu Tipps geben könnt.


----------



## maki (9. Jun 2009)

Die version kannst du doch zB. über einen String im response mitsenden, oder über eine public Variable bereitsstellen.
Die Version sollte auf jedenfall mit in die Webapp, zB. als init-parameter für die Servlets, oder oder oder...

Wenn das Servlet generiert wird, sollte es imho nicht ins SCM (CVS, SVN, etc. pp.), sondern die Quellen aus denen es generiert wird sollten ins SCM.
wars, jars und sonstige Artefakte sollten imho auch nicht in SCM.

Oder habe ich dich falsch verstanden?


----------



## DarkGuardian (9. Jun 2009)

OK, wenn ich einen String mit der Versionsangabe nutzen will, muss ich diesen mit ant erzeugen. Dabei müsste ich dann sehen, was ich dabei nutze, da ich keine eindeutige Versionsnummer durch CVS erhalte. Also selbst setzen (z.B. als Parameter) oder den Tagnamen.

Die Wars und Jars wollte ich auch nicht im CVS ablegen. Aber wenn ich eine War-Datei habe, möchte ich ja schon erkennen können, welche Version das ist. Und mit dieser Information muss ich wissen, welche Version (Tag) das im CVS ist.

Und genau diese Verbindung ist mir noch nicht ganz klar. Unter Subversion hätte ich da einfach die Revisionnummer eingetragen, aber die habe ich hier nicht.


----------



## nail (9. Jun 2009)

Dies sollte relativ einfach machbar sein.

Da ja CVS mit substitution keywords arbeitet, kannst du in eine JSP/HTML datei einfach ein Stücken Javascript schreiben, welcher als variable die Revision überreicht bekommt z.B:

var revision = $Revision$

Beim committen (ich arbeite seit Jahren nicht mehr mit CVS darum, weiss ich es nicht genau) wird dann dieser Platzhalter mit der tatsächlichen Revision gefüllt...

Dann kannst du entweder dies Blank so anzeigen (dann kannst du direkt in die JSP/HTML schreiben und brauchst kein javascript) oder durch das Javascript noch umformatieren, damit es die Informationen hat, die du brauchst..


----------



## kama (9. Jun 2009)

Hallo,

in CVS gibt es auch noch die Möglichkeit $Name$ zu Verwenden....ich würde Dir aber raten, dass das im Rahmen eines Build Processes mit Ant zu erledigen.

Also neue Release Taggen und dann die getagte Version bauen und den Tag Namen an einer Stelle einbauen z.B. im Manifest File etc.

MfG
Karl Heinz Marbaise


----------



## DarkGuardian (10. Jun 2009)

Also das Keyword revision hilft mir leider nicht weiter. Denn unter CVS erhält ja jede Datei eine eigene Versionsnummer. Diese wird dann auch in die Datei eingetragen. Somit bräuchte ich eine Datei, die bei jeder Generierung eines definerten Standes geändert wird (und am besten auch nur dann). Das kann ich aber nicht garantieren.

Aber das Keyword name sieht da schon interessanter aus. Damit könnte ich den Zusammenhang zwischen War-Datei und Tag ermitteln. Zudem schaue ich mir mal genauer die Manifestdatei an. Das scheint ja der Ort zu sein, wo man sinnvoll solche Informationen ablegt. Dann muss ich nur noch sehen, wie ich diese dort auch wieder zur Anzeige bringen kann.


----------



## Noctarius (10. Jun 2009)

Ich würde es auch per ANT erledigen. Die Revision (oder Buildnummer) kannst du dann in z.B. einer Textdatei speichern und bei jedem ANT-Durchlauf hochzählen.

Ansonsten kommt noch der Umzug in ein SVN in Frage, welches auf Changesets basiert.


----------



## DarkGuardian (10. Jun 2009)

Ein Umzug auf SVN wäre mir sogar recht lieb, aber darauf habe ich keinen Einfluss. Somit muss ich eine Lösung mit CVS finden.

Das Ganze mit ANT zu erledigen, wäre genau in meinem Sinne. Die Version in einer Datei abzulegen hatte ich mir auch überlegt. Aber wie sinnvoll ist es, dass ANT einfach einen hochzählt?
Die Datei mit der Versionsangabe müsste dann auch unter CVS liegen. Wenn ANT aber diese ändert und eincheckt, ist die Datei nicht mehr Teil des Tags. Wird die Datei aber nicht im CVS hinterlegt, ist ein allgemeines Hochzählen nicht möglich. Und checkt man diese über ANT nicht ein, ist die eindeutige Zuweisung zu Tag nicht gegeben. Dann kann ich nur feststellen, welche Version der Versionsdatei genutzt wurde.


----------



## Noctarius (10. Jun 2009)

Entweder baust du das ANT Plugin so, dass es die Datei automatisch nach dem Hochzählen eincheckt oder es muss erst gebaut und dann eingecheckt werden.


----------



## DarkGuardian (10. Jun 2009)

Dann habe ich meine Bedenken wohl nicht richtig ausgedrückt. Egal ob ANT den Wert in einer Datei automatisch hochläd und eincheckt oder ob es etwas baut und eincheckt, in beiden Fällen ist diese Versionsangabe nicht Teil des Tags und bei erneuter Generierung einer Version kommt es im CVS zur Kollision (ok, das lässt sich aber abfangen).


----------



## Noctarius (10. Jun 2009)

Das kann das Plugin doch machen:

Beispiel Lifecycle des Plugins:
ANT Versionnumber Plugin: ... -> automatischer CVS Checkout "buildnumber.txt" -> buildnumber.txt einlesen, hochzählen, wegschreiben -> CVS Checkin "buildnumber.txt"

Wenn keiner von Hand an der Datei schraubt sollte es so funktionieren. Praktisch wüsste ich sonst keinen anderen Weg, da CVS eben nicht Changeset sondern File basiert Versionen (bzw Revisionen) zählt.

edit: ich habe gerade mal nach "cvs changeset" gegoogled und da gibt es ein Perlscript, dass die Checkins anhand der Commitmessage zusammen sucht und so könnte man wenn man mag die "Changesetrevision" ausrechnen, indem man alle Commits nach zusammenlegen aufaddiert. Damit könnte man das File umgehen (wird vermutlich nur bei vielen Commits umfangreich. Wenn man aber nen Set nimmt und jede Message reinschmeisst hat man am Ende genau die Anzahl der Commits, das sollte dann schon reichen)

noch ein Nachtrag: How does FishEye calculate CVS changesets? - FishEye 1.6 - Atlassian Documentation - Confluence


----------



## DarkGuardian (10. Jun 2009)

Danke für deine Hinweise. So richtig überzeugend finde ich das Vorgehen nicht, aber das liegt wohl wirklich an der Arbeitsweise von CVS. Mal sehen wie ich das nun genau umsetze, aber anscheinend wird es wohl in Richtung deines Vorschlags gehen.


----------



## Noctarius (10. Jun 2009)

Wenn es dich übrigens interessieren würde daran gemeinsam zu werkeln würde ich ein kleines OSS Projekt vorschlagen, das genau dieses Problem als ANT und vllt auch als Maven Plugin lösen würde. Gibt bestimmt noch mehr Leute die es toll fänden wenn es sowas geben würde (zumind. da CVS in dem Bereich pfui ist - haben es hier in der Firma auch immer noch im Einsatz und ich kenn schon wenigstens 2 Stellen in unseren Anwendungen wo ich es einsetzen würde *gg*)


----------



## maki (10. Jun 2009)

Noctarius hat gesagt.:


> Wenn es dich übrigens interessieren würde daran gemeinsam zu werkeln würde ich ein kleines OSS Projekt vorschlagen, das genau dieses Problem als ANT und vllt auch als Maven Plugin lösen würde. Gibt bestimmt noch mehr Leute die es toll fänden wenn es sowas geben würde (zumind. da CVS in dem Bereich pfui ist - haben es hier in der Firma auch immer noch im Einsatz und ich kenn schon wenigstens 2 Stellen in unseren Anwendungen wo ich es einsetzen würde *gg*)


Für Maven2 gibt es so etwas natürlich schon (Maven Release Plugin - Maven 2 Release Plugin), bestimmt auch für Ant, müsste man mal Googlen...


----------



## Noctarius (10. Jun 2009)

Aber dieses Plugin macht um Längen mehr als er gerne hätte und mit CVS wird es vermutlich das selbe Problem haben


----------



## DarkGuardian (10. Jun 2009)

Hmm, der Vorschlag mit dem OSS-Projekt ist wirklich nicht schlecht. Aber zum Einen würde ich erst mal recherchieren, ob da nicht vielleicht schon Projekt in dem Bereich bestehen. Denn ich finde es sinnlos, ständig neue Projekte zu starten, obwohl bereits andere in der Richtung arbeiten.

Zum Anderen muss ich mich erst mal allgemein mit ANT und CVS tiefer auseinandersetzen. Denn bisher habe ich es nur genutzt soweit es notwendig war. Alles andere habe ich außen vor gelassen. Bei CVS weil ich SVN bevorzuge und bei ANT weil ich eigentlich seltener Javaprojekte habe.

Ich hoffe, dass ich mich da möglichst bald dazu etwas genauer informieren kann. Wenn ich dann auch noch sehe, dass ich auch Zeit dazu habe, gebe ich hier bescheid. Und die Chancen stehen besser als es erst mal klingt .


----------



## Noctarius (10. Jun 2009)

Ich persönlich mag maven lieber als ant 
und Mercurial oder Darcs > SVN > CVS


----------



## DarkGuardian (12. Jun 2009)

Dann sollten wir schauen, dass das Plugin auch unter Maven eingesetzt werden kann. Zumal Maven ja anscheinend ANT langsam ersetzt.

Mercurial und Darcs kenne ich gar nicht, aber dem Rest deiner Reihenfolge kann ich nur voll zustimmen. Aber anscheinend wird CVS doch noch sehr häufig eingesetzt, so dass ein solches Plugin schon sinnvoll sein dürfte.


----------



## Noctarius (12. Jun 2009)

Maven ersetzt ANT nicht, sondern ist in erster Linie ein Abhängigkeiten-Manager. Für Maven gibt es aber eben auch ein Buildplugin, dass die Sources dann übersetzt.

Ohne Plugin wäre es aber nur ein Dependency Manager und nicht mehr.

Mercurial, Darcs, GIT, ... sind sogenannte Distributed Revision Systems.


----------



## DarkGuardian (12. Jun 2009)

Ah ok, dann deckt Maven doch einen anderen Bereich ab (zumindest in der Grundfunktion ohne Plugins).

GIT ist mir allerdings ein Begriff. Das wird ja auch beim Linux Kernel eingesetzt und in der aktuellen iX ist ein Bericht dazu. Der gibt zwar in der Tiefe nicht viel her, aber er hilft, um den grundsätzlichen Unterschied zu manch anderen Versionverwaltungssystemen zu erkennen.


----------



## kama (12. Jun 2009)

Hi,



Noctarius hat gesagt.:


> Maven ersetzt ANT nicht, sondern ist in erster Linie ein Abhängigkeiten-Manager. Für Maven gibt es aber eben auch ein Buildplugin, dass die Sources dann übersetzt.


Also Sorry die Aussage kann ich so nicht stehen lassen.

Die Primäre Aufgabe von Maven2  ist es einen definierten Compile/Test/Packaging/Release Zyklus zu definieren, wobei andere Dinge wie z.B. Abhängigkeiten auch ein Teil sind und dazu ist zu sagen, dass hierbei auch Transitive Abhängigkeiten gehandhabt werden.

Maven - What is Maven?

Wenn man sich auf die Abhängigkeiten Bezieht gibt es für Ant entsprechendes, dass nennt sich Ivy....

Abgesehen davon ist Maven noch wesendlich mehr....

Die technische Grundlage, dass Maven in Form von PlugIns realisiert ist, ist richtig...aber dazu brauche ich nichts zu tuen, um bspw. Sourcen zu compilieren, Unit Tests zu Fahren oder ein Jar zu bauen....
Die Folgende POM

```
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.soebes.t1</groupId>
  <artifactId>test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>
```
Definiert alles was ich benötige, um ein Projekt zu Compilieren, Unit Tests laufen zu lassen und in ein Jar zu verpacken...

Das kriegt man mit Ant nicht so kurz in einem build.xml hin....

Aber eines der wichtigsten Paradigmen die man in Maven mit bekommen muss und auch akzeptieren muss ist die Aussage: Konvention über Konfiguration.
z.B. Verzeichnisstruktur etc.

Ich halte Maven 2 auch noch nicht für den Weisheit letzen Schluss aber meiner Erfahrung nach geht es in die richtige Richtung...
MfG
Karl Heinz Marbaise


----------



## Noctarius (12. Jun 2009)

Ok Maven ist ein Lifecycle Management, besser? Dass es Unittests und Kompiliert ohne, dass es extra definiert ist liegt aber nur daran, dass es halt einen gewissen Lifecycle gibt der abgearbeitet wird, aber auch nur dann, wenn man die von Maven definierten Standardpfade benutzt.

Ivy dagegen ist wirklich ein reines Dependency Management. Es ersetzt (soweit ich weiß) nicht das Lifecycle Management.

Für mich zumindestens ist Maven aber trotzdem hauptsächlich ein Dependency Manager mit zusätzlichen Lifecycle. Beides zusammen sorgt unteranderem auch dafür, dass ich ein Parent Project machen kann und damit Abhängigkeiten global für alle Projekte setzen kann, die Buildreihenfolge festlegen kann, usw.


----------



## kama (12. Jun 2009)

Hallo,


Noctarius hat gesagt.:


> Ok Maven ist ein Lifecycle Management, besser? Dass es Unittests und Kompiliert ohne, dass es extra definiert ist liegt aber nur daran, dass es halt einen gewissen Lifecycle gibt der abgearbeitet wird, aber auch nur dann, wenn man die von Maven definierten Standardpfade benutzt.


Ja genau. Eben Konvention über Konfiguration....



Noctarius hat gesagt.:


> Ivy dagegen ist wirklich ein reines Dependency Management. Es ersetzt (soweit ich weiß) nicht das Lifecycle Management.


Ja genau. Der Lifecylce ist genau der große Unterschied zwischen den Beiden. zzgl. einiger andere Sachen wie unten beschrieben.



Noctarius hat gesagt.:


> Für mich zumindestens ist Maven aber trotzdem hauptsächlich ein Dependency Manager mit zusätzlichen Lifecycle. Beides zusammen sorgt unteranderem auch dafür, dass ich ein Parent Project machen kann und damit Abhängigkeiten global für alle Projekte setzen kann, die Buildreihenfolge festlegen kann, usw.


Vererbung etc. ist ein riesiger Vorteil für größere Projekte und Unternehmen....Ähm...die Buildreihenfolge kann man nicht festlegen, die ist vom Lifecycle definiert...man kann lediglich bestimmte Aufgaben (anderes Packaging z.B. .tar.gz etc.) daran hängen. 
Siehe auch Lifecycle Referenz.


----------



## Noctarius (12. Jun 2009)

kama hat gesagt.:


> Ähm...die Buildreihenfolge kann man nicht festlegen, die ist vom Lifecycle definiert...



Doch kannst du indem du das Maven Module System benutzt. Da kannst du im Parent genau angeben in welcher Reihenfolge die Projekte gebaut werden um die richtigen Abhängigkeiten zu garantieren:

http://www.castellcore.org/svn/castellcore/branches/modularize/CastellCoreParent/pom.xml


```
<modules>
        <module>../CastellCoreApi</module>
        <module>../CastellCoreBase</module>
        <module>../CastellCoreUtils</module>
        <module>../CastellCoreTesting</module>
        <module>../CastellCoreObjectQuery</module>
        <module>../CastellCoreSecurity</module>
        <module>../CastellCoreValidator</module>
        <module>../CastellCoreWire</module>
        <module>../CastellCoreWindowing</module>
        <module>../CastellCoreInterconnect</module>
        <module>../CastellCoreMaven</module>
        <module>../CastellCoreStateMachine</module>
    </modules>
```


----------



## kama (12. Jun 2009)

Hallo,



Noctarius hat gesagt.:


> Doch kannst du indem du das Maven Module System benutzt. Da kannst du im Parent genau angeben in welcher Reihenfolge die Projekte gebaut werden um die richtigen Abhängigkeiten zu garantieren:


Achso das Meintest...Hatte ich anders verstanden ;-(

Damit gibst Du lediglich die Module an die Verwendung finden. Das ist aber nicht gleichzeitig die Build Reihenfolge...Die Abhängigkeit werden duch die Module selbst festgelegt. Wenn keine Abhängkeiten die Reihenfolge festlegen, dann wird Sie durch die Angabe im Parent POM festgelegt (Ist aber auch durch Abhängigkeiten der Module untereinander definiert).

Wenn z.B. in dem Beispiel CastellCoreTesting Abhängigkeiten zu CastellCoreValidator hätte, dann würde CastellCoreTesting nach CastellCoreValidator gebaut...Das löst Maven selbst auf...

Mit anderen Worten in Maven brauchst Du Dir nur gedanken über die Abhängigkeiten der Module untereinander zu machen. Im Parent POM gibst Du dann nur die Liste der Benutzen Module an und die Reihenfolge des Bauens löst Maven selbst auf.
Beispiel aus einem eigenen Projekt (Ausschnitt POM)

```
<modules>
		<module>supose-cli</module>
		<module>supose-rest</module>
		<module>supose-war</module>
		<module>supose-tomcat</module>
		<module>supose-doc</module>
		<module>supose-it</module>
		<module>supose-core</module>
		<module>supose-soap</module>
		<!-- 	<module>supose-wefe</module> -->
	</modules>
```
Aber Maven bringt das schon in die Richtige Reihenfolge:
	
	
	
	





```
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] SupoSE :: Subversion Repository Search Engine ......... SUCCESS [2.563s]
[INFO] SupoSE :: Core ........................................ SUCCESS [0.281s]
[INFO] SupoSE :: CLI ......................................... SUCCESS [0.156s]
[INFO] SupoSE :: RESTlet ..................................... SUCCESS [0.047s]
[INFO] SupoSE :: WAR ......................................... SUCCESS [0.328s]
[INFO] SupoSE :: SOAP ........................................ SUCCESS [1.047s]
[INFO] SupoSE :: Tomcat ...................................... SUCCESS [0.203s]
[INFO] SupoSE :: Documentation ............................... SUCCESS [0.141s]
[INFO] SupoSE :: Integration Test ............................ SUCCESS [0.016s]
```
Egal in welcher Reihenfolge ich die in der POM Schreibe....

MfG
Karl Heinz Marbaise


----------

