2017-03-26 69 views
7

Ja eksperymentuje z Java 9 i patrząc na następujących scenariuszach:W języku Java 9, dlaczego kolizje pakietów są traktowane nieco inaczej w niektórych przypadkach?

Experiment 1

  • moduł A
  • moduł B
  • zarówno zadeklarować non pakiet pusty nazwie com.foo, ale nie eksportuj go.
  • oba są wymagane przez 3rd modułem C

uruchomiony główny z 'C' daje błąd wykonania:

java.lang.RuntimeException: Pakiet com.foo zarówno w module B i modułem

Eksperyment 2

samo jak wcześniej, ale tym razem zarówno com.foo eksportu.

wyniku realizacji głównej z C:

java.lang.module.ResolutionException: Moduły B i A pakiet eksport com.foo do modułu C

Eksperyment 3

samo jako 2, ale tym razem zadeklarowałem pakiet com.foo w module C.

Teraz pojawia się błąd kompilacji: Błąd: (4, 1) java: moduł C odczytuje pakiet com.foo z obu A i B

Dlaczego dwa pierwsze przypadki nie zostały złapane podczas kompilacji? Czy istnieją właściwości środowiska wykonawczego, o których nie wiem, że uniemożliwiają rozwiązanie przed uruchomieniem programu?

Ponadto, jeśli chodzi o komunikaty o błędach: w jaki sposób komunikat o błędzie w eksperymencie 2 jest lepszy niż ten podany w eksperymencie 1. Nie jest tak, jeśli jeden z modułów nie eksportuje go, aby wynik końcowy będzie inaczej. Innymi słowy, na czym polegało tworzenie różnych komunikatów o błędach?

+2

* "Dlaczego dwa pierwsze przypadki nie zostały złapane podczas kompilacji?" * Ponieważ kompilator nie przeszedł tej * rozszerzonej * analizy pakietów, które nie są bezpośrednio używane przez moduł C. Dlaczego? Tylko # 3 powoduje, że kompilator nawet patrzy na pakiet 'com.foo'. Teraz, jeśli twoje # 2 próbowało "zaimportować" klasę z 'com.foo', prawdopodobnie przegrałoby kompilację, ponieważ kompilator musiałby dowiedzieć się, z którego modułu go pobrać. – Andreas

+1

@Andreas, nie wiem o tym - po tym wszystkim ten sam pakiet jest eksportowany do obu modułów. Praktycznie oddaję go kompilatorowi na srebrnej tabliczce :). Nawet jeśli byłby to dłuższy łańcuch - biorąc pod uwagę słowa kluczowe - nie jest to skomplikowany obliczeniowo problem. Już tworzą wykres czytelności, więc wszystko jest na zewnątrz. – Vitaliy

+1

Więc nie wykonali dodatkowej (opcjonalnej) pracy. Jeśli uważasz, że to ważne, zamiast pytać * "dlaczego?" *, Proponuję złożyć wniosek o ulepszenie. – Andreas

Odpowiedz

7

Eksperyment nr 2 i nr 3 są problemami z pakietem podzielonym i powinny to być błędy zarówno podczas kompilacji, jak i uruchamiania. Dla numeru 2 nie mogę stwierdzić z twojego wpisu, dlaczego nie widzisz błędu kompilacji podczas kompilacji C. Powinieneś zobaczyć błąd z tekstem takim jak "moduł C czyta pakiet com.foo z obu A i B".

Eksperyment nr 1 to prawdopodobnie A, B i C na ścieżce modułu aplikacji, w której nie wszystkie mogą mieszkać w tej samej przestrzeni nazw (ten sam program ładujący klasy) ze względu na nakładające się pakiety. Komunikat o błędzie został nieco poprawiony w ostatnich kompilacjach.

Należy pamiętać, że eksperymenty tutaj zostały omówione w wielu wątkach na temat jigsaw-dev i może to być lepsze miejsce do zadawania pytań i doświadczeń, przynajmniej podczas gdy JDK 9 jest jeszcze w fazie rozwoju.

+0

Dzięki Alan. Jeśli dobrze rozumiem, powinienem otrzymywać błędy kompilacji we wszystkich przypadkach. W razie potrzeby ponownie sprawdzę i ponownie opublikuję to na liście mailingowej. Teraz, gdy o tym myślę, przeprowadzam eksperymenty w wersji EA Intellij. Możliwe, że także czegoś brakuje. – Vitaliy

+2

Eksperyment nr 1 nie spowoduje błędu kompilacji, pozostałe dwie powinny. # 1 będzie działał w czasie wykonywania, gdy moduły będą ładowane do warstwy podrzędnej, a nie do ścieżki modułu aplikacji. –

+1

Fajnie, gdy otrzymasz odpowiedź od @AlanBateman na SO! – Eugene