Eclipse – nefunkční "hot code replace"

Alternativní nadpis tohoto příspěvku by mohl znít „Jak použít Eclipse (java) compiler“ mimo IDE. Tímto jsem asi dost napověděl, o čem budou následující řádky pojednávat.

Remote Debugging

Vzdálené debugování (remote debugging) je užitečný nástroj pro ladění „vzdálených“ aplikací – „vzdálených“ v tom smyslu, že se pomocí svého debuggeru připojujete do jiné běžící Java Virtual Machine nejspíše s úmyslem ladění dané aplikace 😉 Nebudu nosit dříví do lesa: Více si o tomto tématu přečtete například v článku Debugging v praxi – opravdu samozřejmost?! od otce Fura či Eclipse a drobné maličkosti – vzdálené debugování od Dagiho.

Hot Swap

S remote debuggingem souvisí další funkcionalita, která z mé vlastní zkušenosti dokáže ušetřit obrovské množství času. Tato funkcionalita se jmenuje hot swap. Hot swap umožňuje „vpašovat“ do běžící aplikace novou verzi přeloženého kódu a nahradit jí tak kód původní.

Pro lepší představu, proč považuji hot swap za maximálně efektivní pomůcku, uvedu jeden příklad z mé praxe. Pracoval jsem na Ariba projektu, kde restart modulu Ariba aplikace (to jest jedné instance Weblogicu) na které jsem pracoval, trval na laptopu přibližně 9-10 minut (díky tomu, že se inicializovaly různé adaptéry, Tibco repositories, kontrolovala se XML metadata,…).

Součástí typického úkolu na tomto projektu byl vývoj nějakého vysoce sofistikovaného 😉 java kódu, který používá pokud možno public API aplikace a na konci dosáhne kýženého výsledku, za aplausu business consultantů 🙂 V uvedené konfiguraci, kdy jedním restartem ztratíte tolik času, si musíte dávat sakra dobrý pozor na jakékoliv triviální chyby (na netriviální chyby si často pozor dát ani nemůžete, například z toho důvodu, že API není zrovna dobře zdokumentované a až stacktrace při testování vás upozorní na možný problém) 😉

Zde se pomalu dostávám k jádru věci. Hot swap vám v těchto případech velice dobře poslouží: triviální problém – zapomněli jste test na null? Chcete přidat debugovací řádku…? S hrůzou zjistíte že nerovnost v podmínce je přesně obráceně? Bez remote debuggingu (aneb tak jak jsem to viděl kupodivu u velkého množství kolegů konzultantů) musíte shodit server, opravit, překompilovat, zrestartovat a dvacet minut je pryč. Následnovně zjistíte, že o pár řádků dále je problém podobný a tak pořád dokola.

Ti rozumnější (případně ti pracující v módu fixed fee a ne time&material 😀 ) využijí hot swap: kód v IDE jednoduše opravíte, upravíte, přeložíte, a pokud jste debuggerem připojeni do JVM v které běží aplikace, hot swap nahraje novou verzi byte-kódu do JVM a nahradí jí kód původní. V těchto jednoduchých případech vám hot swap nezanedbatelně šetří čas. (Samozřejmě zde existuje mnoho omezení, která když porušíte, debugger zobrazí varování, že daná změna není podporována (změny v hierarchii tříd ale i například přidání public metody atd.) a restartu se stejně nevyhnete).

Hot Swap v Eclipse

Zatímco v Intellij Idee hot swap fungoval bez problémů a intuitivně, po přechodu na Eclipse mi hot code replace (jak se tato feature v eclipsu nazývá) v mnoha případech nefungoval. Po rekompilaci třídy se mi místo očekávaného nahrání nového byte-kódu na server zobrazovalo často následující varování:

Hot code replace failed

Trochu jsem pátral co je příčinou a dopátral jsem se. Na obranu debuggingu v Eclipsu můžu uvést, že je v tom (částečně nevinně).

Scheme change not implemented

Zásadní problém je ten, že Eclipse pro kompilaci nepoužívá sunovský javac, nýbrž svůj kompilátor (součást JDT Core component). Vyprodukovaný byte kód se liší (nezkoumal jsem do detailů jak…) od byte kódu class přeložených javac kompilátorem. Tyto rozdíly jsou pro debugger ale podstatné tak, že neumožní záměnu byte kódu za běhu. Podobný problém viz např. na news.eclipse.tools.jdt: Scheme change not implemented.

