Project Jigsaw

anonym

Project Jigsaw
« kdy: 11. 07. 2018, 08:36:47 »
Na této stránce je asi nejpěknější popsání tohoto projektu na jaké jsem zatím narazil:

http://www.baeldung.com/project-jigsaw-java-modularity

Moc však z těch modulů nadšený nejsem. Hlavní věc, kterou to má řešit, je vytvoření API k balíčku a vytvoření zapouzdřenosti na úrovni balíčků. To mi přijde jako dost zbytečné, protože to jde řešit pěkně návrhovým vzorem Facade. Mám nějaký balíček a chci k němu vystavit api, tak mu dám do rootu Facade třídu do které podle OOP zaobalím práci s tím modulem (nebo těch zaobalujících Facade tříd udělám víc).

Jestli se pak najde někdo, kdo to bude obcházet a vrtat se ve vnitřnostech balíčku, tak to je přece jeho problém a jeho věc. Na menších projektech je to fuk, ať si děcka z VŠ bastlí jak chou, a větší projekty mají přece svého sys. architekta, který má takové věci učesat.

Dále má Jigsaw rozkouskovat knihovnu v JDK. Opět nechápu smysl proč to dělají přes nějaký Jigsaw. Ať si JDK rozkouskují jak chtějí, ale dependency projektu na jednotlivé kousky se budou řešit přes Maven. Všichni Javisti používají Maven, tak proč do toho někdo cpe Jigsaw?

Další věc kterou to má řešit je JAR Hell, že totiž nejde z classpath načíst třídu z jedné verze stejného JAR a jinou verzi stejného JAR. Opět, naco tady je Jigsaw, když to, jakou verzi která dependency potřebuje je plně obsaženo v pom.xml od Mavenu. Měli to do JDK zaintegrovat tak, aby si to mohl vyřešit buildovací nástroj.


A to by mělo být snad všechno. V Java projektech přibude podle mě zbytečně 1 konfigurák navíc:

1. Obsahující redundantní informace o závislostech, které se už nacházejí a nebo se můžou nacházet v pom.xml
2. Definuje API, které se ale dá nadefinovat  dobrým OOP návrhem, takže opět zbytečné.



Javista

Re:Project Jigsaw
« Odpověď #1 kdy: 11. 07. 2018, 09:12:38 »
Ptáš se na něco nebo jen brečíš, žes něco nepochopil?

MarSik

Re:Project Jigsaw
« Odpověď #2 kdy: 11. 07. 2018, 09:15:06 »
Tak úplně nevím jestli je tohle otázka nebo co, ale modularita už je dávno součástí JDK/JRE od verze Java 9 (aktuální je Java 10).

Máte jinak skoro pravdu, ale zapomněl jste na nezávislost na platformě a nerozlišujete build a runtime.

> Dále má Jigsaw rozkouskovat knihovnu v JDK. Opět nechápu smysl proč to dělají přes nějaký Jigsaw. Ať si JDK rozkouskují jak chtějí,
> ale dependency projektu na jednotlivé kousky se budou řešit přes Maven.

Těžko. Standarní knihovna "přibalená" k JRE obsahuje mnoho kódu specifického pro konkrétní platformu (interní implementace). JARy tohle neumí. Cílem bylo nenahrávat do paměti (a nedistribuovat) implementace API + knihovny, které aplikace nepotřebuje. Třeba minimalizaci velikosti kontejnerů s ořezaným JRE.

> Měli to do JDK zaintegrovat tak, aby si to mohl vyřešit buildovací nástroj.

Ne všichni používají maven (vážně).

pom.xml je záležitost překladu a ne koncového uživatele/serveru, ten už má jen hromadu JARů (nebo třeba WAR, EAR), takže ty vztahy to runtime JRE nemá jak poznat. A ten modul soubor je přesně ten způsob jak se o těch závislostech runtime dozví.

Krom toho, buildovací nástroj (nebo IDE) by klidně mohl tu konfiguraci modulů vygenerovat pro Vás, všechna data k tomu má.

Re:Project Jigsaw
« Odpověď #3 kdy: 11. 07. 2018, 09:44:47 »
To mi přijde jako dost zbytečné, protože to jde řešit pěkně návrhovým vzorem Facade. Mám nějaký balíček a chci k němu vystavit api, tak mu dám do rootu Facade třídu do které podle OOP zaobalím práci s tím modulem (nebo těch zaobalujících Facade tříd udělám víc).

Jestli se pak najde někdo, kdo to bude obcházet a vrtat se ve vnitřnostech balíčku, tak to je přece jeho problém a jeho věc.
Jenže ty implementační třídy vám pořád budou strašit na classpath a kdokoli je může použít omylem. Moduly nemají zabránit tomu, že by někdo chtěl škodit záměrně, ale mají předcházet omylům.

