Právě dnes uběhlo třicet let od představení programovacího jazyka Java i virtuálního stroje Javy. Na stránkách Roota jsme si připomněli (a taktéž trošku oslavili) hned několik kulatých výročí různých programovacích jazyků. Nezapomněli jsme ovšem ani na programovací jazyk ALGOL, jehož nejznámější varianta, která se jmenuje ALGOL-60, vznikla skutečně již v roce 1960 a jehož historii jsme si připomněli v tomto článku. Dnes si připomeneme kulaté výročí skutečně těžké váhy v oblasti programovacích jazyků. Třicet let od svého představení totiž slaví Java, tj. jazyk, který byl již relativně krátce po svém vzniku nejpopulárnějším programovacím jazykem vůbec a i dnes se stále (a to s velkým přehledem) drží v první desítce nejpoužívanějších a nejpopulárnějších (což nemusí být ani zdaleka totéž) programovacích jazyků. Dokázala totiž nejenom přežít jak zánik původních platforem, pro které původně vznikla, ale přežila i svou „rodnou“ firmu Sun Microsystems.
Co je ale důležitější - Java nezůstala jazykem určeným pro jedinou izolovanou niku, ale adaptovala se v nových oblastech. Obrázek 3: Původní logo programovacího jazyka Java. Programovací jazyk Java byl navržen Jamesem Goslingem ze společnosti Sun Microsystems. Mělo se jednat o jazyk umožňující (relativně) snadnou tvorbu aplikací, navíc bez nutnosti řešení správy paměti (ta byla automatická). Ovšem z pohledu sémantiky jde o odlišný jazyk, který podporuje objektově orientovaný návrh založený nikoli pouze na hierarchii tříd, ale i na rozhraních (interface). Navíc je to jazyk více dynamický, protože například podporuje reflexi apod.
Některé nízkoúrovňové koncepty zůstaly zachovány a zajímavé je, že právě tyto koncepty jsou z dlouhodobého hlediska nejvíce problematické. Jedním z motivů nového programovacího jazyka bylo write once, run anywhere neboli WORA. Nicméně se nejedná o přenositelnost na úrovni zdrojových kódů, ale o přenositelnost již přeloženého kódu. Pokud by se programy napsané v Javě překládaly přímo do strojového kódu dané platformy, pochopitelně by to znamenalo, že přenositelnost nebude zaručena a navíc by jednou přeložené programy nemohly využívat například nová rozšíření instrukčních sad, nové registries atd. (musel by se provést nový překlad).
Tento problém byl v případě Javy řešen technologií, která již byla předtím použita u jiných jazyků, například u Pascalu. Namísto překladu programů do strojového kódu se prováděl (a stále provádí) překlad do takzvaného bajtkódu, který je posléze nějakým způsobem spouštěn virtuálním strojem Javy. Původní virtuální stroj Javy (JVM) byl interně relativně jednoduchý. Jednalo se totiž o interpret bajtkódu. Zdrojové kódy napsané v Javě byly nejdříve standardním překladačem Javy (javac, ostatně ten je po úpravách používán dodnes) přeloženy do bajtkódu (soubory .class, taktéž používané dodnes, ovšem s vylepšeními). A tento bajtkód byl po spuštění aplikace interpretován, což je sice z implementačního hlediska jednoduché, na druhou stranu však tímto způsobem spouštěné aplikace v žádném případě neoplývaly rychlostí a nemohly v tomto ohledu konkurovat aplikacím přeloženým do nativního kódu.
Dnes je JIT nedílnou součástí platformy Javy. Virtuální stroj Javy se tedy vlastně skládá ze tří hlavních subsystémů. Jedná se o zmíněný JIT překladač, dále o správce paměti a taktéž o běhové prostředí (runtime - interpret, standardní class loader, synchronizační mechanismy, správce vláken). Na rychlost (výkon) aplikací má největší vliv právě JIT. V současnosti se můžeme setkat s několika typy JIT překladačů. Právě existence JIT umožnila, aby se v Javě začaly vytvářet i rozsáhlé a sofistikované programy, které navíc měly srovnatelný výpočetní výkon, jako programy napsané v běžných překládaných programovacích jazycích (C, C++, později například Rust).
Původní verze programovacího jazyka Java byla z dnešního pohledu v několika ohledech omezená, protože v ní chyběly některé důležité programové konstrukce, specifikátory datových typů atd. Tvůrci Javy stáli před rozhodnutím, jakým tempem se má vlastně tento programovací jazyk vyvíjet a jak rychle do sebe má „absorbovat“ nové vlastnosti. V této oblasti (pokud se zaměříme na populární a používané programovací jazyky) můžeme vidět dva extrémy. Na jedné straně jazyk C, jehož vývoj je velmi pomalý a jeho nové verze si velmi přísně hlídají zpětnou kompatibilitu a novinky jsou poměrně malé. A na straně druhé jazyk C++, který za dobu své existence (40 let) prošel několika vlnami velkých změn, z nichž některé jsou dnes považovány za překonané, ale stále se musí z důvodu zpětné kompatibility udržovat. Programovací jazyk Java je v tomto ohledu spíše konzervativní, ovšem vývoj jazyka byl a je nutný, protože se vyvíjí i způsoby tvorby aplikací. Některé změny a vylepšení Javy byly spíše kosmetické, jiné naopak jazyk posunuty na jinou úroveň.
První změnou v Javě bylo přidání klíčového slova strictfp v Javě 1.2. Toto klíčové slovo se používá jako modifikátor u deklarace proměnných, návratových typů metod, u tříd atd. Druhým příkladem je zavedení podpory pro generické datové typy. Jedná se o zcela novou sémantiku, která je kompatibilní - původní zdrojové kódy bude možné stále bez problémů přeložit. Současně se jedná o posunutí možností jazyka na novou úroveň, protože je možné pracovat s „typově bezpečnými“ kontejnery atd. Na druhou stranu se tato změna dotýká spíše samotného programovacího jazyka a nikoli jeho bajtkódu.
V mnoha případech se termínem „Java“ nemyslí pouze samotný programovací jazyk Java, ale i celý ekosystém, který byl okolo tohoto jazyka postupně vytvořen. V první řadě se pochopitelně jedná o samotný virtuální stroj Javy (Java Virtual Machine neboli JVM), ovšem taktéž nesmíme zapomenout na celé běhové prostředí Javy (Java Runtime Environment neboli JRE), které kromě virtuálního stroje obsahuje i základní knihovnu Javy a další pomocné nástroje (práce s databází certifikátů atd.).