(Nutno podotknout, že důvod proč se mi na serveru objevuje kód kompilovaný jiným kompilátorem (javac než z IDE (eclipse compiler), je fakt, že instalace a deployment této aplikaci je poměrně komplikovaný proces a je pro něj přepdřipravena sada nástrojů (Ant skriptů), které je nutné ve správném pořadí použít v závislosti na prováděné změně).

Řešení

Řešení problému spočívá v použití stejného kompilátoru v obou případech.

První možnost je donutit Eclipse kompilovat pomocí javac. To jde podle mě jednoduše pouze pomocí nového ANT builderu a custom Ant scriptu. Což není zrovna elegantní.

Druhá varianta je donutit existující produkt, který obsahuje vlastní „Ant“ build systém, kompilovat pomocí Eclipse kompilátoru.

To jde celkem jednoduše:

  1. stáhnout ecj.jar (JDT Core Batch Compiler)z eclipse.org
  2. donutit Ant použít tento compiler: tzn. nastavit hodnotu Ant property build.compiler na org.eclipse.jdt.core.JDTCompilerAdapter
  3. a nakonec samozřejmě přidat ecj.jar do classpath (tip pro lenochy: nahrát tento jar do adresáře ant/lib)

Tímto donutíme Ant kompilovat pomocí Eclipse kompilátoru a hot swap neboli hot code replace funguje tak jak má. Malá poznámka na konec. Rozhodně bych nedoporučoval měnit použitý compiler na produkčním server, o čem tu pojednávám, je prostředí vývojáře! Více kompilování v Eclipse o možnostech použití vně Eclipse IDE se lze dočíst v online nápovědě: JDT Plug-in Developer Guide > Compiling Java code.

11 komentářů: „Eclipse – nefunkční "hot code replace"

  1. Anonymous 09/07/2007 / 12:39

    co je potreba pro aktivaci toho hot code replace udelat? remote debug mi slape, ale jak docilim toho, ze mi eclipse danou tridu po zmene nahradi?

    To se mi líbí

  2. Milan Boruvka 09/07/2007 / 12:56

    Cau Anonyme, Hot code replace se spusti automaticky, jakmile zmenis a prelozis nejaky zdrojak.Takze jestli si to chces vyzkouset, tak pokud mas vypnute automaticke buildovani v projektu, tak si zkus 1) otevrit nejakou tridu2) zmen ji (pridej napr. radek System.out.println(„neco“);3) Ctrl+Btrida se znova prelozi, a pokud tvuj remote debugging funguje, eclipse se pokusi nahrat novou verzi class filu na „server“V pripade ze pouzivas automaticke buildovani v projektu, tak predpokladam se ti zdrojak prelozi pote, co ho ulozis (takze bod 3) Ctrl + SMilan

    To se mi líbí

  3. Anonymous 09/07/2007 / 13:39

    dik, jeste mi to nejde prelozit s pouzitim toho:build.compiler=org.eclipse.jdt.core.JDTCompilerAdapterPise to chyby ohledne javy 1.5, napr:Syntax error, annotations are only available if source level is 5.0jinak dik moc

    To se mi líbí

  4. Milan Boruvka 09/07/2007 / 13:54

    Aha,tak bud je to tim, ze ten eclipse compiler nepodporuje anotace (mas posledni verzi?), ale spis bych to videl na to, ze nema defaultne nastaveny „source level“ na 5.0 ale na neco nizsiho…Na tomhle projektu pouzivam source-level 1.4. Ted je otazka jak predat tuhle informaci compileru – zkus hledat nejake dalsi property… kdyztak to sem pls. pripis.Milan

    To se mi líbí

  5. kooudy 17/12/2007 / 08:49

    Taxe mi zda, ze Hot Code Replace mi v Eclipsu 3.3 funguje nekdy i bez toho, ze bych kompiloval s JDTCompilerAdapter. Asi zazrak.

    To se mi líbí

  6. gaspoda 24/12/2008 / 14:09

    Ahoj, Vykoumal jsem dobre reseni:Pokud volate ant z prikazove radky, misto volani ant buildzavolejteant build -Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter -Dant.build.javac.target=1.5Tim padem odpadaji veskere modifikace na filesystemu.Predtim samozrejme zkopirujte jar do lib adresare vaseho antu.pekny stedry den 🙂

    To se mi líbí

Zanechat odpověď

Vyplňte detaily níže nebo klikněte na ikonu pro přihlášení:

Logo WordPress.com

Komentujete pomocí vašeho WordPress.com účtu. Odhlásit /  Změnit )

Facebook photo

Komentujete pomocí vašeho Facebook účtu. Odhlásit /  Změnit )

Připojování k %s