Dále má Jigsaw rozkouskovat knihovnu v JDK. Opět nechápu smysl proč to dělají přes nějaký Jigsaw. Ať si JDK rozkouskují jak chtějí, ale dependency projektu na jednotlivé kousky se budou řešit přes Maven. Všichni Javisti používají Maven, tak proč do toho někdo cpe Jigsaw?
Všichni Javisti nepoužívají Maven. Používají také Ant, Ivy, Gradle… A když už jste zmínil ten Maven, ten to zrovna dělá špatně, protože vám standardně nacpe tranzitivní závislosti na compile time classpath, takže právě můžete snadno udělat tu chybu, že začnete používat nějaké třídy, na kterých nemáte deklarovanou závislost.

Další věc kterou to má řešit je JAR Hell, že totiž nejde z classpath načíst třídu z jedné verze stejného JAR a jinou verzi stejného JAR. Opět, naco tady je Jigsaw, když to, jakou verzi která dependency potřebuje je plně obsaženo v pom.xml od Mavenu. Měli to do JDK zaintegrovat tak, aby si to mohl vyřešit buildovací nástroj.
Tady jste ani nepochopil, v čem je problém. Když budu mít v projektu závislost na knihovnách A a B, a knihovna A závisí na C-1.0, zatímco B závisí na C-2.0, přičemž C-2.0 není zpětně kompatibilní s C-1.0 (ale používají stejné package a třídy), mám neřešitelný problém. Protože když dám na classpath c-1.0.jar i c-2.0.jar, použijí se třídy jen z jednoho z nich, a buď knihovna A nebo B nebude fungovat.

Obsahující redundantní informace o závislostech, které se už nacházejí a nebo se můžou nacházet v pom.xml
Když by se ty informace nacházely v pom.xml (jako že ve skutečnosti tam je jenom jejich část), můžete z nich přece module-info.java vygenerovat. Navíc pom.xml se používá pouze při překladu, moduly se používají i za běhu.

Definuje API, které se ale dá nadefinovat  dobrým OOP návrhem, takže opět zbytečné.
Není to zbytečné, naopak to umožňuje, abyste ten dobrý OOP návrh také mohl použít.

anonym

Re:Project Jigsaw
« Odpověď #4 kdy: 11. 07. 2018, 11:02:57 »
To mi přijde jako dost zbytečné, protože to jde řešit pěkně návrhovým vzorem Facade. Mám nějaký balíček a chci k němu vystavit api, tak mu dám do rootu Facade třídu do které podle OOP zaobalím práci s tím modulem (nebo těch zaobalujících Facade tříd udělám víc).

Jestli se pak najde někdo, kdo to bude obcházet a vrtat se ve vnitřnostech balíčku, tak to je přece jeho problém a jeho věc.
Jenže ty implementační třídy vám pořád budou strašit na classpath a kdokoli je může použít omylem. Moduly nemají zabránit tomu, že by někdo chtěl škodit záměrně, ale mají předcházet omylům.

Jakému typu omylu zabrání to, že ty třídy nebudou na classpath? To si nějak neumím moc představit.

Citace
Dále má Jigsaw rozkouskovat knihovnu v JDK. Opět nechápu smysl proč to dělají přes nějaký Jigsaw. Ať si JDK rozkouskují jak chtějí, ale dependency projektu na jednotlivé kousky se budou řešit přes Maven. Všichni Javisti používají Maven, tak proč do toho někdo cpe Jigsaw?
Všichni Javisti nepoužívají Maven. Používají také Ant, Ivy, Gradle… A když už jste zmínil ten Maven, ten to zrovna dělá špatně, protože vám standardně nacpe tranzitivní závislosti na compile time classpath, takže právě můžete snadno udělat tu chybu, že začnete používat nějaké třídy, na kterých nemáte deklarovanou závislost.

Doposud se vezme první třída dané signatury na classpath, ikdyž tam bude ve vícero verzí jar. Tzn. to chování která třída se vezme je deterministické. Čím to dělá špatně Maven? Maven přece nemůže za to, že JRE nepodporuje načtení konkrétní verze importu.


Citace
Další věc kterou to má řešit je JAR Hell, že totiž nejde z classpath načíst třídu z jedné verze stejného JAR a jinou verzi stejného JAR. Opět, naco tady je Jigsaw, když to, jakou verzi která dependency potřebuje je plně obsaženo v pom.xml od Mavenu. Měli to do JDK zaintegrovat tak, aby si to mohl vyřešit buildovací nástroj.
Tady jste ani nepochopil, v čem je problém. Když budu mít v projektu závislost na knihovnách A a B, a knihovna A závisí na C-1.0, zatímco B závisí na C-2.0, přičemž C-2.0 není zpětně kompatibilní s C-1.0 (ale používají stejné package a třídy), mám neřešitelný problém. Protože když dám na classpath c-1.0.jar i c-2.0.jar, použijí se třídy jen z jednoho z nich, a buď knihovna A nebo B nebude fungovat.

