Dlaczego pakiety i moduły są odrębnymi koncepcjami w Javie 9?

21

Java 9 będzie zawierać moduły oprócz pakietów. Zwykle języki mają jeden lub drugi. I większość programistów postrzega dwa terminy jako synonimy. Moduły są zbudowane na pakietach, traktując je jak prymitywy. Wzór złożony sugeruje równomierne traktowanie prymitywów i kompozytów. W przeciwnym razie zdarzają się złe rzeczy. Na przykład spójrz na projekt Valhalla, w którym starają się zmodernizować wspólny nadtyp dla typów pierwotnych (wartość) i referencyjnych.

Czy moduły i pakiety reprezentują semantycznie odrębne pojęcia? Oznacza to, że rozsądnie jest mieć oba w dowolnym języku (oddzielenie problemów). Czy Java musi mieć jedno i drugie jako hołd dla wstecznej kompatybilności?

Po co wprowadzać nową koncepcję zamiast rozszerzać istniejącą?


JSR 376 : „System modułów platformy Java” zaimplementowany w ramach projektu Jigsaw .

Według SOTMS

Moduł to nazwany, samoopisujący zbiór kodu i danych. Jego kod jest zorganizowany jako zestaw pakietów zawierających typy, tj. Klasy Java i interfejsy; jego dane obejmują zasoby i inne rodzaje informacji statycznych.

JLS ostrożnie unika definiowania pakietu . Z Wikipedii :

Pakiet Java to technika porządkowania klas Java w przestrzeniach nazw podobnych do modułów Modula, zapewniająca programowanie modułowe w Javie.

Wiem, że cytowanie Wikipedii jest złą praktyką, ale odzwierciedla powszechne zrozumienie. Od pozycji programowania modułowego:

Termin pakiet jest czasem używany zamiast modułu (jak w Dart, Go lub Java). W innych implementacjach jest to odrębna koncepcja; w Pythonie pakiet jest kolekcją modułów, podczas gdy w nadchodzącej Javie 9 planowane jest wprowadzenie nowej koncepcji modułów (zbiór pakietów z rozszerzoną kontrolą dostępu).

użytkownik2418306
źródło
3
Myślę, że zadajesz tutaj wiele pytań? 1) Czy moduły i pakiety to ten sam semantyczny pomysł? 2) (jeśli nie 1), czy jigsawmoduły-style są tylko ulepszeniem technicznym w stosunku do pakietów? 3) (jeśli nie 1 i jeśli 2), Java po prostu (lub pozornie) zachowuje obie koncepcje dla kompatybilności wstecznej. Na niektóre z tych pytań można odpowiedzieć, inne są przede wszystkim oparte na opiniach. Wydaje mi się, że edycja upraszczająca poszukiwane wyjaśnienia jest w tym miejscu.
Tersosauros
1
@Tersosauros Sklasyfikowałeś „niektóre” pytania jako nie na temat, ale nie oznaczyłeś, które z nich jest które. Widzę to jako tylko jedno pytanie (1). Inne zostaną rozwiązane automatycznie. Kompatybilność wsteczna dla java nie jest pytaniem. Tak więc albo java wprowadziła moduły do ​​poprawiania błędów w projektowaniu pakietów, albo dwa pojęcia są naprawdę osobnymi problemami. A zamieszanie wynika z niewłaściwego nazewnictwa.
user2418306
1
Chcę wyjaśnić pytanie. Ale muszę zrozumieć, która część tego według ciebie jest nieodwracalna. Kiedy myślę, że jest tylko jedna część.
user2418306
Ach, rozumiem zamieszanie. Myślę, że na pytanie nr 1 można odpowiedzieć (odpowiedź brzmi „tak, ale nie” - w tym miejscu pojawia się pytanie nr 3). Zgadzam się co do # 3, oczywiście Java nie zamierza zmienić tego, co słowo kluczowe w języku packagejest / robi / znaczy, ani też nie zmieni systemu (klasycznego, dość okropnego) systemu ścieżek klas w środowisku JRE. Pytanie nr 2 czuję się przede wszystkim opinia zorientowany (to odpowiada , ale moja odpowiedź, a ktoś inny może się różnić i żadna z nas nie musi być źle).
Tersosauros
1
Spróbuj zadać jasne pytanie z góry, a następnie podaj materiał pomocniczy.
Jay Elston,

Odpowiedzi:

22

Pojęcie modułu różni się od konkretyzacji tego pojęcia.

Java zawsze miała moduły. Metoda jest modułem, podobnie jak klasa, podobnie jak pakiet. Moduł to jednostka organizacyjna, w której wewnętrzne szczegóły są ukryte i która komunikuje się z innymi modułami za pośrednictwem uzgodnionych umów. Na przykład metoda jest modułem, ponieważ ma ukryte elementy wewnętrzne (kod i zmienne lokalne) oraz kontrakt (parametry i typ zwracany). Moduły można składać z modułów niższego poziomu, np. Klasy zawierają metody.