Obrázek 6: Důležitou součástí ekosystému Javy jsou pochopitelně i integrovaná vývojová prostředí. Okolo JVM resp. JRE postupem času vznikly i mnohé další nástroje - monitorovací aplikace, nástroje, které se k JVM připojují přes JVM TI (Java Virtual Machine Tools Interface), JDI (Java Debugger Interface) či JDWP (Java Debug Wire Protocol), ale i ucelená integrovaná vývojová prostředí (IDE).

Obrázek 8: Eclipse je skutečně platformou, nad níž lze vytvářet další více či méně sofistikované nástroje. Příkladem je integrované vývojové prostředí pro jazyk COBOL.
Virtuální stroj Javy (JVM), specifikace JVM a dokonce ani jeho instrukční soubor vlastně nikde striktně nepředpokládají, že JVM bude spouštět pouze bajtkód získaný překladem zdrojových kódů naprogramovaných přímo v Javě. Ve specifikaci JVM je dokonce na několika místech explicitně zmíněn předpoklad, že nad virtuálním strojem Javy budou provozovány i další programovací jazyky umožňující přímý či nepřímý překlad do bajtkódu. Kromě toho je samozřejmě možné přímo v Javě vytvořit interpret prakticky libovolného (interpretovaného) programovacího jazyka, takže vlastně nebude velkým překvapením, když zjistíme, že dnes těchto „JVM jazyků“ již existuje relativně velké množství (minimálně několik desítek) a některé z nich jsou dosti populární.
Prvním programovacím jazykem určeným pro běh nad virtuálním strojem Javy, o němž se dnes alespoň ve stručnosti zmíníme, je jazyk pojmenovaný Kotlin. Jedná se o moderní staticky typovaný programovací jazyk vyvinutý ve společnosti JetBrains a jeho cíl je vlastně velmi podobný cíli, který si dal dále zmíněný a poněkud starší jazyk Scala - efektivní a rychlá tvorba typově bezpečných aplikací určených pro běh nad JVM.
Typovost jde ještě o krok dále, než je tomu v Javě, protože například rozlišuje mezi nulovatelnými a nenulovatelnými datovými typy. Na rozdíl od Scaly je však rychlost překladu zdrojových kódů naprogramovaných v Kotlinu rychlejší a blíží se rychlosti překladu kódů napsaných v samotné Javě. Pravděpodobně druhým nejznámějším příkladem programovacího jazyka provozovaného nad JVM je Scala, která nabízí prakticky bezproblémovou spolupráci mezi částmi kódu psanými ve Scale a zbytkem aplikace psaným v Javě (popř. jsou některé projekty psané pouze ve Scale, ovšem provozovány jsou například na ryze javovských serverech - Tomcat, Jetty atd.).
Další jazyky pro JVM: Clojure, Groovy a další. Díky tomu, že zdrojové kódy psané ve Scale jsou přímo překládány do bajtkódu, získali tvůrci tohoto programovacího jazyka prakticky zadarmo veškeré vymoženosti, které virtuální stroj Javy poskytuje - od poměrně pečlivé kontroly bajtkódu při jeho načítání do virtuálního stroje přes použití správců paměti a JIT překladačů až po možnost využití rozsáhlých standardních knihoven J2SE a samozřejmě taktéž mnoha dalších knihoven a frameworků, které jsou pro JVM dostupné.
Z dalších překladačů programovacích jazyků, které pro virtuální stroj Javy vznikly, je podle mého názoru nejzajímavějším jazykem a současně i jazykem s poměrně velkým potenciálem pro budoucnost programovací jazyk s názvem Clojure, jehož autorem a dodnes nejaktivnějším vývojářem a propagátorem je Rich Hickey. Samotný název tohoto jazyka vznikl vložením písmene „j“ (Java/JVM) do slova closure. Velká část předností a pro mnohé vývojáře záporů programovacího jazyka Clojure vychází z toho, že se jedná o jazyk, jehož syntaxe a sémantika do značné míry vychází z LISPu a Scheme, tedy jazyků známých především tím, že se v programech v nich psaných používá nadměrné množství kulatých závorek.
Dalším programovacím jazykem, a nutno říci že jazykem poměrně populárním, je Groovy. Jedná se o jazyk inspirovaný některými dalšími (většinou dynamicky typovanými) programovacími jazyky, jako je Python, Ruby, ale například i Perl. Groovy podporuje objektově orientované programování a oproti Javě umožňuje psát kratší kód, z něhož jsou odstraněny méně podstatné části, které Java jakožto silně staticky typovaný jazyk vyžaduje. Z tohoto důvodu se Groovy velmi často používá všude tam, kde je vyžadovaný skriptovací jazyk běžící nad JVM. Dobrým příkladem je například konzole Jenkinsu, která ve výchozím nastavení používá právě Groovy.
Zatímco Scala, Clojure i Groovy jsou novými jazyky pro JVM, zmíníme se v této podkapitole alespoň ve stručnosti o jazycích „klasických“, které byly na JVM pouze naportovány. V první řadě se jedná o projekty pojmenované JRuby a Jython, což jsou varianty jazyků Ruby a Python. Původní interpretry Ruby a Pythonu jsou naprogramovány v jazyku C, proto se tato varianta Pythonu nazývá CPython; JRuby a Jython jsou reimplementace pro JVM. Python byl portován i na platformu .NET ve formě IronPython a existuje i varianta PyPy naprogramovaná v samotném Pythonu. Na platformu JVM byl portován i programovací jazyk JavaScript, a to několikrát. V případě projektu Kawa se jedná o implementaci jazyka Scheme naprogramovanou v Javě a běžící nad JVM. Je to plnohodnotný překladač jazyka Scheme do bajtkódu JVM, ačkoli to není jen primitivní interpret. Z benchmarků vyplývá, že výsledný kód dokáže konkurovat dalším jazykům nad JVM a dokáže kooperovat se samotným ekosystémem Javy.
JVM bajtkód pro začátečníky (a pro nás ostatní)
Na virtuální stroj Javy bylo portováno i mnoho dalších programovacích jazyků, ať již se jednalo o překladače či o interpretry. V následující tabulce jsou některé z těchto jazyků vypsány. V prvním sloupci je zobrazen název původního jazyka popř. rodiny jazyků, ve sloupci druhém pak jméno jeho konkrétní implementace pro JVM.
Programovací jazyk Java se přibližně po dvě desetiletí pohyboval na samotné špičce popularity programovacích jazyků. Netýkalo se to pouze IT profesionálů, protože se Java na některých univerzitách stala primárním programovacím jazykem. V současnosti sice popularita Javy relativně klesá v porovnání s konkurencí, nicméně se stále jedná o jeden z nejpopulárnějších jazyků současnosti. Uvedeme také, že v další tabulce je vypsáno deset nejpopulárnějších programovacích jazyků podle Tiobe a že většina z nich je starších než 20 let; výjimkou je Go.
Co to znamená? 85% profesionálních vývojářů je mladších než 45 let a pokud začali svoji kariéru ve věku dvaceti let, znamená to, že s vysokou pravděpodobností pracují s jazyky používanými ještě před jejich praxí. Java se původně používala pro mikrovlnné trubky a výtahy, ale tato oblast se neujala a Java se začala používat pro tzv. middleware a aplikace pro něj určené. Do určité míry za to mohla i Java applety, ale Java se neprosadila na desktopu a měla i určité problém s instalací a grafickým uživatelským rozhraním. Přesto Java pokračuje v evoluci, rozšiřuje své prostředky a ekosystém a nadále zůstává významným hráčem na poli programovacích jazyků.
tags: #programovaci #jazyk #jawa