Softwareentwicklung: Minimale Unterstützung für das Java-Modulsystem

Das Java Module System ist in der Entwicklung von Anwendungen und Bibliotheken noch immer eine selten genutzte Funktion. Dabei ist der Einstieg oft leicht.

In Pocket speichern vorlesen Druckansicht 1 Kommentar lesen
Lesezeit: 3 Min.
Von
  • Hendrik Ebbers

In den letzten Jahren hat man immer wieder viele unterschiedliche Meinungen zum Java-Modulsystem gehört. Während viele Entwicklerinnen und Entwickler der standardisierten Möglichkeit zur Definition von Modulen positiv entgegenstehen, gibt es viele kritische Meinungen, die der Definition beispielsweise fehlende Features wie die Unterstützung von Versionen ankreiden. Diese Diskussion möchte ich hier allerdings überhaupt nicht aufmachen. Ich selber sehe viele Vorteile im Modulsystem und kann verstehen, dass vor allem Framework und Bibliotheksentwickler das Ganze nutzen (wollen).

Neuigkeiten von der Insel - Hendrik Ebbers

Hendrik Ebbers (@hendrikEbbers) ist Java Champion, JCP Expert Group Member und wurde mehrfach als Rockstar-Speaker der JavaOne ausgezeichnet. Mit seinem eigenen Unternehmen Open Elements hilft Hendrik aktuell den Hedera Hashgraph zu gestalten und dessen Services der Öffentlichkeit zugänglich zu machen. Hendrik ist Mitgründer der JUG Dortmund sowie der Cyberland und gibt auf der ganzen Welt Vorträge und Workshop zum Thema Java. Sein Buch "Mastering JavaFX 8 Controls" ist 2014 bei Oracle Press erschienen. Hendrik arbeitet aktiv an Open Source Projekten wie beispielsweise JakartaEE oder Eclipse Adoptium mit. Hendrik ist Mitglied des AdoptOpenJDK TSC und der Eclipse Adoptium WG.

Ein großer Nachteil ist hier allerdings, dass eine (transitive) Abhängigkeit, die in keiner Weise auf das Java Modulsystem angepasst ist, möglicherweise nicht zu den Definitionen und Einschränkungen des Modulsystems passt und somit nicht zum Modul-Path hinzugefügt werden kann. Das Java-Modulsystem erstellt automatisch ein Modul für jedes JAR, das es auf dem Modul Path findet. Hierbei kann es zu einigen Problemen kommen, die man allerdings oft durch kleine Anpassungen in einer Bibliothek beheben kann.

Diese Probleme möchte ich in mehreren Posts einmal genauer betrachten und mögliche Lösungen aufzeigen. Dieser Beitrag geht auf die Nutzung und Definition von automatischen Modulen einmal genauer ein.

Eine wichtige Definition des Modulsystems ist, dass jedes Modul einen eindeutigen Namen benötigt. Hierbei wird zwischen explizit deklarierten Modulen, die über eine module-info.java verfügen, und automatischen Modulen, die implizit deklariert werden, unterschieden. Weitere Infos lassen sich der JavaSE Spec entnehmen. Wenn man in seinem Projekt nicht die Vorteile des Modulsystems durch die Nutzung einer module-info.java nutzen möchte, reicht es völlig aus, wenn man die eigene Bibliothek als automatisches Modul definiert.

Die einzige Voraussetzung hierfür ist, dass das Modul über einen eindeutigen Namen verfügt. Zwar kann Java für JARs auf dem Module Path zur Not sogar einen Namen aus dem Namen des JAR extrahieren, was aber ganz klar nicht empfohlen ist. Vor allem, da die Definition eines Namens für ein automatisches Modul wirklich sehr einfach ist. Es muss lediglich die Automatic-Module-Name Property in der MANIFEST.MF des JARs definiert werden. Wenn Maven oder Gradle als Buildtool genutzt werden, kann man dies über ein Plug-in sogar voll automatisiert erstellen.

Wie man im folgenden Beispiel sehen kann, muss bei einem Maven Build nur das maven-jar-plugin entsprechend konfiguriert werden:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.3.0</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Automatic-Module-Name>com.example.lib</Automatic-Module-Name>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

In Gradle lässt sich das Ganze einfach durch Nutzung des Java-Library-Plug-ins umsetzen, das Bestandteil jedes Java Builds sein sollte. Eine ausführliche Dokumentation zum Einsatz in Gradle kann man hier finden, während der folgende Code eine einfache Einbindung in ein Projekt zeigt:

tasks.jar {
    manifest {
        attributes("Automatic-Module-Name" to "com.example.lib")
    }
}

Da die Änderungen wirklich sehr einfach sind, eignen sie sich auch hervorragend, um das Ganze für Open Source Libraries als Pull Request anzubieten. In einem Beispiel habe ich einen PR zur Definition eines Automatic-Module-Name zu einer Open Source-Java-Bibliothek hinzugefügt. Vielleicht liest ja eine oder ein Open Source Developer mit und erstellt für eine solche Umstellung der eigenen Bibliotheken ein „Good First Issue“, das beispielsweise zum Hacktoberfest von Neulingen umgesetzt werden kann.

iX-Workshop: Skalierbare Java-Anwendungen mit Virtual Threads

Mit der Veröffentlichung von Java 21 gehören Virtual Threads sicherlich zu den aufregendsten Entwicklungen der letzten Jahre. Diese kleinen Helfer machen die Verarbeitung von Aufgaben nebenläufiger, indem sie unzählige Client-Anfragen gleichzeitig bedienen können, ohne an die Ressourcengrenzen des Betriebssystems oder der Hardware zu stoßen.

Wie man sich das zunutze macht, wie eine Architektur dafür strukturiert sein muss und welche Fallstricke und Sonderfälle zu beachten sind, erklärt Marwan Abu-Khalil in seinem Workshop Skalierbare Java-Anwendungen mit Virtual Threads am 5. Februar 2024.

(rme)