Ano ale toto já právěže chápu, jenže to jde přece řešit podporou verzí u importů v bytecode a buiidovací nástroj jako maven by se postaral, aby tam ty správné verze do bytecode dal (aby se o to nemusel starat proramátor). Porotože Maven z pom.xml ví, že A závisí na C-1.0 a B na C-2.0, takže může na classpath vložit cosi, co podporuje JRE a podle čeho bude rozhodnuto, které C-X.0 se zrovna použije. Takže A bude při běhu volat z C-1.0 a b bude volat z C-2.0.

Citace
Obsahující redundantní informace o závislostech, které se už nacházejí a nebo se můžou nacházet v pom.xml
Když by se ty informace nacházely v pom.xml (jako že ve skutečnosti tam je jenom jejich část), můžete z nich přece module-info.java vygenerovat. Navíc pom.xml se používá pouze při překladu, moduly se používají i za běhu.

Je tam v Mavenu ta část, co dokáže vyřešit tranzitivní závislosti, a o to přeci jde především.

Citace
Definuje API, které se ale dá nadefinovat  dobrým OOP návrhem, takže opět zbytečné.
Není to zbytečné, naopak to umožňuje, abyste ten dobrý OOP návrh také mohl použít.

No takhle, vyvíjelo se tak posledních 20 let a ty projekty fungují. Můžete dát příklad, kdy konkrétně kvůli chybějícímu zapouzdření na úrovni modulů něco nefungovalo? Jako viděl jsem už pár velkých projektů a chybějící zapouzdřenost na úrovni modulů bylo to úplně nejposlednější, co by mi vadilo.


Re:Project Jigsaw
« Odpověď #5 kdy: 11. 07. 2018, 13:17:48 »
Jakému typu omylu zabrání to, že ty třídy nebudou na classpath? To si nějak neumím moc představit.
Omylu, že tu třídu použijete.

Doposud se vezme první třída dané signatury na classpath, ikdyž tam bude ve vícero verzí jar. Tzn. to chování která třída se vezme je deterministické.
No, deterministické… Pokud máte zaručené pořadí JARek na classpath, je to determenistické. Jenže pokud se classpath sestavuje dynamicky, třeba skriptem nebo hvězdičkou, je to sice deterministické, ale určit, jaké pořadí to v jakém případě bude, není úplně snadné.

Ale hlavně vám je úplně k ničemu, že aplikace deterministicky načte třídu z c-1.0.jar, když knihovna potřebuje stejně pojmenovanou třídu z c-2.0.jar.

Čím to dělá špatně Maven?
S Mavenem to nijak nesouvisí. Bavíme se tu o Java modulech (projekt Jigsaw).

Maven přece nemůže za to, že JRE nepodporuje načtení konkrétní verze importu.
Až do Javy 8 to skutečně podporované nebylo. Od Javy 9 to díky modulům podporované je.

Ano ale toto já právěže chápu, jenže to jde přece řešit podporou verzí u importů v bytecode a buiidovací nástroj jako maven by se postaral, aby tam ty správné verze do bytecode dal (aby se o to nemusel starat proramátor). Porotože Maven z pom.xml ví, že A závisí na C-1.0 a B na C-2.0, takže může na classpath vložit cosi, co podporuje JRE a podle čeho bude rozhodnuto, které C-X.0 se zrovna použije. Takže A bude při běhu volat z C-1.0 a b bude volat z C-2.0.
Tento teoretický nástroj, který jste vymyslel, a který má ještě určité mouchy, někdo vzal a v podobě projektu Jigsaw ho dotáhl do použitelné podoby. Takže dnes máme k dispozici Java moduly. Nebo-li to, co popisujete jako „dalo by se řešit“ je už právě pomocí modulů vyřešené.

Je tam v Mavenu ta část, co dokáže vyřešit tranzitivní závislosti, a o to přeci jde především.
Pokud jde o něco především, tak o to, aby tranzitivní závislosti nebyly zveřejněné. To, že nějaká knihovna A používá pro implementaci nějaké další knihovny B, nemá zajímat nikoho jiného než tu knihovnu A samotnou. Když knihovna A v příští verzi pro implementaci použije jinou knihovnu C, nemá to ovlivnit nikoho, kdo knihovnu A používá. A tohle řeší Maven špatně (dá vám tranzitivní závislosti na compiletime classpath), a za běhu to bez modulů ani nijak řešit nejde, protože když máte jen runtime classpath, ta knihovna B nebo C na ní musí být, a to ovlivňuje váš kód, který o B a C nemá vůbec nic vědět.

