2017-09-18 33 views
9

Kiedy kompiluję moduł, który zależy od innych modułów, które wcześniej skompilowałem, muszę podać opcję --module-path <directory>. To sprawia, że ​​moduły zależą od widoczności.Czy można mieszać ścieżkę -klasę i --moduł-ścieżkę w javac (JDK 9)?

Ale jednocześnie chciałbym, aby niektóre niemagnetyczne pliki Jar były widoczne. Jeśli jednak nie zrobisz z nich automatycznych modułów i po prostu podasz --class-path some.jar tuż obok --module-path <directory>, wydaje się, że javac zignoruje claspath i wyrzuci "package yyy not found" oraz inne błędy "nie znaleziono".

mogę zrozumieć, że za pomocą --class-path i --module-path w tym samym (kompilacji) czas jest nielegalne, ale javac nie ostrzega mnie przed nim w jakikolwiek sposób.

+0

Możliwe jest połączenie dwóch, czy możesz udostępnić minimalny przykład, który możemy zweryfikować? –

+0

* Rozumiem, że używanie --class-path i --module-path w tym samym (kompilacji) czasie jest nielegalne, * dlaczego tak jest? – nullpointer

+5

Mieszanie jest całkowicie legalne.Jednak słoiki modułowe nie mogą odwoływać się do niem modułowych słoików w ścieżce klas. Moduły automatyczne (słoje niemodułowe na pokrywie modułowej) pełnią funkcję mostu: słoiki modułowe _can_ odwołują się do nich, a moduły automatyczne mogą odczytywać ścieżkę klas. –

Odpowiedz

14

Można używać ścieżki klas i ścieżki modułu równolegle, ale istnieje kilka szczegółów do rozważenia.

Zależność modułu Ścieżka ~> Ścieżka klasy moduły

Jawne (słoiki z deskryptora modułu na ścieżce modułu) nie może odczytać moduł nienazwanej (JAR na ścieżce klasy) - to było zrobione celowo, aby zapobiec modułowe JARs od zależności od "chaosu ścieżki klasowej".

Ponieważ moduł musi wymagać wszystkich swoich zależności, a te mogą być spełnione tylko przez inne nazwane moduły (tj. Nie JARy na ścieżce klasy), wszystkie zależności modułu JAR muszą zostać umieszczone na ścieżce modułu. Tak, nawet nie modułowe pliki JAR, które następnie zostaną przekształcone w automatic modules.

Interesującą rzeczą jest to, że moduły automatyczne może odczytu modułu nienazwany, więc ich zależności mogą iść na ścieżce klasy.

Zależność klasy Path ~> Moduł Ścieżka

Jeśli skompilować kod niemodularnego lub uruchomić aplikację z niemodularnego JAR, system moduł jest nadal w grze i dlatego kod niemodularnego nie wyrazić dowolny zależności, nie rozwiąże modułów ze ścieżki modułu.

Jeśli kod niemodularny zależy od artefaktów na ścieżce modułu, należy dodać je ręcznie za pomocą the --add-modules option. Niekoniecznie wszystkie z nich, tylko te, na których bezpośrednio polegasz (system modułowy pobierze przechodnie zależności) - lub możesz użyć ALL-MODULE-PATH (sprawdź powiązany post, objaśnia to bardziej szczegółowo).

+5

Nicolai - twoja odpowiedź jest poprawna, ale myślę, że mogłaby być rozszerzona, aby wskazać, że opcja '--add-modules' może być potrzebna, aby zapewnić, że moduły wymagane przez kod ścieżki klasy zostaną rozwiązane. Pierwotne pytanie zadaje pytanie, dlaczego javac kończy się niepowodzeniem i zakładam, że dzieje się tak dlatego, że on/ona kompiluje kod na ścieżce klasy, odwołując się do klas w modułach na ścieżce modułu i po prostu potrzebuje '--add-modules', aby upewnić się, że moduły zostały rozwiązane . –

+0

Myślę, że OP próbuje skompilować modułowy kod z niemodularną zależnością - tak czy inaczej, dodałem także inny kierunek, żeby się upewnić. – Nicolai

9

wierzę używając opcji --classpath i --module-path jednocześnie jest nie nielegalne. Możliwe jest użycie obu jednocześnie, nawet jeśli nie określisz bezpośrednio ścieżki klasy jako domyślnej do bieżącego katalogu.

Szczegóły z komunikatem javac -help i javac tools docs -

--module-path <path>, -p <path> 

Określ, gdzie znaleźć moduły aplikacji

--class-path <path>, -classpath <path>, -cp <path> 

Określ, gdzie znaleźć pliki klas użytkowników i procesorów adnotacji

Jeśli --class-path, -classpath lub -cpnie zostały określone, wówczas ścieżka klasy użytkownika jest katalogiem bieżącym .


Edit: Dzięki @MouseEvent, prawdopodobnie stracili część w pytaniu

Jednak jeśli nie robią im automatyczne moduły i po prostu określić - Ścieżka-ścieżka.jar tuż obok --module-ścieżka, wtedy javac wydaje się zignorować claspath i wyrzuca "pakiet yyy nie znaleziony" i inne błędy "nie znaleziono".

Jeśli nie uczynić je automatycznie, jest traktowany jako Module System's unnamed module i -

Nazwany moduł może nie, w rzeczywistości, nawet deklarować zależność od modułu bezimiennego . To ograniczenie jest zamierzone, ponieważ zezwolenie na moduły o nazwach zależą od arbitralnej zawartości ścieżki klasy, co uniemożliwiłoby niezawodną konfigurację.

Ponadto nienazwane eksportu modułu wszystkich swoich pakietów stąd kod W automatycznych modułów będzie w stanie uzyskać dostęp do wszelkiego rodzaju publicznych załadowany ze ścieżki klasy.

Ale automatyczny moduł, który korzysta z typów z ścieżki klasy , nie może wystawiać tych typów na jawne moduły, które zależą od niego, ponieważ jawne moduły nie mogą zadeklarować zależności na module bez nazwy.

Jeśli kod w wyraźnej modułu com.foo.app odnosi się do rodzaju publicznym w com.foo.bar, np, a podpis tego typu odnosi się do rodzaju w jednym z plików JAR nadal na ścieżce klasy, a następnie kod w com.foo.app nie będzie mógł uzyskać dostępu do tego typu, ponieważ com.foo.app nie może zależeć od modułu bez nazwy.

Można temu zaradzić poprzez traktowanie com.foo.app jako automatyczny moduł chwilowo tak, że jego kod może uzyskać dostęp do typów ze ścieżki klasy, do czasu odpowiedniego pliku JAR na ścieżce klasy mogą być traktowane jako automatyczny moduł lub przekonwertowany na jawny moduł.

+1

Nie mówiąc już o tym, czy jest to legalne ... Cała koncepcja nienazwanego modułu dotyczy słoików w ścieżce klas, a jawne moduły nie mają do nich dostępu. – Mordechai

+0

@MouseEvent Cóż, to prawda. Wydaje mi się, że wcześniej tę część pytania przeoczyłem i właśnie odpowiedziałem na tytuł. Edytowane, aby uwzględnić to również. Dzięki :) – nullpointer