and - maven compiler plugin java 9



Java 9+maven+junit: il codice di prova ha bisogno di module-info.java e dove metterlo? (2)

Diciamo che ho un progetto Java usando Maven 3 e junit. Ci sono le directory src/main/java e src/test/java che contengono rispettivamente le fonti principali e le fonti di test (tutto è standard).

Ora voglio migrare il progetto a Java 9. src/main/java content rappresenta il modulo Java 9; c'è com/acme/project/module-info.java aspetto approssimativo come questo:

module com.acme.project {
    require module1;
    require module2;
    ...
}

Cosa succede se il codice di prova ha bisogno di module-info.java ? Ad esempio, per aggiungere una dipendenza su alcuni moduli che è necessaria solo per i test, non per il codice di produzione. In tal caso, devo inserire module-info.java in src/test/java/com/acme/project/ dando al modulo un nome diverso. In questo modo Maven sembra trattare le fonti principali e le fonti di test come moduli diversi, quindi devo esportare i pacchetti dal modulo principale al modulo di test e richiedere pacchetti nel modulo di test, qualcosa del genere:

modulo principale (in src/main/java/com/acme/project ):

module prod.module {
    exports com.acme.project to test.module;
}

modulo di test (in src/test/java/com/acme/project ):

module test.module {
    requires junit;
    requires prod.module;
}

Questo produce

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project test-java9-modules-junit: Compilation failure: Compilation failure:
[ERROR] /home/rpuch/git/my/test-java9-modules-junit/src/test/java/com/acme/project/GreeterTest.java:[1,1] package exists in another module: prod.module

perché un pacchetto è definito in due moduli. Quindi ora devo avere diversi progetti nel modulo principale e nel modulo di test, il che non è conveniente.

Sento di seguire la strada sbagliata, tutto inizia a sembrare molto brutto. Come posso avere module-info.java suo codice di test, o come ottengo gli stessi effetti ( require , etc) senza di esso?

https://ffff65535.com


Aggiunta di alcuni dettagli.

In Java a partire da 9, un file jar (o una directory con classi) può essere messo su classpath (come prima) o sul percorso del modulo. Se viene aggiunto a classpath, le sue informazioni sui moduli vengono ignorate e non vengono applicate restrizioni relative ai moduli (cosa legge cosa, cosa esporta cosa, ecc.). Se, tuttavia, un jar viene aggiunto al percorso del modulo, viene considerato come un modulo, quindi le sue informazioni sui moduli vengono elaborate e verranno applicate ulteriori restrizioni relative ai moduli.

Attualmente (versione 2.20.1), maven-surefire-plugin può funzionare solo nel vecchio modo, quindi mette le classi in fase di test su classpath e module-path viene ignorato. Quindi, al momento, l'aggiunta di informazioni sui moduli a un progetto Maven non dovrebbe cambiare nulla con i test eseguiti usando Maven (con il plugin surefire).

Nel mio caso, la riga di comando è simile alla seguente:

/bin/sh -c cd /home/rpuch/git/my/test-java9-modules-junit && /home/rpuch/soft/jdk-9/bin/java --add-modules java.se.ee -jar /home/rpuch/git/my/test-java9-modules-junit/target/surefire/surefirebooter852849097737067355.jar /home/rpuch/git/my/test-java9-modules-junit/target/surefire 2017-10-12T23-09-21_577-jvmRun1 surefire8407763413259855828tmp surefire_05575863484264768860tmp

Le classi sotto test non vengono aggiunte come modulo, quindi sono su classpath.

Attualmente è in corso un lavoro in https://issues.apache.org/jira/browse/SUREFIRE-1262 (SUREFIRE-1420 è contrassegnato come duplicato di SUREFIRE-1262) per insegnare al plugin surefire di inserire il codice sotto test sul modulo sentiero. Una volta terminato e rilasciato, verranno considerate le informazioni sul modulo. Ma se faranno il modulo sottoposto a test per leggere automaticamente il modulo junit (come suggerisce SUREFIRE-1420), module-info (che è un descrittore del modulo principale) non dovrà includere un riferimento a junit (che è necessario solo per i test) .

Un curriculum:

  1. modulo-info deve solo essere aggiunto alle fonti principali
  2. per il momento, surefire ignora la nuova logica relativa al modulo (ma questo verrà modificato in futuro)
  3. (Quando i moduli funzioneranno sotto test infallibili) junit non avrà probabilmente bisogno di essere aggiunta alle informazioni sul modulo
  4. (quando i moduli lavoreranno sotto test infallibili) se alcuni moduli sono richiesti dai test (e solo da essi), possono essere aggiunti come dipendenza solo compilazione (usando require static ), come suggerito da @nullpointer. In questo caso, il modulo Maven dovrà dipendere da un artefatto che fornisce quel modulo di solo test usando un ambito compilabile (non di prova) che non mi piace molto.

Il sistema del modulo non distingue tra codice di produzione e codice di test, quindi se si sceglie di modulare il codice di test, il prod.module e il test.module non possono condividere lo stesso pacchetto com.acme.project , come descritto nelle specs :

Non interferenza : il compilatore Java, la macchina virtuale e il sistema di runtime devono garantire che i moduli che contengono pacchetti con lo stesso nome non interferiscano tra loro. Se due moduli distinti contengono pacchetti con lo stesso nome, dal punto di vista di ciascun modulo, tutti i tipi e i membri di quel pacchetto sono definiti solo da quel modulo. Il codice in quel pacchetto in un modulo non deve essere in grado di accedere a tipi o membri privati ​​del pacchetto in quel pacchetto nell'altro modulo.

Come indicato da Alan Bateman, il plug -in del compilatore Maven utilizza --patch-module e altre opzioni fornite dal sistema del modulo durante la compilazione del codice nell'albero src / test / java, in modo che il modulo sotto test sia aumentato con le classi di test. E questo viene fatto anche dal plug-in Surefire quando si eseguono le classi di test (consultare Supporto per eseguire test unitari in moduli Java 9 denominati ). Ciò significa che non è necessario inserire il codice di prova in un modulo.





java-module