No takhle, vyvíjelo se tak posledních 20 let a ty projekty fungují. Můžete dát příklad, kdy konkrétně kvůli chybějícímu zapouzdření na úrovni modulů něco nefungovalo? Jako viděl jsem už pár velkých projektů a chybějící zapouzdřenost na úrovni modulů bylo to úplně nejposlednější, co by mi vadilo.
Když to nefungovalo, tak to samozřejmě není nikde v praxi použité. Nedávalo by smysl, aby někdo před dvaceti lety napsal kód, který začne fungovat, až někdo možná za dvacet let přidá do Javy moduly. Ale ty problémy reálně existují, akorát se různými způsoby obcházejí.

U větších projektů máte třeba na classpath spoustu tranzitivně dotažených pomocných knihoven a tříd. Takže tam máte třeba několik tříd StringUtil(s), z nichž některé byly myšlené čistě jako interní třídy nějakých knihoven, a některé jsou opravdu myšlené jako utilitní třídy pro veřejné použití, ale pořád je máte do projektu zavlečené jen jako tranzitivní závislost. Typicky ale chcete používat jen jednu z nich z knihovny, která je pro daný projekt vybraná. Takže to musíte někde zdokumentovat, která třída to má být, a pokaždé, když jí chcete použít, musíte si na to dávat pozor, přičemž IDE vás zbytečně mate nabídkou tříd, které používat nemáte. Když použijete špatnou třídu, IDE ani kompilátor nijak neprotestují – a najednou máte v projektu závislost na další knihovně, zavlečenou omylem, v žádném pom.xml ani jinde není nadefinovaná. Přínos takového chování není žádný, má to jen negativní důsledky.

Konfliktu verzí závislostí předcházejí některé knihovny tak, že zdrojáky závislé knihovny přibalí do svého projektu a přesunou je do svého package. Takže takhle máte třeba ASM aCGlib přibalené ve Springu, v knihovně Jodd máte přibalené taky ASM…

Apache HTTP Components řešily zpětně nekompatibilní změny mezi verzemi 3 a 4 tak, že verze 4 má jiné package – tím pádem může jeden projekt záviset na verzích 3 i 4 a nepotluče se to.

Stalin

Re:Project Jigsaw
« Odpověď #6 kdy: 11. 07. 2018, 13:22:26 »
Pekný trolling, prípadne si niekto pod inou prezývkou založil vlákno, aby v odpovediach mohol rozdávať pseudorozumy. Úbohé, vlastne ako celá tunajšia diskusia za posledných pár mesiacov.

anonym

Re:Project Jigsaw
« Odpověď #7 kdy: 11. 07. 2018, 13:30:40 »
Pekný trolling, prípadne si niekto pod inou prezývkou založil vlákno, aby v odpovediach mohol rozdávať pseudorozumy. Úbohé, vlastne ako celá tunajšia diskusia za posledných pár mesiacov.

Co to kecáš? Tady se normálně bavíme o novince v Javě. Ubohý jsi leda ty.

MarSik

Re:Project Jigsaw
« Odpověď #8 kdy: 11. 07. 2018, 14:01:37 »
Citace
takže může na classpath vložit cosi, co podporuje JRE a podle čeho bude rozhodnuto, které C-X.0 se zrovna použije

A to něco se jmenuje module-info.class (zkompilované module-info.java) a implementace tohoto mechanizmu přišla právě s projektem Jigsaw.

anonym

Re:Project Jigsaw
« Odpověď #9 kdy: 11. 07. 2018, 14:32:36 »
Tzn. teď Franta dodá Pepovi jarko, které používá StringUtils 1.0, a Pepa si nemusí dělat starost s tím, že používá StringUtils 2.0. Jasně, takže už to chápu, prostě teď ty jednotlivá Jarka budou navzájem opravdu izolovaná, jako kdyby běžela ve vlastní kontejneru.

Jen jestli to nepovede k plýtvání, kdy starou cestou Pepa by vynadal Frantovi, že si má upgradovat verzi, protože má starou. Teď tam budou 2 stejné věci jednoho a toho samého a nikomu se s tím nebude chtít lámat hlavu.

Re:Project Jigsaw
« Odpověď #10 kdy: 11. 07. 2018, 15:19:02 »
Ty konfliktní závislosti jsou nejčastěji problém knihoven třetích stran, kdy si nemůžete jen tak poručit, že přejdou na novou verzi. Naopak vás to často nutí použít starší verzi, protože vy byste v projektu chtěl použít aktuální verzi, ale nějaká knihovna závisí na starší verzi.

Ale jinak samozřejmě modulový systém není žádná kouzelná hůlka, která by verze vyřešila za vás. Je to jenom možnost dělat to lépe – a jestli jí využijete závisí na vás a na autorech knihoven, které používáte.