Wie man mit Maven eine Konfigurationsdatei in den Ordner “META-INF/services” einer JAR-Datei einfügt

Lesezeit: 3 Minuten

Benutzer-Avatar
Matt Vukas

Ich arbeite an einem Java-Projekt in Eclipse, das mit Maven erstellt wird. Ich verwende recycelten Code aus einem älteren Projekt, und eine dieser Klassen sucht nach einer Datei in der META-INF/services Ordner des JAR mit einem bestimmten Namen und parst dann den Text dieser Datei. In diesem speziellen Beispiel sucht es nach einer Datei mit dem Namen einer Java-Schnittstelle und ruft dann den Klassennamen der Implementierung aus der Datei ab.

Also im Grunde versuche ich es zu tun Fügen Sie eine Datei in den Ordner “META-INF/services” der JAR mit einem Dateinamen (X) und einer Textzeile (Y) ein.. Ich vermute, dass dies mit Maven geschehen sollte, vielleicht durch Angabe eines Attributs in der POM-Datei, aber meine Recherchen haben nichts ergeben. Ich weiß, dass Sie keine META-Dateien fest codieren oder manuell eingeben sollen, daher bin ich mir nicht sicher, was ich hier tun soll.

  • Nach 8 Jahren ist es immer noch wahnsinnig schwierig, ein Maven-Projekt dazu zu bringen, den Ordner META-INF/services zu erkennen. Wenn überhaupt möglich.

    – Gerry

    13. September 2021 um 22:47 Uhr


Benutzer-Avatar
Brian

Erstellen Sie einen neuen Quellordner mit dem Standort src/main/resourceserstellen Sie dann Ihre META-INF/services Ordner darin und legen Sie Ihre vollqualifizierte Klassennamendatei (FQCN) ab. Dies sollte sie automatisch in die JAR-Datei kopieren. Also für Implementierungen einer Schnittstelle mit einem FQCN von com.acme.MyInterfacedu wirst haben:

Project
| src
| | main
|   | java
|     | [your source code]
|   | resources
|     | META-INF
|       | services
|         | com.acme.MyInterface

Beachten Sie, dass com.acme.MyInterface ist der Name der Datei, keine Verzeichnisstruktur wie bei einem Java-Paket. Der Name der Datei ist der FQCN der Schnittstelle, die Sie implementieren, und darin haben Sie den FQCN jeder Implementierung in einer eigenen Zeile, z.

com.example.MyInterfaceImpl
com.example.AnotherMyInterfaceImpl

Es ist erwähnenswert, dass dies auch für Gradle-Projekte mit den Standardquellsätzen gilt.

Sobald Sie dies getan haben, können Sie alle Implementierungen der Schnittstelle mit laden ServiceLoader:

ServiceLoader<MyInterface> loader = ServiceLoader.load(MyInterface.class);
for (MyInterface service : loader) {
    // Prints com.example.MyInterfaceImpl and com.example.AnotherMyInterfaceImpl
    System.out.println(service.class.getName());
}

Einige Dinge zu beachten:

  • Alle Implementierungen müssen einen No-Args-Konstruktor haben
  • Anwendungen, die Module oder benutzerdefinierte Classloader verwenden, müssen möglicherweise die Überladungen von verwenden ServiceLoader.load

Wenn diese Bedingungen für Sie nicht funktionieren, möchten Sie möglicherweise auf ein anderes System umsteigen, z. B. ein Framework im CDI-Stil wie Spring, EJB usw.

  • Was in den Dienstordner einfügen?

    – Ozan Kurt

    13. Juni 2016 um 3:02 Uhr

  • @OzanKurt Bitte werfen Sie einen Blick auf das Javadoc der ServiceLoader-Klasse: docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html

    – Puce

    13. Juni 2016 um 15:19 Uhr

  • @OzanKurt Hier ist der zugehörige Java-Trail. Kurz gesagt, der Name der Datei in META-INF/services lautet etwa so wie META-INF/services/com.acme.MyInterface und enthält jeden FQCN der Implementierungen in Ihrer Anwendung, jeweils in einer neuen Zeile, z com.example.MyInterfaceImpl

    – Brian

    13. Juni 2016 um 18:39 Uhr

  • Danke @Brian! Das hat mir sehr geholfen!

    – andrbmgi

    30. September 2020 um 14:41 Uhr

  • META-INF/services/com.acme.MyInterface oder META-INF/services/com/acme/MyInterface?

    – Gerry

    13. September 2021 um 22:49 Uhr

Standardmäßig sucht Maven nach Ressourcen unter:

src/main/resources

Also leg es an

src/main/resources/META-INF/services

  • Was in den Dienstordner einfügen?

    – Ozan Kurt

    13. Juni 2016 um 3:02 Uhr

Wenn Ihr Projekt keine Standardverzeichnisstruktur verwendet (oder Sie einfach alternative Ressourcenverzeichnisse haben möchten), können Sie alternativ angeben Ressourcenverzeichnisse manuell die POM-Datei.

Wenn zum Beispiel Ihre META-INF/services befindet sich in einem Ordner namens resources das sich im Stammverzeichnis Ihres Projektverzeichnisses befindet, könnte es wie folgt angeben:

<project>
...
  <build>
    ...
    <resources>
      <resource>
        <directory>resources</directory>
      </resource>
    </resources>
    ...
  </build>
  ...
</project>

Sie können dies verwenden, um mehrere Verzeichnisse anzugeben, indem Sie mehrere hinzufügen <resource> Elemente.

  • Was in den Dienstordner einfügen?

    – Ozan Kurt

    13. Juni 2016 um 3:02 Uhr

  • @OzanKurt Ich bin mir nicht sicher, was da reinkommt, aber ein Beispiel für eine Datei, die normalerweise in META-INF/services lebt, ist ein benutzerdefinierter CharsetProvider.

    – Robert Bartlett-Schneider

    14. Juni 2016 um 19:56 Uhr

  • Ich habe das bekommen, musste Anmerkungen hinzufügen. Vielen Dank

    – Ozan Kurt

    15. Juni 2016 um 0:33 Uhr

1245290cookie-checkWie man mit Maven eine Konfigurationsdatei in den Ordner “META-INF/services” einer JAR-Datei einfügt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy