Teilen eines großen Projekts, um ein Maven-Projekt mit mehreren Modulen zu erstellen

23

Ich arbeite an einer Spring-MVC-Anwendung, in der wir Maven für das Abhängigkeitsmanagement verwenden. Da das Projekt groß ist, denken wir darüber nach, das Projekt in mehrere Teile aufzuteilen. Ich hatte einige Zweifel, auf die ich hier hoffentlich Antworten bekomme.

Derzeit stellen wir eine einzelne WAR-Datei wie ROOT.warauf Apache Tomcat auf unserem Server bereit. Da das Projekt groß ist, enthält die Webanwendung Teile wie Benachrichtigungen und E-Mail, Dienste von Drittanbietern, PUSH (Cometd), REST-APIs usw. Gegenwärtig sind alle in Clubs zusammengefasst und voneinander abhängig. Zum Beispiel Notificationhängt das Objekt auch vom PersonObjekt ab, da Benachrichtigungen auf Benutzer zugeschnitten sind.

Die Hauptabsicht der Aufteilung des großen Projekts besteht darin, an einzelnen Modulen arbeiten zu können, um Fehler zu beheben, Funktionen hinzuzufügen, zu testen usw. Wenn dies der Fall ist, kann statt der gesamten Anwendung nur dieses Modul auf dem Server ersetzt werden. Ist das möglich?

Wie bereits erwähnt, gibt es Abhängigkeiten und Zuordnungen zwischen Objekten. Wie werden diese über verschiedene Untermodule verwaltet oder werden nur die Importanweisungen geändert, um andere Projekte einzuschließen?

Wie gesagt, es ist beabsichtigt, an einzelnen Modulen zu arbeiten und diese einsetzen zu können (vorzugsweise im laufenden Betrieb). Derzeit haben wir nur eine einzige WAR-Datei als ROOT.war. Werden durch das Aufteilen mehrere Kriegsdateien erstellt, die dann als URL bezeichnet werden domain-name.com/module_name/some_mapping?

Ich überprüfe derzeit die Dokumentation, aber dies ist das Hauptziel, das wir mit dem von Maven bereitgestellten Multi-Modul erreichen möchten, und wir möchten wissen, ob dies machbar ist. Wenn Sie weitere Informationen benötigen, lassen Sie es mich bitte wissen.

Zur Zeit benutze ich ein Eltern-POM aus dem Frühjahr wie folgt:

<parent>
    <groupId>io.spring.platform</groupId>
    <artifactId>platform-bom</artifactId>
    <version>1.1.3.RELEASE</version>
    <relativePath />
</parent>
Wir sind Borg
quelle
1
Ich überlasse es anderen, zu antworten. Die Idee ist sehr solide. Sie könnten mit einem übergeordneten POM mit dependencyManagement und einem Jar für DAOs wie Person beginnen. Eine sehr einfache Bibliothek. Und so weiter. Natürlich keine zyklischen Abhängigkeiten.
Joop Eggen

Antworten:

20

Ist es möglich ?

Ja sicher. Ich habe in der Vergangenheit einige Projekte wie dieses strukturiert, hier ein paar Teile, von denen ich hoffe, dass sie Ihnen den Einstieg erleichtern.

Es gibt zwei Hauptmerkmale von Maven, mit denen Sie Dinge zusammenweben können:

Teilen und erobern

Sie müssen Ihre Projekte in mehrere unabhängige Projekte aufteilen. Hiermit unabhängig meine ich, dass alle Verweise auf Code außerhalb des Projekts durch Abhängigkeiten in Maven und nicht direkt Zusammenführen des Quellbaums erfolgt.

Abhängig vom Status Ihres Quellbaums kann dies eine Menge Arbeit bedeuten. Das heißt, Sie tun es nicht, um Maven einen Schuhlöffel abzulegen, sondern um Ihre Codebasis zu strukturieren und zu bereinigen. Stellen Sie es sich als Ihren Werkzeugschuppen vor, der es viel einfacher macht, Dinge hier zu finden:

Schöner Werkzeugschuppen

als hier:

Nicht so schöner Geräteschuppen

Maven verlässt sich stark auf Konventionen. Je besser die Organisation Ihres Materials ist, desto mehr kann Maven Ihnen helfen. Das heißt, es kann erforderlich sein, dass Sie Ihre Organisation neu organisieren, um sie besser an die eigene Konvention anzupassen, und wenn ich hier einen Ratschlag geben muss, ist es VIEL einfacher, Ihre Inhalte an die Konventionen von Maven anzupassen, als zu versuchen, Maven so zu konfigurieren Verstehe deine Konvention.

Wenn diese Projekte außerhalb der Hauptanwendung verwendet werden könnten, könnten sie als wirklich unabhängige Bibliotheken und in Abhängigkeit von Maven existieren. Sie sollten sich in einem eigenen Repository befinden (nicht im Anwendungsquellbaum) und von keinem Teil der Hauptanwendung abhängig sein.

