Portál AbcLinuxu, 4. května 2025 11:47
Internet běží sice převážně na TCP/IP, ale v rámci jednoho počítače máme i vhodnější způsoby komunikace. Článek Java a unixové doménové sokety, FD, systemd a xinetd se věnuje unixovým soketům a jejich použití v Javě, předávání souborových popisovačů (FD) z rodičovského procesu potomkovi, konceptu tzv. socket activation a ukazuje i propojení Jetty a Apache pomocí unixových soketů.
Tiskni
Sdílej:
…hezky zpusob programovani v jave…
Toto^^^ existuje?
Původně jsem chtěl udělat radost lidem jako ty a dát sem blogový zápisek ve smyslu: Vím, že spousta lidí tady nesnáší systemd a spousta jich nesnáší Javu, tak jsem to dal dohromady, abyste mohli nesnášet, když nesnášíte :-)
Co přesně znamená lidem jako ty? Nevšiml jsem si, že bych nějak nesnášel Javu (a/nebo systemd), ale vždycky se najde pár jasnovidců, kteří dovedou na dálku z křišťálové koule vyčíst, co přesně kdo nesnáší a jací jsou lidi jako já. Zatímco jinde je tohle spíš kuriozita, na ABCLinuxu se to stalo téměř normou.
Nevšiml jsem si, že bych nějak nesnášel Javu
Tak proč píšeš komentáře jako #6? :-)
Mozna by se sluselo do clanku dat disclaimer, ze toto neni zrovna hezky zpusob programovani v jave a je to idealni cesta k tomu, aby program za par let prestal s nejakou novou verzi javy fungovat.
V kapitole Přístup k vyšším FD v Javě to varování je:
Takové řešení je ale poměrně křehké a pokud bychom se k používání neveřejného API uchýlili, museli bychom svůj program důkladně testovat s každou verzí Javy. Nakonec je tedy lepší si napsat vlastní implementaci (nad JNI nebo pohodlnějším JNA), která bude jen vracet vlastní instance standardních javovských rozhraní (proudy, sokety, kanály…), ale nebude záviset na žádném neveřejném API.
Je zřejmé, že tohle není moc dobrá cesta, resp. je to hack který se může někdy hodit, ale není to pro obecné použití.
Nebo myslíš, že může být problém s předáváním soketů obecně? Metoda System.inheritedChannel()
je oficiální veřejné API od Javy 1.5, to už žádný hack není a ty servery jako Jetty nebo Tomcat to normálně používají. Asi se tak úplně nepočítalo s tím, že tam kromě TCP a UDP může přijít i UDS (viz ten problém s adresou při odpovídání na datagram), ale vzhledem k tomu, že dneska (po víc než třiceti letech) se i nejmenované zaostalejší OS naučily pracovat s AF_UNIX
, tak věřím, že tohle se i v Javě bude jen zlepšovat, protože tím víceméně padá ten argument, že je to není dost multiplatformní. Spíš doufám v to, že by se podpora UDS mohla dostat do normálně do standardní knihovny.
A jeste vetsi disclaimer by si zaslouzil napad pouzit socket activation spolecne s javou. Co je na jave pomaleho je jeji start a cekani na to, az se kod trochu zahreje. Takto mas sice nepatrne rychlejsi prenos dat nez po TCP/IP, ale nekolikanasobne to prebijes opakovanym spoustenim runtimu nez u klasickeho sitoveho deamona.
Socket activation chápu tak, že se služba spustí při prvním požadavku – nikoli tak, že by se měla po každém požadavku vypínat (jako se to dělalo s některými službami v inetd/xinetd). Ona se vypínat může i v tom systemd, může se pro každé spojení pouštět nový proces, ale není to preferovaná varianta a už vůbec to není podstata socket activation. Těch výhod je víc – jednak ta práva (naslouchání na privilegovaných portech), IoC nebo třeba rychlejší/jednodušší start – nemusí se čekat, až služba opravdu naběhne, stačí vytvořit soket, a kdyby ji náhodou někdo potřeboval dřív, než stačí nastartovat, tak si jen o chvilku déle počká na první odpověď, ale nespadne to na tom, že by se nešlo připojit.
ale vzhledem k tomu, že dneska (po víc než třiceti letech) se i nejmenované zaostalejší OS naučily pracovat s AF_UNIX, tak věřím, že tohle se i v Javě bude jen zlepšovat, protože tím víceméně padá ten argument, že je to není dost multiplatformní.A jak dobre to funguje na Windows a macOS? Mas to otestovane?
Co je na jave pomaleho je jeji start a cekani na to, az se kod trochu zahreje.To není pomalé na Javě, ale na klasických implementacích JVM. Když si s GraalVM přeložíte javovskou aplikaci do nativní binárky, bude startovat stejně rychle, jako jiné nativní aplikace. Navíc socketová aktivace neznamená, že se ta aplikace musí hned zase vypínat.
Nemluve o problemech s prenositelnosti...Lepší by bylo, kdybyste o tom mluvil. Kdybyste napsal, v čem konkrétně vidíte problém. Co se rozbije tím, když ke klasickému spuštění, kdy se aplikace sama připojí na zvolený port, přidáte i možnost spuštění pomocí socket activation.
Když si s GraalVM přeložíte javovskou aplikaci do nativní binárky, bude startovat stejně rychle, jako jiné nativní aplikace.Za podminky ze pujde prelozit a spustit. GraalVM je porad hracka, ktera se do produkce absolutne nehodi. Doufam, ze jednou bude, ale momentalne to jako argument neberu.
Kdybyste napsal, v čem konkrétně vidíte problém.JNI, JNA, ...
String fd = "/proc/self/fd/4";
Constructor<FileDescriptor> c = FileDescriptor.class.getDeclaredConstructor(Integer.TYPE); c.setAccessible(true); return c.newInstance(fd);A celkove vidim (ze zkusenosti) problem v tom, kdyz aplikace zacne spolehat na neco, co je mimo jeji ekosystem. Po nejakem case se to ma tendenci rozejit a je pak problem to dat dohromady. Vedle toho se mi vybavil kod od frajeru, kteri valili funkce z sun.misc.Unsafe, protoze to bude rychlejsi a kdo vi co jeste, a s JDK 11 se to stalo i rozbitejsi.
Vedle toho se mi vybavil kod od frajeru, kteri valili funkce z sun.misc.Unsafe, protoze to bude rychlejsi a kdo vi co jeste, a s JDK 11 se to stalo i rozbitejsi.Nechci komentovat tu konkrétní situaci, ve který ses s tím setkal, ale IMO ta chyba není jednoznačně na straně lidí, kteří používají
sun.misc.Unsafe
. Z mého pohledu je také na stole možnost, že je to chyba Javy, že některá ta API nestandardizuje. Když vidím, jaké žonglování vyžaduje použití file descriptoru, tak mi přijde, že minimálně v některých případech to tak bude...
ale IMO ta chyba není jednoznačně na straně lidí, kteří používají sun.misc.UnsafeNe, ta chyba je jednoznacne na strane lidi, kteri to pouzivali. Oni si byli moc dobre vedomi (uz z toho nazvu), ze to je interni nestandardizovana zalezitost (ktera treba nebyla v Jave od IBM), ktera muze byt kdykoliv zmenena nebo odstranena, presto to pouzivali.
Z mého pohledu je také na stole možnost, že je to chyba Javy, že některá ta API nestandardizuje.To je mozne, ale nemuzes mit vsechno hned. A co se tyce standardizace rozhrani a celkove JCP, tak myslim, ze ostatni jazyky muzou docela zavidet.
Když vidím, jaké žonglování vyžaduje použití file descriptoru, tak mi přijde, že minimálně v některých případech to tak bude...To je dan za prenositelnost... Podobne by mohl prijit nekdo z windows a domahat se handlu na okno.
To je mozne, ale nemuzes mit vsechno hned.Tedy, 16 ~ 17 let v mých knihách není "hned"...
To je dan za prenositelnost...Jak už jsem poznamenával níže, s přenositelností to moc nesouvisí.
Podobne by mohl prijit nekdo z windows a domahat se handlu na okno.Ano, to by mohl.
Jak už jsem poznamenával níže, s přenositelností to moc nesouvisí.To sakra souvisi. Aby vec byla prenositelna, musi mit dobre definovanou semantiku (chovani) na vsech platformach.
Tak a ted si polozme otazku, k cemu neco takoveho ma slouzit. (A bude neco takoveho prenositelne na jiny OS?) V podstate toto je ukazka, jak udelat rozhrani, ktere neco nabizi, protoze muze, ale nikdo vlastne neresi, kolik komplikaci to muze napachat.Podobne by mohl prijit nekdo z windows a domahat se handlu na okno.Ano, to by mohl.
To sakra souvisi. Aby vec byla prenositelna, musi mit dobre definovanou semantiku (chovani) na vsech platformach.Ale vždyť to není v rozporu. Přenositelnost neznamená, že zatrhneš přístup k nativní platformě, ale že poskytuješ přenositelné abstrakce. Dále pak platí, že můžeš mít sebelepší abstrakce, ale občas se stane, že stačit nebudou - v takovém případě dává smysl poskynout nízkoúrovňovější a třeba platformě-závislé API, pomocí kterýho můžeš daný framework/API rozšířit víceméně podobným způsobem, jakým jsou napsány komponenty toho frameworku samotné. V zásadě mi přijde lepší ta platformě-závislá API poskytnout, protože můžeš zároveň s tím poskytnout i různé feature detekce atd., které pomůžou zajistit přenositelnost. Existuje samozřejmě určitý balanc - když bude platformních API moc a abstrakcí málo/špatné, nebude celá ta věc fungovat dobře nebo skoro vůbec (to je třeba případ těch wxWidgetů), na druhou stranu druhý extrém je IMO taky nedobře. IMO tím směrem je trochu vychýlená Java - 'řeší' přenositelnost tak, že si platformu tahá s sebou a poskytuje málo napojení na nativní systém. Java aplikace jsou v důsledku všude tak trochu cizinec. Jediný široce používaný systém, kde je Java skutečně doma, je pak paradoxně Android...
v takovém případě dává smysl poskynout nízkoúrovňovější a třeba platformě-závislé API, pomocí kterýho můžeš daný framework/API rozšířit víceméně podobným způsobem, jakým jsou napsány komponenty toho frameworku samotnéTakto si prenositelnost predstavuje programator v C. Vytoris si "prenositelny" program, ktery si pak musis upravit pro kazdou platformu, aby vubec fungoval. Vec, ktere si na Jave cenim, je prenositelnost stylem write-once-run-anywhere. A to ani ne tolik z pohledu, ze v jeden okamzik muzi mit stejny kod, ktery bezi na ruznych operacnich system, ale spis z pohledu casu, kdy muzu mit kod, ktery pred patnacti lety nekdo naprogramoval na necem, co uz je tezce za zenitem a bez problemu to spustim na dnesnim hardware a OS. Java ma prostredky, jak muzes opustit virtualni stroj (JNI, JNA), ale je to hodne problematicke. Za normalnich okolnosti totiz mas aplikaci zavislou jen na JVM (coz je super), v momente, kdyz zacnes pouzivat JNI/JNA, vytvaris zavislost i na hostitelskem operacnim systemu, velice casto i na konkretnim tool-chainu a v nejhorsim pripade i na konkretnim HW. Uz mnohokrat jsem narazil na nejaky nastroj nebo knihovnu, ktery nekdo v dobre vire (protoze rychlost) zoptimalizoval pomoci JNI/JNA a dnes to neslo ani prelozit, pricemz ten kod nebyl zase tak stary (5+ let). Takovy kod je casto proste na vyhozeni (javovsky i nativni). Pricemz s cistou javou neni problem pouzivat v dnesnich projektech veci, ktere vznikly pred dvaceti lety. Podobny problem se objevoval i v prvni verzich .NETu (nevim, jak je na tom ted .NET core), ale standardni knihovna a casto i aplikace byly prolezle P/Invoke s provazanim na windows DLL, takze i kdyz Mono jako runtime bylo uz docela uchazejici, proste portovat aplikace na Linux bylo peklo.
IMO tím směrem je trochu vychýlená Java - 'řeší' přenositelnost tak, že si platformu tahá s sebou a poskytuje málo napojení na nativní systém.Ano. Feature, not a bug.
Jediný široce používaný systém, kde je Java skutečně doma, je pak paradoxně Android...A webove aplikace ne?
Takto si prenositelnost predstavuje programator v C. Vytoris si "prenositelny" program, ktery si pak musis upravit pro kazdou platformu, aby vubec fungoval.Není to specifické pro C/C++, viz třeba ty příklady s Pythonem. A ano, úprava pro každou platformu je v menší nebo větší míře potřeba (minimálně na straně frameworku), to je celá definice multiplatformního SW. Ze stejného důvodu Java sice je přenositelná, ale ne moc multiplatformní.
A webove aplikace ne?Tak to jsou typicky aplikace, kde veškerá interakce se systémem je socket I/O a nějaké základní věci, dohromady toho moc nepotřebují. To je mimochodem důvod, proč třeba Go je jazykově i API-wise velmi omezené, ale přitom úspěšné. Protože každý a jeho babička dnes píše síťové appky.
A ano, úprava pro každou platformu je v menší nebo větší míře potřeba (minimálně na straně frameworku), to je celá definice multiplatformního SW.Michas dve veci. Jedna vec je upravovat aplikaci pro kazdou platformu, druha vec je upravovat framework. To prvni je vazny problem, ktery nikdo nechce delat, ale tve navrhy k tomu jednoznacne vedou. To druhe neni problem a v podstate se to da povazovat za spravny postup, protoze platformove zavisle veci mas vyclenene do jednoho mista a upravujes je pouze jednou, resp. udela to za tebe nekdo jiny.
Michas dve veci. Jedna vec je upravovat aplikaci pro kazdou platformu, druha vec je upravovat framework.Ano, míchám, protože řeším rozšiřitelnost frameworku. Až bude existovat dokonalý framework, můžeme se bavit o tom, že není dobré ho rozšiřovat...
Ale vždyť to není v rozporu. Přenositelnost neznamená, že zatrhneš přístup k nativní platformě, ale že poskytuješ přenositelné abstrakce.
Zrovna číselný FD žádná abstrakce není, protože na systémech, které otevřený soubor identifikují jinak nebo dokonce nic jako otevřené soubory nemají, to fungovat nebude.
Dále pak platí, že můžeš mít sebelepší abstrakce, ale občas se stane, že stačit nebudou - v takovém případě dává smysl poskynout nízkoúrovňovější a třeba platformě-závislé API, pomocí kterýho můžeš daný framework/API rozšířit víceméně podobným způsobem, jakým jsou napsány komponenty toho frameworku samotné.
Tuhle možnost v Javě máš – JNI. A tím spíš není důvod zatahovat ty platformě-specifické věci do standardní knihovny. Ostatně ta za tím myšlenka je: „přeložíte jednou – spustíte kdekoli“ – takže pokud si vystačíš se standardní knihovnou resp. i s dalšími knihovnami v čisté Javě, mělo by ti to fungovat kdekoli.
Nicméně u těch UDS si myslím, že by dneska ve standardní knihovně klidně být mohly – navzdory tomu, že může existovat OS, kde poběží Java a nebudou tam UDS, ale je to tak rozšířená věc, že mi to přijde jako přijatelný kompromis. Ale číselné FD mi do toho nezapadají – to je hodně nízkoúrovňová věc – zatímco UDS jsou stejná úroveň abstrakce jako TCP, UDP nebo SCTP, se kterými se v Javě běžně pracuje.
a poskytuje málo napojení na nativní systém
Poskytuje JNI, přes které si uděláš libovolné napojení na nativní systém.
Docela by se mi ale líbilo, kdyby existovaly dodatečné knihovny od autorů Javy, které by poskytovaly javovské API pro různé platformě-specifické věci. Nebyla by to sice standardní knihovna, ale bylo by to více oficiální a více důvěryhodné něž různé knihovny třetích stran.
Java aplikace jsou v důsledku všude tak trochu cizinec.
Zrovna ten článek jsem psal taky trochu kvůli tomu, abych ukázal, že Java se dá s OS integrovat lépe, než si většina lidí myslí. Já např. dlouho o System.inheritedChannel()
nevěděl a bral jsem jako smutný fakt, že čistě javovský program nemůže naslouchat na privilegovaném portu (pokud neběží pod rootem, což ale snad nikdo nedělá), ale ono to přitom možné je.
Možná ale tohle API mohlo být lépe udělané – umožnit zdědit více kanálů/soketů/proudů… ale pak je otázka, jak identifikovat, který je který. Např. systemd na to má nějaké céčkovské funkce, ale to už není specifické jen pro konkrétní platformu, to už je specifické pro jeden konkrétní init systém.
Zrovna číselný FD žádná abstrakce neníAni jsem neříkal, že je. Abstrakce by mohla být třeba něco jako
RawHandle
nebo cokoli a na různých systémech mít různé vlastnosti (velikost) nebo třeba úplně chybět.
protože na systémech, které otevřený soubor identifikují jinak nebo dokonce nic jako otevřené soubory nemají, to fungovat nebude.To úplě nedává smysl jako argument, protože na takovém systému nebudou fungovat ani běžné součásti Java stdlib jako
FileReader
atd.
Nicméně u těch UDS si myslím, že by dneska ve standardní knihovně klidně být mohlyTo v každém případě.
Docela by se mi ale líbilo, kdyby existovaly dodatečné knihovny od autorů Javy, které by poskytovaly javovské API pro různé platformě-specifické věci. Nebyla by to sice standardní knihovna, ale bylo by to více oficiální a více důvěryhodné něž různé knihovny třetích stran.Ano, tak jsem to zhruba myslel. To API klidně může být (resp. mělo by být) explicitně označené jako platformně-závislé, nebezpečné a podobně.
Abstrakce by mohla být třeba něco jako RawHandle nebo cokoli a na různých systémech mít různé vlastnosti (velikost) nebo třeba úplně chybět.Cimz vytvoris neprenositelnou aplikaci, ve smyslu write-once-run-anywhere.
Ano, tak jsem to zhruba myslel. To API klidně může být (resp. mělo by být) explicitně označené jako platformně-závislé, nebezpečné a podobně.Cimz prijdes o jednu z naprosto zasadnich vlastnosti dane platformy.
Při použití JNA nemusíš napsat ani řádek céčka, ani nepotřebuješ kompilátor céčka. Používá se tam libffi, která volá nativní funkce dynamicky.
Jde ale hlavně o to, že JNI/JNA ti poskytuje přístup ke všem nativním funkcím OS. Kdežto když se budeš spoléhat na javovská rozhraní, které ti někdo připravil, tak tam budeš mít vždy jen nějakou podmnožinu. Nikdo ti nepřepíše celý POSIX do Javy, ani by to nemělo smysl. Navíc POSIX ti většinou nestačí, budeš potřebovat tuhle něco z Linuxu, tuhle něco z GNU, támhle funkci z nějaké knihovny…
P.S. pak je otázka, jestli má smysl poskytovat nějaké polovičaté řešení v podobě podmnožiny nativních platformě-specifických funkcí, která se autorům Javy zdála důležitá. V některých případech možná ano, viz #56, ale rozhodně to není tak jednoznačné. A v zásadě není chyba ani to, jak to Java dělá teď.
Při použití JNA nemusíš napsat ani řádek céčka, ani nepotřebuješ kompilátor céčka. Používá se tam libffi, která volá nativní funkce dynamicky.Ok, dík za info.
Jde ale hlavně o to, že JNI/JNA ti poskytuje přístup ke všem nativním funkcím OS. Kdežto když se budeš spoléhat na javovská rozhraní, které ti někdo připravil, tak tam budeš mít vždy jen nějakou podmnožinu.No jo, tak je to nějaký tradeoff. S JNI máš k dispozici celé API systému, ale zase se s tím nepracuje moc dobře, resp. může být vhodné/potřeba si vytvořit sám nějaké wrappery apod... Btw. to vůbec není specifické pro Javu, to platí víceméně pro cokoli, co není C
Cimz vytvoris neprenositelnou aplikaci, ve smyslu write-once-run-anywhere.
Muselo by se to jasně komunikovat tak, že „tohle je sice software od autorů Javy, ale není to součást Javy a není multiplatformní“. Nejpohodlnější by bylo to distribuovat s JRE pro danou platformu – pak bych měl jistotu, že daná knihovna bude na dané platformě vždy k dispozici a nemusím ji přibalovat k aplikaci. Možná by se to dalo zapínat nějakou volbou na příkazové řádce, která by způsobila načtení patřičného JARu a dynamické knihovny resp. modulu.
Je tu bohužel riziko, že i když některým vývojářům pětkrát řekneš, že to není součást standardní knihovny a není to dostupné na všech platformách, tak to stejně bezhlavě použijí, protože „u nich to funguje“ a pak si budou stěžovat, že „ta Java není zase tak multiplatformní, jak se slibovalo“ – což samozřejmě není chyba Javy, ale těch vývojářů…
Ale i kdyby to byla dodatečná knihovna, kterou by sis musel ručně nainstalovat, tak bych v tom viděl přínos v tom smyslu, že by tam byl jakýsi závazek autorů Javy „dokud budeme podporovat Javu na platformě XY, tak se budeme starat i o to, aby na platformě XY fungovala tahle knihovna“. Tuhle záruku u knihoven třetích stran nemáš – proto mimochodem nerad používám knihovny, které a) nejsou dostatečně malé na to, abych si je v nejhorším případě mohl převzít a starat se o ně sám a zároveň b) nejsou dostatečně známé a rozšířené na to, aby dost lidí mělo zájem na tom, aby se udržovaly dál.
Když vidím, jaké žonglování vyžaduje použití file descriptoru
Což je ale dané tím, že Java není Céčko, je to jazyk určený pro úplně jiný druh aplikací. I v tom článku píšu, že je to hack a je lepší to nepoužívat – když už, tak je lepší si volat C funkce přes JNI/JNA – tam pak žádné neveřejné API ani hacky nepoužíváš, je to standardní postup.
fdopen()
nebo dokonce open()
jsou až v konkrétních rozšířeních.
Za podminky ze pujde prelozit a spustit. GraalVM je porad hracka, ktera se do produkce absolutne nehodi. Doufam, ze jednou bude, ale momentalne to jako argument neberu.GraalVM mimochodem používá v produkci například Twitter a celkově to postupuje velkou rychlostí dopředu. Chodil jsem na ty matfyzácké talky od Jaroslava Tulacha a musím říct, že to na mě zapůsobilo i mimo jiné tím, jak moc progressu během krátké doby bylo.
GraalVM mimochodem používá v produkci například TwitterKancelar pro uvadeni romanovych pribehu na pravou miru k tomu primo v clanku pise: “As far as I know, we are the only ones using Graal in production, or at least at this scale, and it works great for us,” Thalinger says. “We want to move all of our services to Graal because so far, we have thousands of servers and we’ve only converted maybe 20 sesrvices. Jinak argument, ze neco pouziva FB, Twitter, Google, apod. pro radu veci v IT sektoru je naprosto irelevantni, protoze tyto spolecnosti pracuji na uplne jinem rozsahu nez vsichni ostatni. Pro ne vylepseni vykonu o par procent muze byt uspora v milionech a tak se jim vyplati investovat cas a vyclenit lidi na udrzovani zatim krehke platformy. Z druheho pohledu, pokud vyvijis normalni aplikacni software a jsi vystaven riziku, ze ze dne na den nepujde prelozit nebo spustit, protoze se neco zmenilo v platforme nebo vysla nova verze knihovny, ktera s ni nejde prelozit, tak je to hodne velky hazard.
Jinak argument, ze neco pouziva FB, Twitter, Google, apod. pro radu veci v IT sektoru je naprosto irelevantni, protoze tyto spolecnosti pracuji na uplne jinem rozsahu nez vsichni ostatni.Já rozporoval tvoje tvrzení, které doslova říká, cituji:
GraalVM je porad hracka, ktera se do produkce absolutne nehodi.Argument není irelevantní, ve chvíli, kdy toto není pravda.
Kancelar pro uvadeni romanovych pribehu na pravou miru k tomu primo v clanku pise:To bylo takové hezky poetické. Co to jako mělo uvést na pravou míru? Citaci jak jim to skvěle funguje? To že byli v roce 2018 jediní, kdo to v téhle míře používal v produkci mi nepřišlo jako nic co by bylo třeba uvádět na pravou míru.
Z druheho pohledu, pokud vyvijis normalni aplikacni software a jsi vystaven riziku, ze ze dne na den nepujde prelozit nebo spustit, protoze se neco zmenilo v platforme nebo vysla nova verze knihovny, ktera s ni nejde prelozit, tak je to hodne velky hazard.To samozřejmě může být problém. Co by mě zajímalo je, jestli to fakt je problém, nebo jen hypotetická věc, která by se sice v principu mohla stát, ale nedochází k ní. Ideálně od někoho, kdo to fakt používá.
Tak jsem se nechal trochu unest, spravne jsem chtel napsat absolutne nehodi s vyjimkou nekterych specifickych pripadu. Je to lepsi?GraalVM je porad hracka, ktera se do produkce absolutne nehodi.Argument není irelevantní, ve chvíli, kdy toto není pravda.
To samozřejmě může být problém. Co by mě zajímalo je, jestli to fakt je problém, nebo jen hypotetická věc, která by se sice v principu mohla stát, ale nedochází k ní. Ideálně od někoho, kdo to fakt používá.Treba ja bych to rad pouzival, mel bych pro to i velice pekne scenare, kde by to padlo jak prdel na hrnec, ale nejde to, protoze nektere knihovny mi to proste nezchrousta.
Za podminky ze pujde prelozit a spustit. GraalVM je porad hracka, ktera se do produkce absolutne nehodi.Nesouhlasím. Na mikroslužby, které nejsou kritické, bych se to nebál nasadit.
JNI, JNA, ...Ptal jsem se, v čem konkrétně vidíte problém. Tohle není vůbec konkrétní. Když se to pokusím dešifrovat – obáváte se, že když v Javě implementujete socketovou aktivaci pro systemd, rozbije se vám použití JNI nebo JNA na jiných platformách (třeba na Windows) nebo na Linuxu bez systemd? Chtělo by to být konkrétnější, opravdu mne nenapadá, jak by ta socketová aktivace mohla rozbít JNI na Windows, když se tam ten kód pro socketovou aktivaci vůbec nebude provádět.
A celkove vidim (ze zkusenosti) problem v tom, kdyz aplikace zacne spolehat na neco, co je mimo jeji ekosystem.Socketovou aktivaci používá spoust aplikací. Dříve ty aplikace nic takového neměly. Prostě přiblya nová možnost, tak ji aplikace používají, když je k dispozici. Takhle jde vývoj softwaru dopředu.
Nesouhlasím. Na mikroslužby, které nejsou kritické, bych se to nebál nasadit.Nasazuj si, co chces, ale IMHO graal ma do vyzrale tecnologie vhodne do produkce porad daleko. Coz sam dokazujes tim, ze by ses nebal to pustit jen na nekriticke mikrosluzby.
Ptal jsem se, v čem konkrétně vidíte problém.Viz vyse, zbytek je jen mlaceni slamenneho panaka.
Socketovou aktivaci používá spoust aplikací.To nerozporuju a nemam s tim problem. Problem vidim v tom, ze tu socketovou aktivaci musi neco delat, coz je dalsi zavislost, ktera se muze z nejakeho duvodu (typicky v budoucnu) rozbit. Treba LP vymysli neco noveho jeste uzasnejsniho, zahodi se systemd, a budes muset kvuli tomu upravovat spousteni aplikace.
Takhle jde vývoj softwaru dopředu.A vyvoj software jde dopredu i tak, ze spousta lidi dela aplikace v Electronu, a co ma byt? Nemohu proto rikat, ze nektere veci mohou byt problematicke?
Treba LP vymysli neco noveho jeste uzasnejsniho, zahodi se systemd, a budes muset kvuli tomu upravovat spousteni aplikace.
Pokud by to záviselo na systemd, tak by se mi to taky nelíbilo. Ale jak je uvedeno v tom článku: stejného výsledku dosáhneš s klasickým xinetd nebo s těmi pár řádky v céčku. Socket activation tedy není nějaká „proprietární“ technologie LP/systemd, ale je to obecný princip, návrhový/architektonický vzor.
A vyvoj software jde dopredu i tak, ze spousta lidi dela aplikace v Electronu, a co ma byt?
Tohle přece nemůžeš srovnávat. UDS jsou věc z 80. let, tzn. dostatečně zralá a stabilní technologie. A to předávání soketu z rodičovského procesu potomkovi se používá taky odpradávna – byť se tomu třeba dřív neříkalo socket activation. Vždyť jde vlastně jen o to, že nejdřív vytvoříš soket a fork()
/exec()
uděláš až někdy později, ne hned. Nevím, kdo s touhle myšlenkou přišel první, ale určitě to bylo už dost dávno. Nepovažoval bych to za nějaký módní výstřelek poslední doby.
Socket activation tedy není nějaká „proprietární“ technologie LP/systemd, ale je to obecný princip, návrhový/architektonický vzor.Ja proti socket activation v podstate nic nemam, i kdyz nektere veci, jak jsou resene v systemd me fakt toci, ale to nechci resit. Jde mi to, ze kdyz ted vytvorim aplikaci, chci ji mit spustitelnou za deset let na cemkoliv bez dalsich uprav (protoze ty upravy casem mohou byt netrivialni). V momente, kdy cast funkcionality presunes ven, mimo svou aplikaci, mimo svuj dohled, je mozne, ze to bude nekdo v budoucnu muset resit a zadelas mu na problemy.
Tohle přece nemůžeš srovnávat.Ja to nesrovnavam, proti unixovym socketum nic nemam a pouzivam je. Mne slo o ten dementni argument, ze se software nejak vyviji a proste se s tim musim smirit.
Vždyť jde vlastně jen o to, že nejdřív vytvoříš soket a fork()/exec() uděláš až někdy později, ne hned. Nevím, kdo s touhle myšlenkou přišel první, ale určitě to bylo už dost dávno. Nepovažoval bych to za nějaký módní výstřelek poslední dobyNerikam, ze to je spatne en bloc, ale ze v kombinaci s javou mi to neprijde jako uplne dobry napad.
V momente, kdy cast funkcionality presunes ven, mimo svou aplikaci, mimo svuj dohledCož ale píšete úplně o něčem jiném, než je socket activation.
Mne slo o ten dementni argument, ze se software nejak vyviji a proste se s tim musim smirit.Na tom, že se do softwaru přidávají nové funkce, nic dementního nevidím. I ty funkce, které má software nyní, v něm někdy dříve nebyly a musely do něj být přidány.
Nasazuj si, co chces, ale IMHO graal ma do vyzrale tecnologie vhodne do produkce porad daleko. Coz sam dokazujes tim, ze by ses nebal to pustit jen na nekriticke mikrosluzby.Řekl bych, že je drobný rozdíl mezi produkčním nasazením třeba na blogísek, e-shop a jadernou elektrárnu.
Viz vyse, zbytek je jen mlaceni slamenneho panaka.Výše jste nenapsal nic, co by podporovalo váš názor, že to způsobí problémy s přenositelností. Proto jsem se na to ptal. Ale jako potvrzení, že žádné argumenty nemáte, už to stačilo.
To nerozporuju a nemam s tim problem.Pokud s tím nemáte problém, asi byste neměl psát „nemluvě o problémech“.
Problem vidim v tom, ze tu socketovou aktivaci musi neco delat, coz je dalsi zavislostNení to další závislost. Z pohledu aplikace funguje socketová aktivace tak, že aplikace od rodiče zdědí už otevřený socket. Takhle funguje třeba předávání standardního vstupu a výstupu.
budes muset kvuli tomu upravovat spousteni aplikaceNebudu. Nevím o žádné aplikaci, která by byla na socket activation závislá, tj. musela by otevřený socket dostat od rodiče a neuměla si ho vytvořit sama.
Nemohu proto rikat, ze nektere veci mohou byt problematicke?Zatím to vypadá, že za problematické označujete věci, o kterých nic nevíte.
Řekl bych, že je drobný rozdíl mezi produkčním nasazením třeba na blogísek, e-shop a jadernou elektrárnu.Ano, je to rozdil, a co jsi tim chtel rict? S Graal jsem mel problemy i na relativne malych hobby projektech, tak nevim, proc by to z nejakeho duvodu melo fungovat lip na produkcnich vecech.
Osvez si funkcni praci s textem. Nerozporuji, ze socket activation pouziva spousta aplikaci a muze to byt uzitecne, sam to bezne pouzivam. Co rozporuji je, ze hrozi, ze vytvoris aplikaci, ktera bude z nejakeho duvodu spatne prenositelna nebo se casem rozbije.Pokud s tím nemáte problém, asi byste neměl psát „nemluvě o problémech“.Socketovou aktivaci používá spoust aplikací.To nerozporuju a nemam s tim problem.
Není to další závislost. Z pohledu aplikace funguje socketová aktivace tak, že aplikace od rodiče zdědí už otevřený socket.A ten rodic je co? Kouzelni skritkove? Z meho pohledu je to dalsi zavislost, kterou je nutne nejak resit, zajistit.
Takhle funguje třeba předávání standardního vstupu a výstupu.Nefunguje, predavani stdin/stdout je z pohledu aplikace zcela transparentni.
Ano, je to rozdil, a co jsi tim chtel rict?Že je lichý váš argument, že když to není vhodné pro nasazení na kritické systémy, nehodí se to na žádné produkční nasazení.
S Graal jsem mel problemy i na relativne malych hobby projektech, tak nevim, proc by to z nejakeho duvodu melo fungovat lip na produkcnich vecech.Tady se ale nebavíme o vašich problémech, bavíme se o GraalVM.
Co rozporuji je, ze hrozi, ze vytvoris aplikaci, ktera bude z nejakeho duvodu spatne prenositelna nebo se casem rozbije.Tak uveďte konkrétní příklad. Zatím to tiž vypadá, že neustále píšete o něčem, o čem nic nevíte.
A ten rodic je co? Kouzelni skritkove? Z meho pohledu je to dalsi zavislost, kterou je nutne nejak resit, zajistit.Ten rodič je třeba shell – velice často se právě shell používá pro spouštění jiných procesů. Zajímalo by mne, kdy jste musel v linuxu nějak speciálně řešit, abyste měl správný rodičovský proces.
Nefunguje, predavani stdin/stdout je z pohledu aplikace zcela transparentni.Myslím, že si tu všichni velice rádi poslechnou, jaký je rozdíl v předávání socketu napojeného na standardní výstup a síťového socketu. Nebo snad ta transparentnost spočívá v tom, že se standardní vstup předává na deskriptoru 0, což je pro vás transparentní číslo, zatímco socket ze socket activation se předává na deskriptoru 3, a to je pro vás absolutně neprůhledné?
Tak uveďte konkrétní příklad. Zatím to tiž vypadá, že neustále píšete o něčem, o čem nic nevíte.
Zřejmě myslí situaci, kdy zmizí všechny zdrojáky systemd, xinetd a dalších init systémů a zároveň nikdo nebude schopný napsat těch pět řádků v céčku, aby procesu nastavil správný soket na FD 0. :-) A zároveň ta aplikace bude brát soket jen ze System.inheritedChannel()
a tobě bude činit nepřekonatelný problém ji upravit, aby si sama vytvořila třeba TCP soket. Pro mě je to tak nepravděpodobná situace, že s takovým rizikem klidně dokážu žít. :-)
jaký je rozdíl v předávání socketu napojeného na standardní výstup a síťového socketu
Zrovna v tomhle rozdíl být může. Pokud se accept()
, přijetí spojení, udělá v rodičovském procesu a ten nastaví tohle jedno klientské spojení na STDIN a STDOUT, tak to víceméně transparentně funguje. Ale pokud ho nastaví jen na STDIN (FD 0) a na STDOUT (FD 1) nechá standardní výstup (soubor, terminál atd.), tak to bude fungovat jinak. A úplně jinak to bude fungovat, když se accept()
dělá až v aplikaci – tzn. aplikace dostane serverový soket a sama si přijímá jednotlivá spojení.
Nicméně předat serverový soket přes FD 0 je IMHO konvence, funguje to ve víc než jednom init systému, není to specifické chování pro nějaký jeden software. K čemu konvence AFAIK chybí je scénář, kdy chceme předat víc soketů – pak je potřeba od rodiče k potomkovi předat i informaci, který FD je který. Dalo by se to dělat třeba přes proměnné prostředí. Systemd to dělá přes svoje funkce definované v sd-daemon.h a třeba takové Qemu přijímá čísla FD jako parametry na příkazové řádce.
A zároveň ta aplikace bude brát soket jen ze System.inheritedChannel()Tohle je jediný možný problém. Že by ta aplikace neuměla sama začít poslouchat. Tím pádem by nefungovala na jiných OS, na Linuxu bez systemd a i se systemd by fungovala jedině se aktivací soketem. Žádnou takovou aplikaci ale neznám.
Zrovna v tomhle rozdíl být může.Samozřejmě jsou rozdíly v přístupu k unixovému socketu, naslouchajícímu síťovému socketu a socketu síťového spojení. Ale nějak na tom předávání socketů ze systemd nevidím nic netransparentního.
K čemu konvence AFAIK chybí je scénář, kdy chceme předat víc soketů – pak je potřeba od rodiče k potomkovi předat i informaci, který FD je který.Podle mne to určuje ta cílová aplikace, takže stačí umět rodiče nakonfigurovat, který deskriptor má předat který socket. Což systemd pokud vím umožňuje.
Podle mne to určuje ta cílová aplikace, takže stačí umět rodiče nakonfigurovat, který deskriptor má předat který socket.
Často to může stačit – v dokumentaci pak bude třeba „na 3 očekávám serverový soket A, na 4 serverový soket B a na 5 soubor C“. Ale když ta aplikace bude víc konfigurovatelná, tak bys to pak musel nastavovat na dvou místech. Např. ta aplikace bude mít jeden soket pro správu a pak 1 až N soketů pro přijímání klientských spojení a pak třeba ještě volitelný soket pro propojení s nějakou jinou komponentou. A tam se pak může hodit, že to (např. naslouchání na několika různých TCP a UDS soketech) nastavím jen v init systému, a aplikaci pak jen nějak předám informaci o tom, který soket je který, aby věděla, co s nimi má dělat.
Tady se ale nebavíme o vašich problémech, bavíme se o GraalVM.Ano, ty problemy s prekladem s Graal jsem nemel, proste mi je nekdo vnutil a nikdo jiny je proste mit nemuze a nenarazi na ne. Odmitam diskutovat timto zpusobem, a toto je posledni prispevek k diskuzi s tebou.
Ten rodič je třeba shell – velice často se právě shell používá pro spouštění jiných procesů. Zajímalo by mne, kdy jste musel v linuxu nějak speciálně řešit, abyste měl správný rodičovský proces.Tobe se evidentne nikdy nepostestilo potkat spousteci, inicializacni, pripadne instalacni skript, ktere byl napsany pro nejaky obskurni shell, ktery bezel na SCO, Solarisu nebo nevim cem, ktery pred dvaceti lety nekdo napsal, protoze to byl standard, a na linuxu to proste nejelo, ze?
Myslím, že si tu všichni velice rádi poslechnou, jaký je rozdíl v předávání socketu napojeného na standardní výstup a síťového socketu. Nebo snad ta transparentnost spočívá v tom, že se standardní vstup předává na deskriptoru 0, což je pro vás transparentní číslo, zatímco socket ze socket activation se předává na deskriptoru 3, a to je pro vás absolutně neprůhledné?FYI, transparentnosti se mysli to, ze neni potreba tu aplikaci nijak upravovat. Tecka. Cisilka v tom nehraji roli. Koncim.
Ano, ty problemy s prekladem s Graal jsem nemel, proste mi je nekdo vnutil a nikdo jiny je proste mit nemuze a nenarazi na ne.Já jsem nerozporoval, že vy jste měl nějaké problémy. Ale když nenapíšete ani čárku o tom, jak se ten problém projevoval nebo co bylo jeho podstatou, ze zkušenosti předpokládám, že chyba byla mezi židlí a klávesnicí.
Odmitam diskutovat timto zpusobemTo je fajn. Takže konečně začnete diskutovat normálně a nebudete jen obecně mlžit?
Tobe se evidentne nikdy nepostestilo potkat spousteci, inicializacni, pripadne instalacni skript, ktere byl napsany pro nejaky obskurni shell, ktery bezel na SCO, Solarisu nebo nevim cem, ktery pred dvaceti lety nekdo napsal, protoze to byl standard, a na linuxu to proste nejelo, ze?To ale nemá nic společného s touto diskusí.
FYI, transparentnosti se mysli to, ze neni potreba tu aplikaci nijak upravovat. Tecka.Aha, takže pokud aplikace není napsaná tak, aby očekávala vstup na file descriptoru 0, podle vás to ta aplikace najednou jednoho dne bude umět, aniž by bylo potřeba ji upravovat. Vidím, že nic nezvyklá vaše mylné přesvědčení, že když se do aplikace přidá funkcionalita, aby uměla převzít socket od rodičovského procesu, zabrání se tím jejímu spouštění klasickým způsobem, kdy si všechny sockety vytváří sama. O tom, že takhle dávno fungovaly programy pod
inetd
nebo xinetd
a běžně se to používalo, zřejmě také nevíte.
Koncim.Výborně. Tak si ve volném čase přečtěte něco o tom, jak funguje fork procesu v unixech a jak se při tom předávají file descriptory.
Ale když nenapíšete ani čárku o tom, jak se ten problém projevoval nebo co bylo jeho podstatou, ze zkušenosti předpokládám, že chyba byla mezi židlí a klávesnicí.Není to trochu přezíravé? S uživatelem deda.jabko v kontextu diskuse sice také spíše nesouhlasím, nicméně vzhledem k jeho zjevně velkým znalostem/zkušenostem bych tohle by-default nepředpokládal...
Ale když nenapíšete ani čárku o tom, jak se ten problém projevoval nebo co bylo jeho podstatou, ze zkušenosti předpokládám, že chyba byla mezi židlí a klávesnicí.Typicky byly problematicke knihovny, ktere intenzivne pouzivaly reflexi, coz je prekvapive dost knihoven. Bud nesly prelozit nebo prelozeny kod padal. Konkretni schvalne nechci byt, protoze se to meni v case. A znam styl mistnich diskutujicich, kteri, kdybych uvedl neco konkretniho, by mi vynadali za to, ze neco takoveho nemam pouzivat nebo, ze je to chyba mezi zidli klavesnici, protoze jim to funguje.
To ale nemá nic společného s touto diskusí.Prekvapive dost. Uz jsem spoustu softwarovych baliku, ktere jsou dnes prakticky nepouzitelne, protoze okolni podpurny system zanikl, ruzne SunOS, SCO, etc. pricemz ty programy samy o sobe by asi fungovaly.
Výborně. Tak si ve volném čase přečtěte něco o tom, jak funguje fork procesu v unixech a jak se při tom předávají file descriptory.Podivej se, vzdycky jsem te akceptoval jako diskutujiciho sice s divnymi nazory, ale ktery ma aspon nejakou uroven. Timto jsi predvedl, ze tva uroven je opravdu nekde jinde, nez jsem si myslel, a nehodlam se na ni snizit. Sbohem, uzij si vitezstvi v teto diskuzi!
GraalVM žádný automagický odhad nepoužívá.Vycházel jsem z tohohle dokumentu, na který jsem proklik odsud. Píše se tam, že přes statickou analýzu je schopen zjistit, k čemu se přistupuje reflexí, pokud jsou ty identifikátory constant-foldable stringy (což dává smysl). Nemam ale tušení, jak moc tohle platí, když člověk kompiluje běžné knihovny / frameworky. Pokud ne, tak sestavovat ten konfigurák zní jako dost zdlouhavá a nepříjemná práce, navíc interní záležitosti nějaké knihovny se můžou kdykoli změnit... Takže bych se úplně nedivil, že to někdo vyhodnotí jako nepoužitelné pro produkci.
A pro zajištění fungování reflexe (v jakémkoli jazyce) potřebujete informace o entitách, ke kterým se přes reflexi přistupuje, nikoli o těch, které reflexi používají.Ano, tak jsem to myslel.
Nemam ale tušení, jak moc tohle platí, když člověk kompiluje běžné knihovny / frameworky. Pokud ne, tak sestavovat ten konfigurák zní jako dost zdlouhavá a nepříjemná práce, navíc interní záležitosti nějaké knihovny se můžou kdykoli změnit... Takže bych se úplně nedivil, že to někdo vyhodnotí jako nepoužitelné pro produkci.K objektům z běžných knihoven/frameworků se málokdy přistupuje reflexí. Proto jsem zdůrazňoval, že jde o entity, ke kterým se přistupuje reflexí – což jsou v aplikaci v drtivé většině případů vaše vlastní třídy. Ale osobně se mi nelíbí ani ten přístup přes reflexi. Typická aplikace má všechny třídy známé už v okamžiku překladu, takže kompilátor může vygenerovat kód, který volá metody přímo. Situace, kdy mám nějakou Springovskou aplikaci a teprve po sestavení ji konfiguruju tím, jaká JARka jí dám na classpath, je dost výjimečná. Proto se mi líbí přístup Micronautu, který to, co dělá Spring až při startu reflexí, udělá už při kompilaci. Reflexi používají pokud vím jenom kvůli Jacksonu, který to zatím jinak neumí.
A že je to úplně základní znalost potřebná pro používání native-image – pokud si někdo nepřečte dokumentaci a jen tak to zkouší, nejspíš pohoří.Heleho, druhy Ponkrac, taky jasnovidec. Graal mam prostudovany docela do hloubky, mam nad nim udelany vlastni jazyk a ctenim dokumentace jsem stravil nemalo casu a moc dobre vim, jak je neuplna a casto neodpovida realite. Tak se s ni radeji moc neohanej. Mimochodem, uz to je pro me poradny duvod, proc to nedavat do produkce. Ale ty vis mnohem lip, co vim a nevim a co jsem udelal ci neudelal.
Vycházím jenom z toho, co jste napsal zde v diskusi.Jo, akorát tomu z mého pohledu zcela chybí to, čemu se v angličtině říká Benefit of the doubt. Ale samozřejmě jak moc člověk ne/předpokládá nekompetenci nebo špatný záměr je individuální a v zásadě si to nastav jak chceš, proti tomu se nevymezuju. Když už, tak proti tomu to prohlásit za objektivní pravdu.
Ty bys to udělal? Myslím, že ne.Co to je za otázku? Vždyť to dělám pořád.
A myslím, že vím i důvod -- slušnost.To myslíš že víš důvod proč se dovoláváš normy, nebo myslíš že víš důvod, proč bys na to měl mít nárok, nebo myslíš že víš důvod, proč si myslíš že bych to (podle tebe) neudělal?
Kokote. Ale protože jsme tady všichni kokoti, tak mega kokot je tady normální. Fajn.Volně přeloženo; "a tohle jsou důvody, proč jsem irelevantní". Vskutku. Tak díky za názor, dál už mě nezajímáš.
Mimochodem, referenční implementace těch Relačních rour není psaná v Javě.
To tam je: public FileInputStream(FileDescriptor fdObj), ale není chybí veřejné API k vytvoření instance FileDescriptor z číselné hodnoty:
Instances of the file descriptor class serve as an opaque handle to the underlying machine-specific structure representing an open file, an open socket, or another source or sink of bytes. The main practical use for a file descriptor is to create a FileInputStream or FileOutputStream to contain it.
Applications should not create their own file descriptors.
Zřejmě proto, že je to platformě-specifická (unixový) věc. Počítám, že třeba v takovém Bystroushaakově objektovém OS by nic takového nebylo (byly by to objekty, ne číselné identifikátory, pokud by tam vůbec bylo něco jako soubory).
To tam je: public FileInputStream(FileDescriptor fdObj), ale není chybí veřejné API k vytvoření instance FileDescriptor z číselné hodnotyTu číselnou hodnotu mám na mysli, když říkám "file descriptor"
Zřejmě proto, že je to platformě-specifická (unixový) věc.To by nemělo ničemu vadit. Můžeš to brát jako třeba
int
v céčku - na každé platformě to může být něco jiného, ale neznamená to, že pro to nemůže existovat API. Ten Pythoní fdopen()
funguje i na Windows a třeba Rust má pro tohle typy a traity [1, 2] ... což je možná trochu overengineering, ale v každém případě se to dá nějak udělat a není moc důvod, proč by to Javě nemělo jít...
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.