W rdzeniu Java (wcześniejszym niż 9) brakuje modułu, który można wdrożyć . Wszystkie powyższe rodzaje modułów nie są jednostkami do rozmieszczenia, które można kopiować. Java ma artefakt, który można wdrożyć, zwany plikiem JAR, ale nie są to moduły, ponieważ nie mają enkapsulacji ani kontraktu: w czasie wykonywania pliki JAR znikają, wszystkie łączą się w jedną „ścieżkę klas”.

OSGi zajęło się brakiem modułów możliwych do wdrożenia w 1998 r. Dzięki koncepcji „pakietu”. Są to fizycznie pliki JAR i zawierają pakiety, ale OSGi definiuje dodatkowe metadane wraz z systemem wykonawczym do obsługi enkapsulacji i kontraktów na tym poziomie.

Java 9 rozwiązuje problem braku modułów do wdrożenia w podobny sposób jak OSGi. Prawdopodobnie było to zupełnie niepotrzebne, ponieważ OSGi istnieje i działa, ale to zupełnie inna dyskusja ...

Niestety Java 9 zamazuje wody, nazywając nową koncepcję modułu tylko „modułem”. Nie oznacza to, że metody, klasy i pakiety przestają być modułami! „Moduł” J9 to kolejna instancja koncepcji modułu . Podobnie jak pakiety OSGi, moduły J9 są zbudowane z pakietów i są fizycznymi artefaktami (zwykle ponownie plikami JAR), które można kopiować. System wykonawczy je rozumie i weryfikuje.

Podsumowanie: tak Moduły i pakiety J9 są semantycznie oddzielnymi pojęciami. Oczywiście Java musi zachować istniejącą koncepcję pakietu w celu zapewnienia kompatybilności wstecznej. Zauważ, że słowo „pakiet” jest używane zupełnie inaczej w Javie niż w innych językach lub w systemach zarządzania pakietami, takich jak RPM. Nowe moduły J9 (i pakiety OSGi) są znacznie bardziej podobne do pakietów w RPM niż kiedykolwiek były pakiety Java.

Neil Bartlett
źródło
Pakiet nie spełnia twoich wymagań dotyczących definicji modułu. Z powodu słabego hermetyzacji i braku środków do agregowania innych pakietów i poprawiania ich widoczności. Klasy mogą zawierać zagnieżdżone klasy lub pola. Metody mogą zawierać zamknięcia lub wywoływać inne metody. Pakiety nie mogą „komunikować się” z innymi pakietami.
user2418306
Nie zgadzam się. Pakiety mają ukryte informacje (domyślne typy dostępu, metody i pola, inaczej pakiet-prywatny). Pakiety z pewnością „komunikują się”, ponieważ kod w pakiecie może wywoływać kod w innych pakietach. Odbywa się to na podstawie umowy, a mianowicie rodzajów publicznych i metod drugiego pakietu.
Neil Bartlett
Zauważ, że zdolność do agregowania artefaktów modułowych na tym samym poziomie (np. Metody zawierające zamknięcia, klasy zawierające klasy zagnieżdżone) NIE stanowi części mojej definicji modułu. Jeśli uważasz, że jest to niezbędna część definicji modułu, wówczas „moduły Java 9” również nie są modułami.
Neil Bartlett
Nie przeczę, że paczki mają ukryte informacje . Powiedziałem, że to nie wystarczy. importmoże łączyć paczki. Ale nie ma sposobu na ustrukturyzowanie paczek jako obywateli pierwszej klasy. Te niedociągnięcia (i ograniczenia OSGi) opisano w JSR 376.
user2418306
Czy możesz wyjaśnić, dlaczego moduły Java 9 również nie są modułami ?
user2418306
10

Pozwól, że zaryzykuję odpowiedź, choć większość z nich może być założeniami / rozdwajaniem włosów / rantowaniem itp.

Czy to to samo? Cóż, tak i nie

Z tego artykułu JavaWorld na temat „Modułowości w Javie 9” :

Pakiety jako rozwiązanie modułowe

Pakiety próbują dodać poziom abstrakcji do środowiska programowania Java. Zapewniają udogodnienia dla unikatowych przestrzeni nazw kodowania i kontekstów konfiguracji. Niestety, konwencje pakietów można łatwo obejść, co często prowadzi do powstania środowiska niebezpiecznych połączeń podczas kompilacji.

Jak wskazał @ user2418306 (OP) , moduły to pakiety wykonane poprawnie . Moduły i pakiety w Javie (oczywiście od Java 9) są (jak pyta OP) semantycznie to samo. Oznacza to, że są to zbiory prekompilowanego kodu bajtowego JVM z innymi metadanymi - w zasadziebibliotekami .

Jaka jest różnica?

Różnica polega jednak na metadanych wewnątrz każdego z nich. packageManifesty Java lub manifesty JAR często nie są obsługiwane przez programistów bibliotek, ani nie zawierają żadnej pewnej umowy dotyczącej tego, co zapewnia pakiet JAR / pakiet. Jak wyjaśniono tutaj (ponownie artykuł JavaWorld) :

Czy pliki JAR nie są wystarczająco modułowe?