Kernteile Ihrer Anwendung können nach Aufteilung in Projekte zu Modulen zusammengefasst werden. Normalerweise werden sie als Unterordner des Hauptquellordners Ihrer App abgelegt.

Auch Ihr übergeordneter POM für Ihre App enthält die Moduldeklaration. Dort platzieren Sie auch alle gängigen Abhängigkeiten für Ihre App und deklarieren die meisten Build-Plugins und deren Konfiguration. Auch hier empfehle ich Ihnen dringend, eine Gruppe von Eigenschaften für Dinge wie die Version der Anwendung zu platzieren, die Sie in den Modulen wiederverwenden können. Viel einfacher zu verwalten, wenn alle dieselbe Version haben und die Version an einem Ort ist, funktioniert dies einfach.

Werkzeug

Wenn Sie ein Team größer als 1 sind, würde ich Ihnen auch dringend empfehlen, ein Repository für Ihre Maven-Abhängigkeiten zu installieren. Schauen Sie sich Artifactory , Nexus oder Archiva an . Sie können die POM-Datei so konfigurieren, dass sie direkt auf diese Dateien installiert wird. Sobald sie ausgeführt wird, ist dies kein großer Aufwand, spart Ihrem Team jedoch viel Zeit, wenn Sie die Abhängigkeiten mit der richtigen JAR-Datei an der richtigen Stelle auflösen.

In Bezug auf das Werkzeug ist der nächste logische Schritt hier ein kontinuierliches Integrationssystem ( Jenkins , es gibt noch viel mehr). Es kümmert sich darum, die Quelle zu erstellen, die die Tests ausführt, und das Artefakt zu erstellen. Mit all dem, was Sie tun müssen, müssen Sie nur den Code bearbeiten, und der Rest funktioniert.

Da Sie Ihre App als War Maven verpacken, können Sie den Krieg erstellen und alle Abhängigkeiten an den richtigen Stellen platzieren, ohne JAR-Dateien oder ähnliche Aufgaben zusammenführen zu müssen.

Beispiel

Ich könnte hier viel länger weitermachen, aber nichts ist besser als ein gutes Beispiel. Suchen Sie in Github nach Projekten ähnlicher Größe und sehen Sie, wie sie ihre POM-Dateien und Ordnerhierarchien erstellt haben. Schauen Sie sich mehr als einen an, einige passen besser zu Ihrem Setup als andere, keiner verkörpert wirklich die Wahrheit, aber Sie sollten genug finden, um sich Gedanken darüber zu machen, wie Sie es schaffen können.

Nehmen Sie Jenkins zum Beispiel:

Sie können sehen, dass der übergeordnete POM ziemlich umfangreich ist.

Sie verwenden Module, wie Sie in diesem Abschnitt sehen können:

<modules>
    <module>core</module>
    <module>war</module>
    <module>test</module>
    <module>cli</module>
</modules>

Und jedem Modul entspricht ein gleichnamiger Unterordner, der auch ein POM enthält. Sie können so viele verschachteln, wie Sie möchten;).

Fangen Sie klein an

Wenn Sie Maven noch nie benutzt haben, würde ich vorschlagen, dass Sie jedoch nicht sofort mit den Modulen beginnen. Nehmen Sie es langsam, beginnen Sie mit einer der einfacheren Bibliotheken, die Sie möglicherweise haben, und machen Sie es zu einem Maven-Projekt. Dann machen Sie aus Ihrer Hauptanwendung ein einfaches Maven-Projekt. Sobald dies funktioniert, füge einfache Abhängigkeiten hinzu, teile dann dein erstes Modul auf und so weiter.

Maven ist ein großartiges Werkzeug, aber es kann auch sehr schmerzhaft im Nacken sein, besonders wenn die Dinge nicht so laufen, wie Sie es möchten. Beginnend mit dem ganzen Paukenschlag bei deinem ersten Versuch ist ein Rezept für eine Katastrophe (war für mich!).

Wenn die Dinge etwas seltsam sind, können Sie immer einen mvn help:effective-pomBefehl verwenden, um zu sehen, was Maven tatsächlich verstanden hat.

Plugins

Durch Ihren Kommentar verstehe ich besser, was Sie erreichen wollen. In diesem Fall würde ich Plugins Ansatz gehen. Erstellen Sie ein Projekt, das die API der Erweiterungspunkte verfügbar macht, an denen Sie die Arbeit isolieren möchten. Dann können Sie dies als Abhängigkeit in einem neuen Projekt verwenden, das es implementiert. Fügen Sie in Ihrer Hauptanwendung einfach die richtigen Abhängigkeiten für diese Implementierungen hinzu (diesmal werden keine Maven-Module verwendet), und Sie sollten einsatzbereit sein. Schließlich enthält das Hauptanwendungsprojekt fast keinen Quellcode mehr, der in externen Projekten ausgeführt und über Abhängigkeiten geladen wird.

