2016-12-28 50 views
15

Obecnie testuję, aby przeprowadzić migrację aplikacji Java 8 do Javy 9/Jigsaw, używając jdk-9 + 149.Gdzie należy umieścić testy jednostkowe podczas migracji projektu Java 8 do Jigsaw

Projekt został rozplanowany w standardowej strukturze katalogów Maven, to znaczy mający src/main/java, src/test/java itp

Jak tylko dodać module-info.java do src/main/java, Maven-compiler-plugin zawiedzie rzuca NullPointerException. Dzieje się tak, ponieważ spodziewa się znaleźć informacje o module dla katalogu test. Tak więc, o ile widzę, opcje są następujące:

  • utrzymywać klasy testowe w oddzielnym module, co oznacza, że ​​mogą uzyskać dostęp tylko do wyeksportowanych pakietów modułu głównego.
  • przenieść klasy testowe do modułu głównego, wraz ze źródłami, co oznacza, że ​​główny moduł wymaga zależności testowych.

Oczywiście żadna z tych opcji nie wydaje się pożądana, dlatego zakładam, że istnieje zalecany sposób testowania modułów Jigsaw w projekcie Maven. Nie mogłem znaleźć ani zaleceń, ani przykładów.

EDIT: Dodawanie pewne informacje, że nie uważa istotne podczas księgowania pytanie (przepraszam)

+0

jakie źródło i miejsce docelowe określono jako konfigurację wtyczki maven-compiler? Proszę również udostępnić ślad stosu dla NPE, aby wyjaśnić błędy. – nullpointer

+0

Przepraszamy, dodaliśmy trochę więcej informacji. Ale w zasadzie NPE było tylko symptomem, który doprowadził mnie do faktycznego pytania, w jaki sposób poradziłbym sobie z testami w ogóle. – peterp

Odpowiedz

9

Obsługa Maven dla Javy 9 w ogóle, a testy w szczególności wciąż są pod Rozwój - wiele rzeczy działa, ale inne nie. Nie widząc śladu stosu dla NPE, jest to oczywiście spekulacja, ale zakładam, że jesteś ran into this error.

Bardziej ogólnie, wciąż trwa dyskusja nad tym, jak dokładnie testy jednostkowe będą działać z Jigsaw - nawet on the Jigsaw mailing list.

Oto moja opinia w tej sprawie:

  1. Jak można zauważyć, putting testy do osobnego modułu oznaczałoby, że tylko typy publiczne w eksportowanych pakietów byłyby sprawdzalne, co na pewno nie jest mało. Może istnieć obejście, ale te wymagają edycji deklaracji modułu (kod źródłowy; module-info.java) lub deskryptora (kod bajtowy, module-info.class) w locie lub dodania tonów flag linii poleceń --add-exports do poleceń javac i java kompilujących i uruchamiających testy . Żadne z nich nie brzmi szczególnie zabawnie, szczególnie jeśli chcesz to zrobić ręcznie.

  2. Przenoszenie testów do drzewa źródłowego jest również złym pomysłem z oczywistych powodów, między innymi to, że utworzenie JARa bez testów wymagałoby wtedy dużo manipulowania.

  3. Inną opcją jest użycie opcji --patch-module, która umożliwia dodawanie plików class lub zawartości JAR do istniejącego modułu.W ten sposób krok testCompile może utworzyć plik JAR zawierający pliki testowe źródła i. Niestety, jeśli nie manipuluje deklaracją/opisem modułu jak opisano powyżej, wynikowy plik JAR nie może zostać wykonany bez dodawania krawędzi odczytu z java --add-reads dla zależności testowych. Nadal, lepiej niż powyżej.

  4. Jako środek ostateczny, istnieją sposoby, aby produkcja JAR traktować jak zwykły JAR zamiast jako moduł. Najłatwiej byłoby prawdopodobnie zrzucić go na ścieżce klasy razem z testowym JARem. W ten sposób wszystko działa tak, jak w Javie < 9. Niestety to złamie kod, który wykorzystuje funkcje przy założeniu, że znajduje się wewnątrz nazwanego modułu (np. Pewne rodzaje interakcji z interfejsem API do refleksji).

