Mit der Veröffentlichung von Java 11 als Long-Term-Support-Version hält das Java Platform Module System (JPMS) endgültig Einzug in die Realität eines jeden Java-Entwicklers. Grund genug, die Möglichkeiten des JPMS in einem praxisorientierten Beitrag zu betrachten.
Dieser Artikel geht von rudimentärer Vertrautheit mit den Begrifflichkeiten rund um das JPMS aus. Im Fokus steht die Migration einer kleinen Beispielanwendung hin zu einer modularisierten Applikation unter Verwendung des Java Platform Module System (JPMS).
Die Domäne des hier vorgestellten Beispiels ist bewusst einfach gehalten: Unsere Anwendung durchsucht einen übergebenen Suchtext nach einem Suchwort und liefert dann als Ergebnis Indices zu allen exakten Aufkommen des Suchworts innerhalb dieses Suchtexts.
Zur Lösung dieses Problems implementiert die Anwendung zwei String-Matching-Algorithmen, die unterschiedliche Charakteristiken aufweisen:
- einen Brute-Force-basierten Ansatz, der insbesondere auf umfangreichen Textkörpern keine gute Performanz zeigt, und
- einen fortgeschrittenen Ansatz mit dem Algorithmus nach Knuth, Morris und Pratt, der seine Stärken bei umfangreichen Textkörpern ausspielt.
Die Anwendung implementiert ein einfaches CLI. Ein Benutzer kann das CLI durch drei Pflichtargumente parametrieren: die Kennung eines ausgewählten Algorithmus (naive für den Brute-Force-Ansatz, kmp für den Knuth-Morris-Pratt-Algorithmus), den Suchtext und das Suchwort.
Struktur der Beispielanwendung
Die Anwendung ist mit Java 8 implementiert und wird mit Apache Maven gebaut. Der Quelltext liegt in zwei Maven-Modulen vor (Abb. 1). Wann immer lediglich von einem Modul die Rede ist und nicht explizit von einem Maven- oder Java-Modul, ist der Begriff synonym zu verstehen.
- matchers-core beinhaltet das Java API für die String-Matching-Algorithmen und die Implementierungen des Brute-Force-Algorithmus und des Knuth-Morris-Pratt-Algorithmus.
- matchers-cli referenziert matchers-core und implementiert das CLI.

Abb. 1: „matchers-core“ definiert das API und stellt konkrete Implementierung bereit, „matchers-cli“ bietet eine CLI-Anwendung auf dessen Basis an
Das Maven-Modul matchers-cor stellt sowohl die öffentliche Schnittstelle als auch die Implementierungen bereit. Die Methode match konsumiert einen Textkörper (vgl. Methodenargument haystack) und ein Suchwort (vgl. Methodenargument needle) und liefert alle Indices zu den Vorkommnissen des Suchworts als List <Integer>. Dieses Interface ist in der aktuellen Lösung im Package net.mguenther.matchers lokalisiert. Ko-lokalisiert mit dem Interface sind die zuvor genannten Algorithmen in den Klassen BruteForceMatcher und KnuthMorrisPrattMatcher (Abb. 2).
Listing 1 zeigt, wie die Auflösung des Algorithmus in Klasse MatchersCli in der Beispielanwendung implementiert ist.
Matcher matcher = null; switch (algorithm) { case "kmp": System.out.println("Using Knuth-Morris-Pratt matcher"); matcher = new KnuthMorrisPrattMatcher(); break; case "naive": default: System.out.println("Using Brute-Force matcher"); matcher = new BruteForceMatcher(); } List<Integer> matchingPositions = matcher.match(haystack, needle);
Defizite
Das grundlegende Problem, mit dem wir uns bei diesem Lösungsansatz konfrontiert sehen, liegt in den Sichtbarkeits- und Zugriffsregeln von Java.