Sie müssen jedoch mit diesem Ansatz die gesamte Anwendung erneut bereitstellen, unabhängig davon, ob sich der Kern geändert hat oder nicht, da der Krieg statisch aus den Abhängigkeiten aufgebaut ist. Wenn Sie eine davon ändern, muss das Ganze erneut erstellt werden. Es klingt schlimmer als es tatsächlich ist. Tatsächlich werden nur die neuen Änderungen erstellt, der Rest ist im Grunde eine Kopie der vorherigen Gläser. Da sich jedoch alles in der Kriegsdatei befindet, muss es neu erstellt und der Server muss gestoppt und neu gestartet werden.

Wenn Sie weiter gehen müssen, werden die Dinge etwas komplizierter, wenn auch nicht unmöglich. Ich würde empfehlen, dass Sie sich mit OSGI befassen. Apache Felix könnte Ihnen den Einstieg erleichtern, obwohl es auch andere Implementierungen gibt. Auf diese Weise können Sie das externe Glas in die richtigen Plugins umwandeln. Sie erhalten viel mehr Kontrolle über den Laufzeit-Lebenszyklus der Komponenten, die die Tür für dynamisches Neuladen und Aktualisieren öffnen. Es werden jedoch wieder größere Änderungen an Ihrem Kern erforderlich sein, wahrscheinlich kein guter Ausgangspunkt. Wenn Sie jedoch ein Projekt haben, das gut getrennt ist und alle Teile wie gewünscht isoliert haben, kann dies ein logischer nächster Schritt sein, wenn das Starten und Stoppen der Anwendung bei der Aktualisierung ein großes Problem darstellt.

Der grundlegende Unterschied zwischen Modulen und Abhängigkeiten ist folgender:

  • Module werden im selben Quellbaum wie die Hauptanwendung gespeichert, idealerweise als Unterordner.
  • Abhängigkeiten können überall sein.

Die Bibel finden Sie hier .

Hoffe das hilft, viel Glück.

Newtopian
quelle
Das Bündeln von Modulen durch maven anstelle des Quellbaums löste eine Menge Fragen, die ich hatte. Können Sie mir bitte etwas über den Einsatz eines solchen Projekts erzählen? Einer der anderen Gründe, über die wir nachdenken, besteht darin, dass Entwickler an ihrem erforderlichen Modul arbeiten und die Änderungen in Echtzeit vornehmen können. Eine Sache, die wir vermeiden möchten, ist, den Anwendungsserver anzuhalten und neu zu starten, anders als für das Kernmodul. Ich kann mir vorstellen, dass 2 Module Code enthalten, der sich häufig ändert. Wir verwenden Tomcat als Anwendungsserver, der von Apache ausbalanciert wird. Vielen Dank.
Wir sind Borg
Maven-Module befinden sich häufig im selben Quellbaum wie die Hauptanwendung. Die Verwendung von Maven-Modulen außerhalb des Quellbaums ist komplizierter als es wirklich wert ist. Wenn Sie die Projekte außerhalb des Quellbaums hosten, wählen Sie normale unabhängige Projekte und verwenden Sie normale Abhängigkeiten.
Newtopian
Ich denke, wir werden Teile unseres Projekts direkt als Maven-Abhängigkeiten hinzufügen. Auf diese Weise können wir Teile des Projekts direkt bearbeiten. Ich hatte nur eine Frage: Wenn wir eines der Unterprojekte als Abhängigkeit in POM.xml hinzufügen, beispielsweise Version 2.0.0, und dann mit einigen Änderungen eine 2.0.1 des Moduls auf Sonatype pushen, wie können wir das? Weisen Sie das Core-Modul direkt an, auf 2.0.1 umzusteigen. Es reicht aus, nur die Datei POM.xml in ROOT.war zu ändern und das ROOT-Verzeichnis zu löschen. Die Hauptabsicht ist, den Server nicht anzuhalten. Vielen Dank.
Wir sind Borg
pom.xml hat nach der Erstellung des Krieges keinerlei Bedeutung, dh Tomcat (oder der von Ihnen verwendete Container) verwendet diese Datei nicht. Die Datei wird von Maven verwendet, um eine neue Kriegsdatei zu erstellen, die Sie wiederum auf dem Server bereitstellen müssen. Der Zyklus besteht also darin, den Code zu bearbeiten, eine JAR-Datei zu erstellen, die Version im POM des Krieges zu aktualisieren, eine Kriegsdatei zu erstellen und den Server mit der neuen Kriegsdatei zu aktualisieren. Einige Server unterstützen die erneute Bereitstellung im laufenden Betrieb, was jedoch im Allgemeinen bedeutet, dass die Anwendung für einige Sekunden ausgeschaltet wird.
Newtopian