Osobiście uważam 3. za najlepszą spośród powyższych opcji. Nie wymagałoby to żadnych zmian w układzie projektu i jedynie względnie niewielkich dodatków do poleceń javac i java.

+0

Dzięki za opracowaną odpowiedź, Nicolai. Dobrze widzieć temat będący przedmiotem dyskusji. Zrobię kilka testów z opcjami 3 i 1, nie wiedziałem, że można dodać eksport w wierszu poleceń. – peterp

+2

Cieszę się, że mogę pomóc. Pamiętaj, aby zgłosić się z powrotem, czy to tutaj, z postu, lub pocztą do układanki-dev. W tym momencie wszystkie informacje zwrotne oparte na rzeczywistych eksperymentach są cenne. – Nicolai

+0

Zdecydowanie będę :) btw: [Komentarz Roberta] (http://stackoverflow.com/questions/41366582/where-to-----------------)-migrating-a-java-8-project-to -jigsaw # comment69959520_41370766) poniżej również wskazuje, że opcja 3 może być sposobem na przejście – peterp

6

Musisz przynajmniej używać programu maven-compiler-plugin 3.6.0, aby mieć wsparcie dla układanki. Jednak od czasu kompilacji +148 zmieniła się struktura binarna pliku klasy, więc wtyczka nie może wyodrębnić nazwy modulu jak poprzednio (nazwa modułowa jest wymagana, aby móc skompilować testy). Pracuję nad poprawką, ale prawdopodobnie zależę od nowej wersji ASM.

AKTUALIZACJA: maven-compiler-plugin-3.6.1 został zwolniony, więc wsparcie dla układanki zostało przywrócone.

+0

Dzięki, Robert. Nie widziałem tego jako problemu z mavenami (z wyjątkiem oczywiście NPE, który nie jest pomocny) - ponieważ kod testowy w rzeczywistości nie jest modułowy. Więc nawet jeśli kod zostanie skompilowany i przejdzie do modułu "bez nazwy", testowanie rzeczy z modułu src nie będzie działać zgodnie z oczekiwaniami. Ale czytając Nicolai [anwer] (http: // stackoverflow.com/a/41367802/1006823) Rozumiem, że to wciąż jest przedmiotem dyskusji. – peterp

+2

FYI: http://maven.apache.org/plugins/maven-compiler-plugin/xref/org/apache/maven/plugin/compiler/TestCompilerMojo.html#L259 pokazuje, że wtyczka maven-compiler używa rozwiązania 3 z @Nicolai, który został zweryfikowany jako poprawne podejście niektórych deweloperów zespołu układającego się. –

+0

Myślę, że miałem nieporozumienie - po tym, jak znalazłem czas, aby dokładniej przyjrzeć się twojemu łączu, zauważyłem, że to jest faktyczne kod v3.6.0 (myślałem, że jest to przyszłe wdrożenie, które ma zostać wydane). Tak więc AFAICS (nie wiedząc o wewnętrznych elementach Mavena) wygląda na to, że powinienem móc uruchamiać testy (bez deskryptora modułu) przeciw moim modułowym źródłom (z deskryptorem modułu), gdyby nie ten NPE. Jeśli tak, powinna istnieć możliwość samodzielnego zbudowania wtyczki dla mojego kompilatora, aby mogła działać w celach testowych. Jaka byłaby oczekiwana wartość zwrotu funkcji getModuleName? – peterp

2

Jak już suggested here korzystając z zaktualizowaną wersję maven-compiler-plugin: 3.7.0 powinna pomóc rozwiązać ten problem: -

<plugins> 
    <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>3.7.0</version> 
     <configuration> 
      <source>9</source> 
      <target>9</target> 
      <compilerArgument>-Xlint:all</compilerArgument> 
     </configuration> 
    </plugin> 
</plugins> 

Gdzie można umieścić swoje testy jednostkowe w tym samym katalogu, co kiedyś było przed modularyzacją. Oto sample project ode mnie, który jest oparty na JDK9 i Maven3 +. Projekt opiera się na strukturze katalogów jak przedstawiony na zrzucie ekranu: -

enter image description here

i post to wszystko co musisz zrobić, to wykonać testy za pomocą polecenia:

mvn test 

z katalogu głównego projekt, aby znaleźć testy, byłby wykonywany jak zwykle.