Pliki JAR i środowisko wdrażania, w którym działają, znacznie poprawiają wiele starszych konwencji wdrażania dostępnych w innym przypadku. Ale pliki JAR nie mają żadnej wewnętrznej wyjątkowości, oprócz rzadko używanego numeru wersji, który jest ukryty w pliku .jar. Plik JAR i opcjonalny manifest nie są używane jako konwencje modułowości w środowisku wykonawczym Java. Zatem nazwy pakietów klas w pliku i ich udział w ścieżce klas są jedynymi częściami struktury JAR, które nadają modułowość środowisku wykonawczemu.


Rant na temat innych języków / środowisk itp

Innym obszarem omówionym w tym artykule są systemy takie jak Maven , które zarządzają zależnościami w ramach procesu kompilacji. Z tej strony w witrynie Apache Maven :

Zarządzanie zależnościami:

Maven zachęca do korzystania z centralnego repozytorium plików JAR i innych zależności. Maven jest wyposażony w mechanizm, za pomocą którego klienci twojego projektu mogą pobierać dowolne pliki JAR potrzebne do zbudowania projektu z centralnego repozytorium JAR, podobnie jak CPAN Perla. Pozwala to użytkownikom Maven na ponowne użycie plików JAR w różnych projektach i zachęca do komunikacji między projektami, aby zapewnić rozwiązanie problemów z kompatybilnością wsteczną.

Teraz mówię o przyszłości, jakbym tam był

Jak wspomniano na tej stronie , inne języki (takie jak Perl) mają repozytoria pakietów (jak CPAN ). Jest to rosnąca tendencja (mówię, ponieważ mam na to ochotę, bez wyraźnego dowodu), w ciągu ostatniej dekady. Narzędzia, takie jak klejnoty Ruby , PyPi Pythona i menedżer pakietów Node ( npm) , bazują na tym, aby zapewnić spójny sposób konfigurowania środowiska (programistycznego, kompilacyjnego, testowego lub uruchomieniowego itp.) Za pomocą odpowiednich elementów (pakietów, modułów, klejnoty, gadżety itp.). Pomysł (wydaje mi się) został zapożyczony z systemów dystrybucyjnych Linux®, takich jak apt Debiana , RedHatarpmitp. (Chociaż oczywiście ewoluowało co najmniej jedno pokolenie i sprawiło, że wszystkie te rzeczy są ładniejsze.)


Moduły Java , chociaż niekoniecznie dodają nic, czego nie można już zrobić, znacznie ułatwiają oprzyrządowanie do zarządzania zależnościami / pakietami i zautomatyzowanymi kompilacjami . Nie wiem, czy to czyni moduły „lepszymi”. : P

Tersozaury
źródło
1
Artykuł ma zaledwie 1 rok, a jednak jest już nieaktualny. Zastanawia się, w jaki sposób przechowywanie wersji jest podstawową cechą modułu. Moduły układanki nie będą miały informacji o wersji. Dla użytkownika końcowego nic się nie zmieni w dziedzinie zarządzania zależnościami. W przypadku narzędzi do budowania rzeczy będą znacznie trudniejsze. Ponieważ muszą wspierać równoległe rzeczywistości classpathi modulepath. I przeskocz przez obręcze, aby wspomóc testowanie jednostek. Przesłanka, że ​​dwa pojęcia są równoważne, ponieważ reprezentują zbiór rzeczy, a metadane jest zbyt odważne, żebym je zaakceptował. Plus w połowie drogi nagle zastąpiłeś słoik paczką.
user2418306
Nie powiedziałem „ dwa pojęcia są równoważne ”, powiedziałem, że są „semantycznie tym samym” - o to pytaliście. Zredagowałeś też to pytanie, ponieważ odpowiedziałem na konkretną wzmiankę o JSR-376 , w przeciwieństwie do układanki, o której mówiono wcześniej: - /
Tersosauros
Układanka obejmuje (implementuje) JSR-376. Pytanie wciąż łączy oba, więc nie wyrządzono żadnej szkody. Słownik definiuje równoważność jako jakość lub stan o tym samym znaczeniu. I semantycznie - w odniesieniu do znaczenia. Przepraszam, ale pedantycznie podchodzisz do niewłaściwych szczegółów. Powiedziałeś, że są równoważne. Ale nie podałeś żadnego uzasadnienia. Zamiast tego odwołujesz się do artykułu, który wyjaśnia, w jaki sposób pakiety i słoiki nie są modułami. Ale nadchodzące moduły również nie będą modułami z artykułu. Stwierdzenie równoważności, a następnie zapewnienie różnicy między 2 (3) jest wewnętrznie sprzeczne.
user2418306
Odpowiedź na pytanie nie może być twierdząca i nie. Albo dwa pojęcia semantycznie równoważne, albo nie. Proszę nie lobotomizować moich komentarzy i wrócić do pierwotnego pytania. Czy język wymaga obu pojęć, czy jest to specyficzny problem ze starszą wersją języka Java? Jeśli potrzebujesz wyjaśnień, chętnie pomogę.
user2418306