2016-10-06 2 views
20

HintergrundUnterstützt das Java 9 Module System optionale Abhängigkeiten?

In Maven kann ein Artefakt eine Abhängigkeit mit

<optional>true</optional> 

erklären, was bedeutet, dass die Abhängigkeit nicht erforderlich, kann aber, falls vorhanden verwendet werden.

The State of the Module System scheint anzugeben, dass ein Modul nur Module lesen kann, die es benötigt.

Fragen

  • das Java 9 Modulsystem unterstützt in der Tat nicht optionale Abhängigkeiten?
  • Warum nicht?
  • Welche Alternativen zu optionalen Abhängigkeiten bietet das Java 9-Modulsystem?

Use Case

Ich habe einen Rahmen, die verschiedenen Bibliotheken integriert, die nicht von einer Anwendung verwendet werden können oder nicht. Derzeit ist dieses Framework ein einzelnes JAR, das den Klassenpfad widerspiegelt, um den Integrationscode für fehlende Bibliotheken zu überspringen.

Ich denke, wir könnten dies in ein separates Modul für jede Konfiguration aufteilen, aber dies würde eine kombinatorische Explosion in der Anzahl der JARs verursachen, weil wir nicht nur eine separate JAR für jede optionale Abhängigkeit benötigen, sondern auch eine separate JAR für die meisten Paare von optionalen Abhängigkeiten ...

Antwort

16

Ja, optional dependencies are supported. Zitiert aus the original proposal:

die Sprache des Moduls Erklärungen Verlängern der static Modifikator zu ermöglichen, auf einer requires Richtlinie verwendet werden, mit den folgenden Bedeutungen:

  • Beim Kompilieren, requires static M drückt eine obligatorische Abhängigkeit . Es ist ein Fehler, wenn ein passendes Modul nicht unter den beobachtbaren Modulen gefunden und aufgelöst werden kann.

  • In den Phasen nach der Kompilierzeit gibt requires static M eine optionale Abhängigkeit aus. Das Modulsystem wird die beobachtbaren Module während der Auflösung nicht nach einem geeigneten Modul durchsuchen, aber wenn das resultierende Moduldiagramm ein geeignetes Modul enthält, wird es die geeignete Lesbarkeitskante hinzufügen, bevor die üblichen Plausibilitätsüberprüfungen nach der Auflösung durchgeführt werden. [...]

So eine hypothetische Moduldeklaration des Formulars

module joda.beans { 
    requires static joda.collect; 
    ... 
} 

würde sicherstellen, dass die joda.collect Modul bei der Kompilierung zur Verfügung steht, so dass der Code in dem joda.beans-Modul, das auf joda.collect verweist kann ohne viel Aufwand zusammengestellt werden. Es kann jedoch nicht garantiert werden, dass joda.collect zur Verbindungszeit oder zur Laufzeit verfügbar ist.

(In der Zwischenzeit official documentation was created for that feature.)

schrieb ich a demo dafür. Die interessante Leckerbissen sind die module-info.java des Moduls die optionalen Abhängigkeiten deklarieren ...

module org.codefx.demo.advent { 
    // list the required modules 
    requires org.codefx.demo.advent.calendar; 
    // with 'static' the factories are only required at compile time; 
    // to be present at run time either other modules most require them 
    // or they must be added with the '--add-modules' command line option 
    requires static org.codefx.demo.advent.factory.chocolate; 
    requires static org.codefx.demo.advent.factory.quote; 
} 

... und den Code innerhalb des gleichen Moduls, die Typen von seiner optionalen Abhängigkeiten zugreifen möchte. Es hat sich so geschrieben, dass es gnädig schlägt fehl, wenn die Typen ChocolateFactory und/oder QuoteFactory fehlen:

private static List<SurpriseFactory> createSurpriseFactories() { 
    return Stream.of(
      createChocolateFactoryIfAccessible(), 
      createQuoteFactoryIfAccessible()) 
      .flatMap(Optional::stream) 
      .collect(toList()); 
} 

private static Optional<SurpriseFactory> createChocolateFactoryIfAccessible() { 
    try { 
     return Optional.of(new ChocolateFactory()); 
    } catch (NoClassDefFoundError er) { 
     return Optional.empty(); 
    } 
} 

private static Optional<SurpriseFactory> createQuoteFactoryIfAccessible() { 
    try { 
     return Optional.of(new QuoteFactory()); 
    } catch (NoClassDefFoundError er) { 
     return Optional.empty(); 
    } 
} 

Schließlich kann die Befehlszeile festgelegt werden, welche Module die App startet mit:

$java \ 
    --add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \ 
    -p mods -m org.codefx.demo.advent 

Es ist natürlich auch möglich, dass andere Module sie nicht optional benötigen, was die JVM zwingt, sie in den Modulgraphen aufzunehmen.

+1

Zukünftige Referenz: Wissen Sie, ob der optionale Abhängigkeitsvorschlag tatsächlich zur endgültigen Version gemacht wurde? – Lii

+2

Es gibt noch keine endgültige Version (Java 9 für Juli 2017 geplant), aber es ist immer noch Teil der EA-Builds und die Chance, dass es an der Grenze auf Null herausgenommen wird. – Nicolai

Verwandte Themen