2050-01-01

Work on this site in progress

Work on this site in progress

After about a year offline, the site was just re-born from the former platform.
The current solution still has a few annoyances, but I'm fixing it :)

The most important thing is so sort out the pages that I brought from the former site.
That needs me to implement auto-generated directory indexes in the JBake platform this uses.
Until then, the blog below will contain all pages.

Another thing is the duplicated titles. That will go away soon.

... read more →
2050-01-01

Image Paths Test

Image Paths Test

← texy-64_med_med.gif

← ./texy-64_med_med.gif

← /favicon.ico

... read more →
2050-01-01

Image Paths Test, in a subdir

Odkaz

Image Paths Test, in a subdir

← texy-64_med_med.gif

← ../texy-64_med_med.gif

← /favicon.ico

... read more →
2018-08-01

NetBeans Wicket support wish list

NetBeans Wicket support wish list

  • One-step creation of html + java files
  • Validation in HTML files aware of wicket: namespace
  • Check consistency of HTML vs. Java files
  • Check consistency of property strings – e.g. new PropertyModel<String>(this, "path")
... read more →
2018-07-31

Dojmy z Ubuntu 8 – Hardy Heron

Dojmy z Ubuntu 8 – Hardy Heron

Update: Čtvrt roku poté – čtěte na konci.

Již delší dobu zkouším proniknout do světa linuxu – až podezřele moc mých známých jej postupně začínalo opěvovat.

Kdysi jsem zkoušel Knoppix, ale upřímně řečeno, nějak to nebylo ono. Příliš nestabilní a netransparentní.

Potom mi kamarád na notebook, který mi prodával, nainstaloval Gentoo. Pro nováčka v linuxu to také moc dobrá volba nebyla. Nechal mi na linux 20 GB z disku a když jsem chtěl nainstalovat standardní aplikace (asi Mozillu, OpenOffice atd), vše se chtělo překládat, ale během překladu došlo na disku místo a systém emerge se sesypal do nenávratného stavu.

Potom přišlo Ubuntu. Nevím přesně, kdy jsem si ho všimnul, tuším že u verze 5 a nainstaloval jsem šestku. Jelikož jsem to zkoušel na notebooku, nikdy jsem nedokázal vypnout LCD notebooku Acer TravelMate 8080 s ATI Radeon 9600 a obraz přesměrovat na LCD monitor 1600 × 1200 – a to jsem zkoušel všelicos vždy až do totálního rozpadu X serveru :-)

Ve verzi 7 (Gutsy Gibon) již byla jakási grafická utilita, která měla být GUI pro nastavení monitorů a rozlišení, ale ani ta si s touto konfigurací neporadila.

Přelomem pro mě byla verze 8 (Hardy Heroin), ale nikoliv proto, že bych v ní již dokázal přesměrovat výstup grafiky, ale protože jsem si koupil desktop :-) Do něj jsem dal starší disk, co se válel v počítači, který jsem prodal spolubydlovi, a na jeho posledních asi 30 GB šlo Ubuntu.

Spokojenost

Musím říci, že Ubuntu již dospělo do stavu, kdy i člověk jako já, který neprahne po tom, aby si vše kompiloval, nastavoval v texťácích a podobně, jej zvládne bez problémů nejen používat, ale i spravovat.

Zásluhu na tom má především vynikající integrace. Na úpravě Gnome je vidět, že Ubuntu se snaží vyjít vstříc uživatelům windows (což je podle mě dobře), a to se projevuje i jinde:

  • Automaticky konfiguruje hardware – já nemusel konfigurovat vůbec nic, a jede veškerý hardware. Dokonce Ubuntu komunita upustila od patetického zakazování („nepovolování“) „nesvobodných“ ovladačů nVidia; použijí se automaticky, což se dozvíte, až když otevřete správce hardwaru.
  • Automatická konfigurace se týká i připojování disků. Když tedy zasunete do USB flashku nebo externí disk, Ubuntu se zachová stejně jako Windows – detekuje, najde a připojí. Například mojí USB klíčenku připojí cca do sekundy jako /media/KINGSTON/.
  • Skvělé zpracování rootovských práv – žádné konzolové hlášky, vždy se pěkně zjeví okénko se žádostí o heslo, zadáte a jede se dál.
  • Grafické rozhraní instalačního systému apt-get, Synaptic, mě osvobodilo od ubíjejícího řešení závislostí, které jsem řešil s emerge v Gentoo
  • Standardně nainstalovaná sada aplikací je sice trochu mimo můj záběr, ale velice snadno jsem si doinstaloval to svoje.
  • Perfektně funguje Wine – spustil jsem Miranda IM a výsledek je úžasný (až na problémy s transparentnos­tí). Dobře šlape také HomeSite. Pro editaci PHP zdrojáků ale brzy přejdu na NetBeans (stejně snad už PHP dlouho editovat nebudu :-).
  • Krusader už také není takové ořezávátko jako před lety, nyní již pokrývá valnou část funkčnosti Total Commanderu, chybí jen podružné (např. možnost uložit do záložek nějaký příkaz – třeba cmd_View – jdou jen adresáře).
  • Nainstaloval jsem 64-bitovou verzi Ubuntu, vše běhá naprosto bez problémů, kromě Skype, ten se trochu cukal, že na x64 nechce, ale nakonec to vyřešilo sudo dpkg --force-architecture -i skype-...deb.
  • Java lítá velice svižně, vývoj v NetBeans je, řekl bych, plynulejší (nechrochtá pořád disk).
  • Místo FTPDrive jsem nainstaloval nějaký FTP filesystem, teď si nevzpomenu na jméno… šlape skvěle.
  • Editor z Krusaderu je mnohem lepší než notepad :-) gEdit už ale tak skvělý není, nemá dobře ošetřenou práci s kódováním.
  • Video šlape dobře hned po instalaci, a to i Flashe ve Firefoxu.

Je tu ale i pár nevýhod:

  • Antialiasing mi přijde nějaký nedotažený; ve Windows se mi písmo zdá mnohem ostřejší. V NetBeans jsem si na linuxu musel dát o dva stupně větší Courier New. Tohle je snad asi nejpalčivější problém, doufám, že se ukáže, že je to někde opravitelné.
  • Můj oblíbený nástroj pro vývoj SQL, MySQL Query Browser, funguje na linuxu dost jinak, o dost hůř. Nechápu proč, vypadá to, jako bych měl dva roky starou verzi, ale mám aktuální. //Update:// Naštěstí Wine nezklamalo, Query Browser pro Windows funguje bezchybně.
  • Chybí mi WinAmp, hlavně jeho Media Library a plugin AlbumList, ale ještě jsem nehledal náhradu, zatím stačí přehrávač z Ubuntu nebo XMMP.
  • Klávesové zkratky fungují nějak pošahaně:
    • V systému (tím myslím Gnome) nějak moc nefunguje klávesa Windows. Dá se to sice nějak ponastavovat, nastavení je ale zmatené a ani tak mi WinKey nefunguje.
    • Ve Firefoxu jsou některé zkratky jinak – nechápu proč, ale např. moje skoro nejpoužívanější Ctrl+E je zde pod Ctrl+K nebo Ctrl+J. Ctrl+E asi nic nedělá.
    • NetBeans se nastavení zkratek celkově chová nějak divně, ale to bude spíše chyba NetBeans.
  • Zkoušel jsem nainstalovat VirtualBox a nějak se mi podařilo nainstalovat více kernelů (verzí jádra). Následně systém startoval ze serverové verze jádra a mě to rozhodilo ovladače grafiky, zvuku a kdoví čeho ještě (v serverové verzi nejspíš vůbec nejsou). Naštěstí jsem tušil, že staré jádro aktualizace jen tak nezahodila, ale někde bude. Kamarád mi poradil, že když mám GRUB, tak mám jít hledat kamsi do /boot/grub a tam upravit menu.lst. Hodil jsem staré jádro jako default a zas všechno šlape. Vlastně to ani nebylo o moc složitější než s Windows, jen to stačí znát.
  • Linuxová komunita nějak nemá ráda různé utilitky pro správu serverů – dost mi chybí Apache Launcher a MySQL Instance Manager.

Co jsem ještě nezkoušel:

  • Tisk (asi půjde)
  • Visual Studio přes Wine (asi nepůjde)

Celkově bych to tedy shrnul tak, že Ubuntu 8 už je systém, který je možné dát do rukou zkušenému Windowsákovi, aniž by neustále něco šteloval, ladil a opravoval, jen aby moh už konečně pohodlně pracovat.

U mě to na přechod ještě nevypadá – ke změně systému mě obvykle dokope něco, co potřebuju, ale ve starém to není. Nic takového ale pro mě Linux zatím nenabízí:

  • Java je multiplatformní a vše běhá i pod Windows.
  • Mít super operační systém je fajn, ale prakticky se to u mě nijak neprojevuje – Windows mi nepadají, běhají rychle a viry nemám.
  • Gnome je moc hezké prostředí (narozdíl od hnusně přeplácaného kýčovitě nablýskaného infantilního KDE (já vím že se dá vzhled měnit, ale nechce se mi), ale na tom zas tak moc nesejde…
  • Compiz a Beryl jsou fajn věci, ale já, který Windows XP vždy ihned po instalaci přenastavuje do vzhledu Windows 2000, takové věci ani nevnímám.
  • Ve Windows toho mám dost rozdělaného – poštu, kontakty, záložky… nechci trávit hodiny exportem a importem
  • Hry – i když hraju zřídkakdy a dalo by se přebootovat…
  • a samozřejmě velmi vyladěný oblíbený software, který přeci jen nativně funguje o něco lépe: Total Commander HomeSite, Miranda IM, … (tím vyladěním myslím pluginy, nastavení, klávesové zkratky, atd atd… prostě ty tisíce malých drobností, které byste dohromady dělali celé dny, a přenést nejdou).

Takže ještě uvidíme – třeba Ubuntu 9 (třeba Instant Ichtyl?) přinese něco naprosto úžasného, co mě přetáhne. Nebo bude mít pravdu Pepa Kyrian, který říká: „Linux je návykovej… Uvidíš, do půl roka budeš linuxák.“ :-)

O čtvrt roku později

Je říjen 2008 a já používám Ubuntu již čtvrt roku jako hlavní pracovní platformu. Mé střednědobé dojmy z této distribuce a celkově dojmy z Linuxu dané jejím prostřednictvím shrnuji na následujících řádkách.

Fonty

V původním textu si stěžuji na antialiasing. Pokusil jsem se to řešit podle návodu na zprovoznění microsoftích písem v Ubuntu. Nevím, jestli jsem si už zvyknul, nebo tento návod zabral, každopádně s MS Courier New v NetBeans už se mi pracuje hezky a s fonty není problém.

Stabilita

Doufám, že tohle nebude číst někdo z kolegů, jinak by mě asi ukamenovali :-) Stabilita Linuxu jako desktopu mi přijde nižší než stabilita Windows XP. A hned musím uvést konkrétní příklady.

  • Uspání do paměti nefunguje vůbec, to je obecně linuxová slabost a ví to každý.
  • Uspání na disk funguje na Ubuntu dobře, dokud jste neprovedli update systému. Systém vám uspání s klidem odsouhlasí, ale při startu nabootuje normálně a vy máte vše, co jste neuložili, v řiti. Naštěstí mám ve zvyku Ctrl+S mačkat skoro za každým entrem, a jak NetBeans, tak Firefox naběhnou zhruba do stavu, v jakém jste je opustili.
  • Všeobecně jsou problémy s multimédii.
    • Různé formy videa se mi často nepodaří rozchodit – zejména v prohlížečích.
    • Audio dělá problémy – např. pauznutí Amaroku mi občas virtuálně „ukradne klávesnici“ – prostě v Gnome nelze psát, jediné, co funguje, je přepnutí do konzole (Ctrl+Alt+Fx).
  • Stabilita některých Linuxových programů je prachbídná, zejména po bootu z uspání. Mezi nejhorší patří Pidgin a Evolution, které mě svými pády štvou každý den. Ať je Outlook Expres sebehorší, nepamatuji si, že by mi kdy v životě spadnul, stejně tak Miranda.

Rychlost

S rychlostí je na tom Linuxový desktop v něčem dobře, v něčem bídně.

Firefox

Desktop, to jsou hlavně okénkové aplikace, a mezi nimi kraluje Firefox s několika desítkami otevřených záložek. A Firefox na Xkách, to je bída. Schválně si proveďte tento test: Načtěte delší stránku (třeba manuál MySQL v kuse), a mačkněte F11 (fullscreen). Zatímco na Windows se změna provede ihned (tj. nepostřehnutelná prodleva), v Ubuntu čekám několik sekund (cca. pět). Podobně přepínání mezi záložkami je velmi pomalé. Ale to může být problém Firefoxu – nevím.

Chování při zátěži disku

Nevím, zda je to nastavením, které neznám, ale Ubuntu se docela špatně vyrovnává s velkou zátěží disku. Celý systém začne reagovat velmi pomalu. Když jsem si na disk překopíroval svoji legální sbírku empétrojek a dal ji indexovat Amarokem a na pozadí běžely testy z EJB modulu TCK, celý systém se stal na několik desítek minut skoro nepoužitelným, a to mám 2× QuadCore. Windows jsou v takové situaci stále svěží a čilé, a to i na obyč DualCore.

Komunikace s médii, síťová komunikace

Naopak velmi dobře je na tom Linux v práci se sítí a nejrůznějšími protokoly. Například FTP lítá na Linuxu mnohem lépe. Jedinou výjimkou je implementace virtuálního diskového systému přes SSH (gvfs), která je schopná na minutu zaseknout programy, které naivně používá blokující volání na filesystem – a to jsou asi všechny: Gnome, Krusader, Konqueror… kupodivu programy psané v Javě (např. NetBeans) s tím problém neměly a prostě načítaly výpis adresářů postupně.

Stejně tak s některým HW asi dokáže Linux pracovat efektivněji, protože když jsem na Ubuntu kopíroval fotky z flašky, lítalo to kolem 32 MB/s, zatímco na Windows mezi 20 a 25 MB/s. Dlužno ale dodat, že šlo o jiné počítače, takže je to dost možná právě tím. Budu muset vyzkoušet na stejném…

Java

Podle mého soudu se Java na Linuxu stává velmi pozvolna, ale čím dál důležitější. Ačkoliv celkově se Linuxová komunita sestává z fundamentalistů, kteří si musí celý den překládat KDE, aby jim jelo o 1% rychleji a ušetřili tak denně několik sekund, postupně se k Linuxu (i díky projektům jako je Ubuntu) dostávají i lidé, kterým je šumák, jestli je všechno přeložené na míru mé architektuře, a raději vyžadují minimální námahu se správou systému a soustředí se na vlastní produktivitu.

Pro takové lidi se programy v Javě stávají mostem mezi Windows a Linuxem. Osobně jsem se již na Windows ustálil na několika málo programech, ve kterých trávím 90 % času (NetBeans, Firefox, Total Commander, Miranda, MySQL Query Browser, Outlook Express, Winamp). Když jsem pro ně před lety v Linuxu hledal náhradu, dopadlo to takto:

  • NetBeans/Eclipse jsou v Javě, krom potíží s fonty jedou bezvadně.
  • Pro Total Commander měla být náhrada Krusader, který ovšem v době, kdy jsem ho zkoušel poprvé, těžce zklamal, a tak jsem našel náhradu v něčem psaném v Javě – dost slušný prográmek, bohužel už si nepamatuju jméno.
  • Místo MySQL QB nyní používám SQuirrel SQL, což je velmi schopný nástroj, který se připojuje přes rozhraní JDBC, které už je k dispozici snad pro všechny databáze na světě, a disponuje mnoha dalšími skvělými vlastnostmi, jako je podpora mapování Hibernate atd.

Z těchto tří příkladů je myslím jasné, že Java pro Linux hraje důležitou roli, byť je většinou Linuxáků opovrhovaná (obvykle z jejich vlastní hlouposti). Dříve či později se Javovské projekty budou prosazovat čím dál více, a to zejména v oblastech, kde je třeba na vývoj technologií reagovat velice rychle, což jsou momentálně právě IDE, ale do budoucna může jít například i o prohlížeče.

Nyní tedy krátce k dojmům z Javy na linuxu.

Pokud jde o rychlost, žádný výrazný rozdíl oproti Windows jsem nezaznamenal. Trochu potíže jsem měl pouze s výchozí instalací OpenJDK (či jak se to jmenuje), kterou jsem chtěl nahradit JDK od SUNu, ovšem po odinstalaci se po ní například NetBeans vehementně sháněly, a musel jsem přepisovat konfigurační soubor (což jakožto původem nelinuxák samozřejmě považuji za nehorázný opruz :-)

Dále jsem na Linuxu poprvé v životě viděl pád JVM – až doteď jsem si naivně myslel, že Javě se taková věc nemůže stát, a ani jsem o ní předtím nikdy neslyšel. Až zde, při spouštění Antu, mi Java prostě sletěla. To mě vážně rozhodilo a můj dlouhodobý dojem z Javy trochu poškodilo. Nicméně když jsem to samé testoval na Windows, vše bylo OK. Takže asi jde o nedostatek linuxové implementace JVM. Kromě toho, po vypnutí JIT to prošlo i na Linuxu.

Jinak se mi celkově v Javě na Linuxu dělá lépe, prostě je vidět, že je tu více „doma“ – se všemi těmi konzolemi a parametry a konfiguračními skripty… :-)

Miranda

Miranda je pro mě natolik důležitá, že jí věnuju samostatný podnadpis :-) Ve Wine chodí naprosto skvěle, až na jedinou drobnost – IRC plugin. Ten se prostě nepřipojí. A jelikož IRC je hlavní IM komunikační kanál mojí společnosti, Miranda letěla. Pidgin je sice proti Mirandě velký shit, ale přeci jen mít na IRC Pidgin a vedle toho Mirandu na zbylých pět zpráv denně přes ICQ/Jabber… e-e.

Tak nějak celkově…

Jinak celkový dojem z Ubuntu, potažmo Linuxu, je dobrý. Žádné zásadní neřešitelné problémy, vše je docela intuitivní a funguje očekávatelně, není třeba nic moc konfigurovat, do konzole chodím jen za svou vlastní prací a nikoliv spravovat rozhašený systém…

Myslím tedy, že tvůrcům Ubuntu se podařilo udělat velmi dobrou kompilaci, která v sobě snoubí dostatek svobody, kterou přináší svět Linuxu, ale zároveň dostatečně dobře zakrývá holá střeva Linuxu, která bych mohl nechtěně potrhat při snaze něco nainstalovat/po­ladit/nastavit… jak se mi to dříve stávalo s distribucemi Knoppix, Gentoo, Debian, Suse, Mandrake a Ubuntu 6 a 7.

Pokud by se mě tedy nyní nějaký technicky netalentovaný kamarád zeptal, zda má zkusit „ten linux“, poprvé bych mu s klidným srdcem podal právě instalační CD Ubuntu 8.04.

„Canonical a komunita Ubuntu nepřispívají do upstreamu!“

Ubuntu je občas terčem kritiky komunity Linuxu, že má sice nejvíce uživatelů, ale nijak nepřispívá rozvoji Linuxu. No ale co se divíte? Copak to není logické? Kdo z komunity přispívá? Jsou to jednak programátoři, které programování baví natolik, že ve volném čase programují pro Linuxovou komunitu, a jednak profesionálové ze společností vyvíjejících Linux distribuce, jako je např Red Hat.

A teď:

  1. Jsou mezi uživateli Ubuntu nadšení geekové, hardcore kernel programátoři a hackeři? Určitě ne.
  2. **Dokázala by firma Canonical vydělat na uživatelích Ubuntu dostatek prostředků na to, aby zaplatila profesionály, kteří by vyvíjeli pro Linux? Určitě ne.

Výkřiky o tom, že z Ubuntu nejde komunitě žádný užitek, jsou tedy – podle mého – liché. Komunitě skutečně nejde žádný přímý užitek v podobě rozvoje software, ale – nemá snad komunita radost z nárůstu počtu uživatelů Linuxu? Nevolala snad komunita dlouhou dobu po řadových uživatelích? A teď, když se konečně našla distribuce, která „to konečně dala do pohybu“, adoranti jiných distribucí zhrzeně a závistivě sledují statistiky počtů instalací, sledovanosti diskutovanosti
a oblíbenosti instalací Ubuntu.

Dále tím, jak díky Ubuntu roste počet uživatelů Linuxu až natolik, že již se dá hovořit o poměru spíše než o počtu, nastávají různé vedlejší efekty:

  • Roste počet potenciálních programátorů – přispěvatelů Linuxové komunitě.
  • Tím, jak roste všeobecné povědomí o Linuxu, může se v budoucnosti snáze dostat na státní instituce, školy nevyjímaje, a tím se roztočí velká spirála nových uživatelů.
  • Významná část uživatelů přejde k jiným distribucím.
  • Zavedení Linuxu ve státních institucích povede k růstu obratu Linuxového byznysu – a tím nemyslím trička a hrnečky, ale podporu od specializovaných firem, jako je Red Hat – pokud po té příležitostí sáhnou.

Navíc, nehledě na to, jestli komunita Ubuntu přispívá do upstreamu, ve výsledku je celé Linuxové komunitě prospěšná – už jenom z této logiky věci: Pokud více jak cca. pětina všech uživatelů Linuxu používá právě Ubuntu, potom je jistě prospěšná minimálně pětině linuxové komunity.

... read more →
2018-07-31

Je Java jako Linux nebo jako Windows?

Je Java jako Linux nebo jako Windows?

Po napsání předchozího článku Výhody a nevýhody PHP se ozval Jakub Vrána a chvíli jsme si mailovali nad některými body článku, což se, jak to bývá, stočilo na srovnání PHP s technologií, kterou já preferuji – tedy s Javou.

V závěru jsme se dostali k tomu, zda je Java nebo PHP podobnější Linuxu nebo Windows. Zde je část z mailu:

Jednu věc nechápu a budu rád, když mi jako (předpokládám) fanda Linuxu vysvětlíš:

Jak je možné, že lidé, kteří preferují Linux před Windows, zároveň preferují PHP před Javou. Protože pokud bychom zobecnili vlastnosti a požadavky na systémy a plaformy, potom právě Java oproti PHP by byla jako Linux oproti Windows – technologicky vyspělejší, vývojově stabilnější, zpětně kompatibilnější, modulárnější, konfigurovatel­nější, víceúčelovější, a druhé ideologicky vykrádá první, přičemž to ani nezvládne dotáhnout do konce a zbyde jenom nedotažený hybrid zatížený historií svého vývoje.

PHP se mi zdá jako takový rozjetý mnohakilometrový vlak tažený slabou mašinkou, ke kterému stále napojují další a další vagóny – některé velice moderní, přepychové, a pokud jedete po rovince, vše je ok – ale pak přijde kopeček a mašinka se sotva vleče; a pak i v těch nejpřepychovějších vagónech poznáte, že je něco špatně. (Mašinka zde nepředstavuje výkonnost, ale právě ono „jádro“.)

Co je tedy podle tebe na PHP lepšího? Co tě k němu táhne kromě citové vazby? (Tvoje zásluhy v PHP komunitě zhruba znám a oceňuji, a chápu a znám z vlastní zkušenosti, že z takového rozjetého vlaku se velmi těžko vyskakuje.) Zkoušels někdy proniknout do J2EE? Znáš základní konceptuální rozdíly? Nechci tě nijak shazovat, jen mě zajímá, jestli se dokážeš vžít do mojí situace a pochopit tak, proč PHP tak „haním“.

Zdraví Ondra Žižka

Dovolím si zkopírovat Jakubovo resumé z článku Je PHP jako Linux nebo jako Windows?:

Jakub Vrána:

PHP a Linux – malé jádro, k tomu volitelné jednoúčelové knihovny s jednoduchým rozhraním.

Java a Windows – vše v jednom spravované přes komplexní objektové rozhraní.

Ondřej Žižka:

PHP a Windows (z pohledu programátora WinAPI): Silně proměnlivá technologie, v lecčems zpětně nekompatibilní, počáteční návrh špatný a směřující k lepšímu po vzoru lepších technologií, mnohé významné featury dodělávané ad hoc a nepřirozeně vmontované do návrhu.

Java a Linux: Stabilní technologie stavěná velmi rozvážně podle promyšleného návrhu dlouho laděného a diskutovaného mnoha IT firmami, silná a zaručená zpětná kompatibilita, standardizované API, mnoho různých použití (od embedded zařízení až po clusterované farmy serverů). Nejčastěji používaná rozšíření časem projdou procesem standardizace a začlení se do jádra, resp. JRE.

Jak někdo poznamenal v tamějších komentářích, Jakub posuzuje z pohledu technického, zatímco já se snažím spíše o ideologické srovnání – zkrátka principy, na kterých vývojáři a komunita dané technologie (ne)staví.

A to je z dlouhodobého hlediska mnohem důležitější – jistě chcete vyvíjet bez obav, že by příští major verze opět přinesla další sadu vlastností z jiných jazyků chaoticky splácaných dohromady se stávající verzí.


Aby byla debata co k čemu, měli bychom tato hesla něčím podpořit, případně vyvrátit. Pusťme se do toho :-)

Malé jádro

Jak změřit velikost jádra? A co je vůbec jádro? Řekněme, že je to ta část technologie, která je nezbytně nutná pro její běh.

  • Binárky pro Java Virtual Machine (interpret Javy) nejnovější verze mají cca 6 MB, což zahrnuje mimo jiné nativní knihovny pro zobrazování desktop aplikací, práci se zvukem, fonty atd.
  • K Javě patří ještě rt.jar, což je balík, ve kterém jsou knihovny obsažené ve standardní distribuci. Z toho se dá jako jádro počítat maximálně část z nich.
  • Jádro PHP, php6ts.dll, má cca. 14 MB (standardní distribuce windows), a tento modul je dále nedělitelný.
  • S okolními knihovnami (kromě API pro Apache, ISAPI a NSAPI) má kolem 20 MB.
  • php5ts.dll má cca. 5 MB, a spolu s okolními .dll má asi 10 MB.

Ale velikost dat není nejlepší ukazatel. Vyberme tedy jiné kritérium. Nabízí se možnost miniaturizace jádra technologie a složitost syntaxe, a Jakubem uvedená „komplexnost jádra“.

Komplexnost jádra

Co se týká „ne/komplexnosti“ jádra, tak si nejsem zcela jist, jak rozlišit, co v jádru je či není.

Pokud vím, v jádru Javy je jen několik tříd typu Object, String, Throwable, dále nativní metody základních systémových tříd, a tím to hasne; drtivá většina funkcionality JRE je již implementovaná v Javě a je oddělitelná.

V PHP je mnoho knihoven instalovatelných z repozitáře PEAR, a většina těch, které jsou ve Windows verzi v phpXts.dll, jsou na linuxu volitelné za cenu vlastní kompilace PHP. Nicméně nevolitelnou součástí jádra jsou funkce jako money_format(), apache_note() nebo highlight_file(), na kterých jistě technologie závislá není.

V tomto je tedy Linuxu podobnější Java, který v jádru obsahuje pouze to nutné (ať už pro funkčnost systému nebo kvůli výkonu).

Že by Java obsahovala vše v jednom je vyvráceno, a za „all-in-one“ technologii se dá považovat spíše PHP.

Windows a „vše v jednom“

U té architektury Windows bych řekl, že se Jakub seknul; od verzí NT až po XP (Visty neznám) je systém poměrně modulárni a dá se očesat skoro až na HAL.

Stejně tak předchozí verze Windows – existuje mnoho různých amatérských minidistribucí Windows 98 (bohužel teď je nenajdu).

„spravované přes komplexní objektové rozhraní“ – to nevím, co tím Jakub u Windows myslel. Na WinAPI není objektového nic, to je čisté C.

Možnost miniaturizace jádra

Až teprve v extrémních podmínkách se ukáže, co vše lze z „jádra“ vypustit, aby technologie stále byla sama sebou.

Takovými podmínkami jsou například mobilní telefony. Java šlape i na telefonech jako jsou několik let staré mobily Nokia. Zde se velikost jádra těžko určí, protože implementace je do jisté míry hardwarová.

Naproti tomu nejmenší mě známý výskyt PHP je verze PHP pro servery Novell, která je osekaná o leccos, a přesto má hlavní knihovna stále několik MB.

Řekl bych, že tím je v tomto bodě jasno – malé jádro a mnoho volitelných knihoven jednoznačně pasuje spíše na Javu.

//Update:// O tom, že Java je skutečně univerzální, se můžete přesvědčit např. na http://www.knihy.cpress.cz/BookDoc.asp?…, kde najdete publikaci pro grafiky, která se věnuje se programování skeneru pomocí Javy.

Složitost syntaxe PHP a Javy

Syntaxe Java oproti syntaxi PHP:

  • Nemá & reference
  • Není zde @ na umlčení
  • Nenahrazují se proměnné ve stringu
  • Nejsou zde věci typu __call, __autoload a další __*
  • Nemá # komentáře
  • Nemá systémová volání
  • Nemá podivné konstrukce typu Array($objekt, „VolanáMetoda“)
  • Nemá konstrukty, které se tváří jako funkce, ale nejsou funkce
  • Nemá operátory and, or, xor, !==, ===
  • Nemá konstrukty require, require_once, include_once, declare
  • Nemá alternativní zápis kontrolních struktur s dvojtečkou
  • Nemá global
  • Nemá $GLOBALS, $_GET, $_POST, $_COOKIE, $_FILES, $_ENV$_REQUEST

Naopak:

  • Má @anotace
  • Má generické <typy>
  • Má navíc klíčová slova pro různé účely (synchronized, transient, enum, volatile a další)

Java syntaxe je jednodušší než syntaxe PHP.

Závěr

Co se tedy týký připodobnění Javy a PHP k Linuxu a Windows, není mnoho argumentů, proč PHP připodobňovat k Linuxu a Javu k Windows – spíše naopak.

PHP je prostě na ocasu vývoje a s velkými obtížemi adoptuje vymoženosti jiných technologií (OOP, Unicode, výjimky, synchronizaci a sdílení, …) – stejně jako Windows.

Naproti tomu Java je spolu s C# a .NET na špičce vývoje na poli IT, podobně jako Linux na poli OS.


Jako tečku cituji člověka, který má PHP opravdu v malíku (a autora skvělého Texy!) – Davida Grudla:

Programovat v Javě umí kdekdo. O ASP.NET ani nemluvě. Jen v PHP píši skuteční hrdinové. Renesanční bytosti. Fascinující a neskutečně trpěliví lidé. Trpěliví od slova trpět. Třeba jako já.

-- David Grudl, http://latrine.dgx.cz/php-surprise

... read more →
2018-07-31

FreeTTS Troubleshooting

FreeTTS Troubleshooting

Java sound problems in Linux – LINE UNAVAILABLE

It's a JVM bug described here

Also here :

  1. Another possibility, which I have not verified, might be due to a delay that we put it to the closing of the currentClip.

    We put in this delay to workaround a Java Sound bug in Linux.

    The resulting scenario is: because the last clip was not closed before the next clip attempts to play,

    the audio device is still occupied, thus generating a LineUnavailable­Exception.

    Though, we've hardly experienced any problems with the JavaClipAudio­Player, so I doubt this is the problem.

Also here about „long sentences“:

The problem, it seems is in the code that breaks up a very long sentence. FreeTTS is designed to synthesize text with low latency. When given a very long sentence, such as in your example, it will decide that the sentence is too long to be synthesized in a timely fashion and break it up into smaller bits. This logic is rarely (if every executed) since it only is invoked when very long sentences occur. If I change your sample code to concatenate a period instead of a comma after every „Number xx“, things are synthesized just fine with no line unavailable error.

Workaround:

System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.openFailDelayMs", "100");
System.setProperty("com.sun.speech.freetts.audio.AudioPlayer.totalOpenFailDelayMs", "30000");

Also here :

If you disable the ARts sound daemon under KDE FreeTTS will work and not give the error:
LINE UNAVAILABLE: Format is PCM_SIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, big-endian Or something simular to t he error above. I believe the issue (and reply if I'm wrong) is the ARts daemon grabs the /dev/dsp device and prevents FreeTTS from using it. Though I don't run ETS (Enlightenment sound daemon) this daemon too, could be a problem for fellow FreeTTS users/developers. I believe this daemon too grabs on to /dev/dsp and prevents others from using it.

Also, testing the line availability :

  1. To test if an environment supports sound, copy the code in com.sun.speech.freetts.audio.JavaStreamingAudioPlayer.openLine()

    to a method in your application (remember to include the javax.sound.sam­pled.* packages).

    Before you call FreeTTS methods, call this method to see if your environment supports sound.

    If it does, remember to close the audio line, since FreeTTS will try to open it again.

Solution:

Fix FreeTTS according to this link, which is now unavailable because Oracle fucked it up. That page supposedly contained a fix for FreeTTS making it not vulnerable to that JVM's bug.

Also see:

Problem finding dependencies – ZipException` „Error opening ZIP file“

After I mavenized FreeTTS, I started getting an exception from JDK saying it can't read ZIP file somewhere in VoiceManager.java.

I used strace to figure out a „Error opening ZIP file“. That did not help because it did not tell me about JVM's calls to open() for some reason, but anyway, here's the command:

sudo strace -e trace=all -o log.txt \
java -Xrunjdwp:transport=dt_socket,server=y,address=4000 \
     -Djpda.listen=true -Djpda.address=4000 \
     -Dmbrola.base="`pwd`/../mbrola301"\
     -Dfreetts.voicespath="`pwd`/../mbrola301/voices"\
     -jar /home/ondra/work/BOTS/SpeechBot/SpeechBot-mavenized/target/SpeechBot-1.0-SNAPSHOT.jar \
     irc.eng.brq.redhat.com '#some'

The cause

The problem was that mavenization of FreeTTS and MBrola involved re-naming the .jar files.

But FreeTTS not only has hard-coded dependencies in it's MANIFEST.MF's Class-Path, which is quite stupid for a library, it also has code inside which actually relies on these data, which is the real peak of stupidity. So if you Mavenize such library, it ends up in different directories. So it will not usually work in IDE.

You need to flatten the dependencies to a single dir, using e.g. mvn dependencies:copy, see this example. You also need to set Maven to put all app's dependencies to it's jar's MANIFEST.MF's Class-Path – here it's ok because it's an app, not a library.

Then you need to manually rewrite all FreeTTS libraries' MANIFEST.MF in the local repository, so that you can rebuild your application. Change the Class-Path to reflect the names of the jar files; Usually, that means adding -<version> so it's e.g. cmulex-1.2.jar:freetts-1.2.jar:....

Then you run a shell command like

java -Dmbrola.base="`pwd`/../mbrola301"\
     -Dfreetts.voicespath="`pwd`/../mbrola301/voices"\
     -jar /home/ondra/work/BOTS/SpeechBot/SpeechBot-mavenized/target/SpeechBot-1.0-SNAPSHOT.jar \
     irc.eng.brq.redhat.com '#some'

Here you don't need to specify -cp because the deps are in the app's MANIFEST.MF as per the explanation above.

Problems finding Voices

I had some troubles make FreeTTS find MBrola's voices.

Don't forget to set the mbrola.base system property when you run your application, e.g.:

java -jar myapp.jar -Dmbrola.base="`pwd`/../mbrola301"

eventually you can set freetts.voicespath to different dir:

java -jar myapp.jar -Dmbrola.base="`pwd`/../mbrola301" -Dfreetts.voicespath="`pwd`/../mbrola301/voices"

There are few voices in FreeTTS with MBrola.

// This is a tiny database, contains only data for time demo app.
System.setProperty("freetts.voices","com.sun.speech.freetts.en.us.cmu_time_awb.AlanVoiceDirectory");

// Using this throws the ClassCastException. You need to recompile it.
System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");

// MBrola voices.
System.setProperty("freetts.voices", "de.dfki.lt.freetts.en.us.MbrolaVoiceDirectory");

Even after setting mbrola.voices, it kept finding only mbrola_us1, mbrola_us2, mbrola_us3. I added some voices from their web, but these were not listed as available. I guess I need some other VoiceDirectory implementation because the voices are hardcoded in KevinVoiceDirectory so I guess there's no dynamic loading despite all that mess in VoiceDirectory.java.

Weird ClassCastException for KevinVoiceDirec­tory, gone after re-compiling

After solving „Error reading ZIP“ by changing FreeTTS's jar's M­ANIFEST.MF's Class-Path value to reflect my jar names (mavenized), I started getting this:

Exception in thread "main" java.lang.ClassCastException: com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory cannot be cast to com.sun.speech.freetts.VoiceDirectory
        at com.sun.speech.freetts.VoiceManager.getVoices(VoiceManager.java:113)
        at cz.dynawest.speechbot.synt.MbrolaSpeaker.<init>(MbrolaSpeaker.java:38)
        at cz.dynawest.speechbot.SpeechBot.<init>(SpeechBot.java:25)
        at cz.dynawest.speechbot.SpeechBot.main(SpeechBot.java:65)

After re-compiling KevinVoiceDirectory and storing it in jar, it works.

... read more →
2018-07-31

Nabídka: Levný Java/JSP/J2EE hosting

Nabídka: Levný Java/JSP/J2EE hosting

S pozvolným přechodem od PHP k Javě a J2EE jsem narazil na problém – kam s ním?

Řeč je o nedostečné nabídce Java EE hostingů, a tedy nízká konkurence a z toho plynoucí vysoké ceny. Nejsem si zcela jist, zda java hosting je na správu náročnější než např. LAMP – podle zkušeností kamaráda, který si hostuje sám, je to jednodušší – prostě nainstalujete Apache Tomcat a hotovo.

Pro upřesnění – kamarádovi příliš nesedly aplikační servery (JBoss, IBM WebSphere, BEA WebLogic a další mamuti – zjistil, že pro něj je lepší řešení Tomcat a všechny featury z aplikačních serverů instaluje do Tomcatu jako jednotlivé moduly, případně je vkládá přímo do webové aplikace.

Mě samotnému se ovšem o server starat nechce – znamenalo by to najít server housing, koupit server, naučit se dobře administrovat Linux, … a jak říká Honza Svoboda – není možné dobře umět a dobře dělat všechno.

Jak jsem k Java hostingu přišel

S jedním kamarádem, zavilým Céčkařem a PHPčkářem, jsme (také :-) vedli debatu o výhodách a nevýhodách PHP. Tak jsme se dostali k tomu, že já vyvíjím nějaké projektíky v Javě, ale nemám je kam dát.

Kamarád měl tehdy zakoupený docela silný stroj (nějaké čtyřjádro s 8 GB paměti a čtyřmi SAS disky @ 10k RMP), který ovšem neměl jak využít, tak jsem na něm aspoň učil nějaké ty neuronové sítě z mojí diplomky :-)

Později jsem se dozvěděl od několika známých, že s Javou a J2EE mají podobný problém – mají J2EE backend, k němu by chtěli J2EE frontend, ale nenašli výhodný hosting a sami si hostovat nechtějí, a tak pro ně bylo cenově výhodnější sáhnout po nouzovém řešení.

Využit kamarádův stroj a znalosti ke zřízení Java hostingu se samo nabízelo. Netrvalo dlouho a stroj se přesunul do server-housingové společnosti a objevila se na něm Java a Tomcat. Zatím na něm běží jen moje J2EE „pokusy“, a stroj lačně čeká na další využití :-)

Co tedy nabízím?

Pokud byste chtěli na výše zmíněném serveru zkusit hostovat svoji J2EE aplikaci, můžete se ozvat a zprostředkuji kontakt.

Možná by se někomu mohlo po přečtení předchozích odstavců zdát nedůvěryhodné dávat hosting „ke kamarádovi nějakého Ondry Žižky“ – ale tento kamarád pracuje jako správce sítě v organizaci s řádově několika tisíci počítači a programátor systému automatické správy této sítě.

Nemá však zkušenosti s administrací Java hostingu, a proto to momentálně řešíme tak, že mám plný přístup k Tomcatu a spravuji si sám.

Řešení vašeho hostingu by vypadalo podobně – server by se nejspíše rozdělil na virtuální hostingy, ať už na úrovni Linuxu nebo Javy, a svůj virtuální hosting byste si spravovali sami.

Zkouška bude nejspíše zdarma – podle dohody.

Máte-li zájem, ozvěte se na ondra@dynawest.cz, kamarád mě pověřil zpracováním „úvodního kontaktu“ :-)

... read more →
2018-07-31

Je Java jako Linux nebo jako Windows?

Je Java jako Linux nebo jako Windows?

Přesunuto sem.

Po napsání předchozího článku Výhody a nevýhody PHP se ozval Jakub Vrána a chvíli jsme si mailovali nad některými body článku, což se, jak to bývá, stočilo na srovnání PHP s technologií, kterou já preferuji – tedy s Javou.

V závěru jsme se dostali k tomu, zda je Java nebo PHP podobnější Linuxu nebo Windows. Zde je část z mailu:

Jednu věc nechápu a budu rád, když mi jako (předpokládám) fanda Linuxu vysvětlíš:

Jak je možné, že lidé, kteří preferují Linux před Windows, zároveň preferují PHP před Javou. Protože pokud bychom zobecnili vlastnosti a požadavky na systémy a plaformy, potom právě Java oproti PHP by byla jako Linux oproti Windows – technologicky vyspělejší, vývojově stabilnější, zpětně kompatibilnější, modulárnější, konfigurovatel­nější, víceúčelovější, a druhé ideologicky vykrádá první, přičemž to ani nezvládne dotáhnout do konce a zbyde jenom nedotažený hybrid zatížený historií svého vývoje.

PHP se mi zdá jako takový rozjetý mnohakilometrový vlak tažený slabou mašinkou, ke kterému stále napojují další a další vagóny – některé velice moderní, přepychové, a pokud jedete po rovince, vše je ok – ale pak přijde kopeček a mašinka se sotva vleče; a pak i v těch nejpřepychovějších vagónech poznáte, že je něco špatně. (Mašinka zde nepředstavuje výkonnost, ale právě ono „jádro“.)

Co je tedy podle tebe na PHP lepšího? Co tě k němu táhne kromě citové vazby? (Tvoje zásluhy v PHP komunitě zhruba znám a oceňuji, a chápu a znám z vlastní zkušenosti, že z takového rozjetého vlaku se velmi těžko vyskakuje.) Zkoušels někdy proniknout do J2EE? Znáš základní konceptuální rozdíly? Nechci tě nijak shazovat, jen mě zajímá, jestli se dokážeš vžít do mojí situace a pochopit tak, proč PHP tak „haním“.

Zdraví Ondra Žižka

Dovolím si zkopírovat Jakubovo resumé z článku Je PHP jako Linux nebo jako Windows?:

Jakub Vrána:

PHP a Linux – malé jádro, k tomu volitelné jednoúčelové knihovny s jednoduchým rozhraním.

Java a Windows – vše v jednom spravované přes komplexní objektové rozhraní.

Ondřej Žižka:

PHP a Windows (z pohledu programátora WinAPI): Silně proměnlivá technologie, v lecčems zpětně nekompatibilní, počáteční návrh špatný a směřující k lepšímu po vzoru lepších technologií, mnohé významné featury dodělávané ad hoc a nepřirozeně vmontované do návrhu.

Java a Linux: Stabilní technologie stavěná velmi rozvážně podle promyšleného návrhu dlouho laděného a diskutovaného mnoha IT firmami, silná a zaručená zpětná kompatibilita, standardizované API, mnoho různých použití (od embedded zařízení až po clusterované farmy serverů). Nejčastěji používaná rozšíření časem projdou procesem standardizace a začlení se do jádra, resp. JRE.

Jak někdo poznamenal v tamějších komentářích, Jakub posuzuje z pohledu technického, zatímco já se snažím spíše o ideologické srovnání – zkrátka principy, na kterých vývojáři a komunita dané technologie (ne)staví.

A to je z dlouhodobého hlediska mnohem důležitější – jistě chcete vyvíjet bez obav, že by příští major verze opět přinesla další sadu vlastností z jiných jazyků chaoticky splácaných dohromady se stávající verzí.


Aby byla debata co k čemu, měli bychom tato hesla něčím podpořit, případně vyvrátit. Pusťme se do toho :-)

Malé jádro

Jak změřit velikost jádra? A co je vůbec jádro? Řekněme, že je to ta část technologie, která je nezbytně nutná pro její běh.

  • Binárky pro Java Virtual Machine (interpret Javy) nejnovější verze mají cca 6 MB, což zahrnuje mimo jiné nativní knihovny pro zobrazování desktop aplikací, práci se zvukem, fonty atd.
  • K Javě patří ještě rt.jar, což je balík, ve kterém jsou knihovny obsažené ve standardní distribuci. Z toho se dá jako jádro počítat maximálně část z nich.
  • Jádro PHP, php6ts.dll, má cca. 14 MB (standardní distribuce windows), a tento modul je dále nedělitelný.
  • S okolními knihovnami (kromě API pro Apache, ISAPI a NSAPI) má kolem 20 MB.
  • php5ts.dll má cca. 5 MB, a spolu s okolními .dll má asi 10 MB.

Ale velikost dat není nejlepší ukazatel. Vyberme tedy jiné kritérium. Nabízí se možnost miniaturizace jádra technologie a složitost syntaxe, a Jakubem uvedená „komplexnost jádra“.

Komplexnost jádra

Co se týká „ne/komplexnosti“ jádra, tak si nejsem zcela jist, jak rozlišit, co v jádru je či není.

Pokud vím, v jádru Javy je jen několik tříd typu Object, String, Throwable, dále nativní metody základních systémových tříd, a tím to hasne; drtivá většina funkcionality JRE je již implementovaná v Javě a je oddělitelná.

V PHP je mnoho knihoven instalovatelných z repozitáře PEAR, a většina těch, které jsou ve Windows verzi v phpXts.dll, jsou na linuxu volitelné za cenu vlastní kompilace PHP. Nicméně nevolitelnou součástí jádra jsou funkce jako money_format(), apache_note() nebo highlight_file(), na kterých jistě technologie závislá není.

V tomto je tedy Linuxu podobnější Java, který v jádru obsahuje pouze to nutné (ať už pro funkčnost systému nebo kvůli výkonu).

Že by Java obsahovala vše v jednom je vyvráceno, a za „all-in-one“ technologii se dá považovat spíše PHP.

Windows a „vše v jednom“

U té architektury Windows bych řekl, že se Jakub seknul; od verzí NT až po XP (Visty neznám) je systém poměrně modulárni a dá se očesat skoro až na HAL.

Stejně tak předchozí verze Windows – existuje mnoho různých amatérských minidistribucí Windows 98 (bohužel teď je nenajdu).

„spravované přes komplexní objektové rozhraní“ – to nevím, co tím Jakub u Windows myslel. Na WinAPI není objektového nic, to je čisté C.

Možnost miniaturizace jádra

Až teprve v extrémních podmínkách se ukáže, co vše lze z „jádra“ vypustit, aby technologie stále byla sama sebou.

Takovými podmínkami jsou například mobilní telefony. Java šlape i na telefonech jako jsou několik let staré mobily Nokia. Zde se velikost jádra těžko určí, protože implementace je do jisté míry hardwarová.

Naproti tomu nejmenší mě známý výskyt PHP je verze PHP pro servery Novell, která je osekaná o leccos, a přesto má hlavní knihovna stále několik MB.

Řekl bych, že tím je v tomto bodě jasno – malé jádro a mnoho volitelných knihoven jednoznačně pasuje spíše na Javu.

//Update:// O tom, že Java je skutečně univerzální, se můžete přesvědčit např. na http://www.knihy.cpress.cz/BookDoc.asp?…, kde najdete publikaci pro grafiky, která se věnuje se programování skeneru pomocí Javy.

Složitost syntaxe PHP a Javy

Syntaxe Java oproti syntaxi PHP:

  • Nemá & reference
  • Není zde @ na umlčení
  • Nenahrazují se proměnné ve stringu
  • Nejsou zde věci typu __call, __autoload a další __*
  • Nemá # komentáře
  • Nemá systémová volání
  • Nemá podivné konstrukce typu Array($objekt, „VolanáMetoda“)
  • Nemá konstrukty, které se tváří jako funkce, ale nejsou funkce
  • Nemá operátory and, or, xor, !==, ===
  • Nemá konstrukty require, require_once, include_once, declare
  • Nemá alternativní zápis kontrolních struktur s dvojtečkou
  • Nemá global
  • Nemá $GLOBALS, $_GET, $_POST, $_COOKIE, $_FILES, $_ENV$_REQUEST

Naopak:

  • Má @anotace
  • Má generické <typy>
  • Má navíc klíčová slova pro různé účely (synchronized, transient, enum, volatile a další)

Java syntaxe je jednodušší než syntaxe PHP.

Závěr

Co se tedy týký připodobnění Javy a PHP k Linuxu a Windows, není mnoho argumentů, proč PHP připodobňovat k Linuxu a Javu k Windows – spíše naopak.

PHP je prostě na ocasu vývoje a s velkými obtížemi adoptuje vymoženosti jiných technologií (OOP, Unicode, výjimky, synchronizaci a sdílení, …) – stejně jako Windows.

Naproti tomu Java je spolu s C# a .NET na špičce vývoje na poli IT, podobně jako Linux na poli OS.


Jako tečku cituji člověka, který má PHP opravdu v malíku (a autora skvělého Texy!) – Davida Grudla:

Programovat v Javě umí kdekdo. O ASP.NET ani nemluvě. Jen v PHP píši skuteční hrdinové. Renesanční bytosti. Fascinující a neskutečně trpěliví lidé. Trpěliví od slova trpět. Třeba jako já.

-- David Grudl, http://latrine.dgx.cz/php-surprise

... read more →
2018-07-31

Feature request discussion: Result sets stored in @variables

Feature request discussion: Result sets stored in @variables

Hello,

I got over several weeks of stored routines developement, and the most missed feature was a seamless mechanism for
- calling routines with a resultset in a parameter,
- retrieving a result set coming stored procedure,
- and eventually, for keeping a resultset somewhere without need to create a table.

All of this would be possible if we could store a resultset in a variable. So I have stated a feature request, not yet submitted to a buglist. First I would like to know others' oppinions and suggestions, because I am not much familiar with other DBMS.

I guess that such functionality would not be easy to implement and is not likely to appear soon. But it would be a giant leap for MySQL's stored procedures programming.

Here is a brief overview:

Create the result set and store it in a variable.

SELECT * FROM table1 INTO @resultset;
– or – SET @resultset = (SELECT * FROM table1);

Pass the result set into a stored procedure.

CALL StoredProcedure( @resultset );

Retrieving a result set from a stored procedure

CALL StoredProcedure() INTO @result; – or – SET @result = (CALL StoredProcedure());

More detailed formatted draft is here: http://ondra.zizka.cz/…ariable.texy

Now – what do you think? Would this ease your SP developement? Is there some better concept?

Thanks for comments.

... read more →
2018-07-31

Nevýhody PHP v praktických ukázkách __aneb__ Yet Another „Why PHP Sucks“ Page

Nevýhody PHP v praktických ukázkách __aneb__
Yet Another „Why PHP Sucks“ Page

Když jsem sestavil docela dlouhý, ale přesto neúplný seznam nevýhod PHP, ozvalo se celkem dost lidí s nechápavými dotazy, proč, co a jaktože.

„Proč pomlouváš PHP!?“

Nevím, jestli má smysl brát PHPčkářům jejich modlu. Někdo by se skoro mohl divit, proč se vlastně do PHPka tak pouštím. Inu, není to proto, že bych ho z duše nenáviděl, či tak něco… Prostě a jednoduše jsem čuchnul k lepšímu a od té doby –mě PHP čim dál více– vidím na PHP čím dál více chyb. A proč tedy píšu tyhle „remcy“, „hemzy“ a „ranty“? Nejspíš abych si ujasnil, zda je na tom PHP opravdu tak špatně.


Učit se novou technologii dá docela práci a chce to svůj čas. Jedním z mých oblíbených citátů z oblasti IT je:

Entrance to the world of Java is a cultural conversion, not a choice of one simple programming language over another.

Vlastně se mi ten citát líbí tak moc, že jej musím uvést v širším kontextu (byť není pro mou oblíbenou Javu nikterak příznivý):

Java Server Pages (link to Jakarta project) is reminiscent in nature of the Microsoft ASP framework, but intended from the ground up for enthusiasts of Java, Enterprise Beans and the whole industry that has grown up around them. A detractor of the juggernaut might describe it as being for people with more money than sense but we try to remain agnostic.

Choosing to use the panoply of tools and techniques engrossed by this world is not a tactical or pragmatic choice of how to get something built but is likely to based more on a strategic perception of how you believe the industry will develop. If all you want is an active website with a database backend, this is going to be overkill unless you already have the range of skills in-house. Entrance to this world is a cultural conversion, not a choice of one simple programming language over another.

Active Web Sites and Comparison of Scripting Languages (autor neznámý)

Já mám teď poslední prázdniny, a tak jsem se rozhodl využít poslední příležitost k této kulturní konverzi a dělám první vlastní komerční projekt v Javě a Java EE – a musím říci, že zatím ke vší spokojenosti a rozhodně nelituji. V PHP bych to už vzdal.

No a tím se dostáváme k praktickým symptomům nevýhod PHP, uvedených v onom článku. Mám velikou chuť rozebrat je opravdu všechny a dokázat, že k většině tvrzení mám pádný důvod a že se skutečně jedná o nevýhody; za to ale od nikoho na chleba nedostanu, leda by mě zaměstnal marketing Sunu, popřípadě RedHatu, IBM, BEA a dalších velkých hráčů na poli Javy :-)

Praktické projevy nevýhod v PHP

Pokud chcete rovnou na konec, tedy k hotovému zmrvenému produktu, čtěte Výsledek nasazení PHP v praxi aneb navrch huj, uvnitř fuj.

Ale vezměme to podle seznamu…

PHP: The work-around language

* PHP nemá danou politiku vývoje, místo toho nadále jen kopíruje prvky jiných jazyků.

Tohle byl asi hlavní důvod mého postupného rozčarování z PHP.

Když jsem se jako mladý učil PHP z čerstvě vydané knihy Jiřího Koska, PHP mě samozřejmě ohromilo: Psát dynamické webové stránky bylo najednou tak jednoduché. Prostě jste zkopírovali kód z ukázky, poupravili, a jelo to!

Rasmus Lerdorf o historii PHP

PHP se vyvinulo tak, že Rasmus Lerdorf ke své sadě nástrojů Personal Home Page Tools přidával stále další funkce, které uživatelé vyžadovali. Vypráví o tom takto:

„Nevím jak to zastavit, nikdy jsem nezamýšlel vytvořit programovací jazyk […] Nemám ani ponětí o tom, jak se píší programovací jazyky. Prostě jsem vždy jen přidával další logický krok v pořadí.“

Celý rozhovor s Rasmusem Lerdorfem najdete na server ITConversations: http://itc.conversationsnetwork.org/…etail58.html.

A přesně ve stejném duchu vývoj PHP pokračuje dodnes – That's the PHP way.

Jak se postupem času vyvíjíte, začnou vám některé věci dost vadit. Při psaní prvního „svého frameworku“ objevíte nepříjemné chyby v návrhu OOP a při použítí referencí se objevují záhadné chyby. Zejména pokud paralelně programujete v nějakém vyspělém jazyce s dobrým návrhem (Java, C#, JavaScript), časem se vám ztratí úsměv z tváře, čím dál častěji kroutíte hlavou a nakonec vzteky bušíte do stolu a kontrolujete blogy vývojářů PHP, jestli už se náhodou nechystají tu kterou pitomost z jazyka odstranit – a zase vás zklamou:

Naštěstí si ještě zachovali dost rozumu na to, aby neimplementovali úplné hovadiny, pravděpodobně proto, že se chystají i nadále jít cestou Javy a zavést deklarace.

If something isn't done soon, then more and more coders using PHP will move on to Ruby and Python and PHP will become the new Perl. I can hear it now, „What ever happen to PHP?“ or „Pfft, no one programs in PHP anymore!“ or „Man, I had to maintain legacy PHP application!“

-- Jacob Santos, PHP is turning into the Classic ASP

* Některé rysy jazyka svádějí ke špatným stylům programování

„That's the PHP way.“

A co některé, rovnou si je vyjmenujme:

Array() – rezignace na OOP.

Spoustu PHP skriptařů si nemůže vynachválit, jak moc je Array() univerzální – můžete jej použít jako pole, jako hash, jako frontu, jako zásobník, můžete s ním vybudovat vícerozměrné pole, ale i strom nebo obecný graf.

Jenže k čemu to je? Kdo potřebuje datový typ, který je zároveň fronta a zároveň strom? Kdo potřebuje indexovat v jedné struktuře jak podle pole, tak podle čísel? Jenom programátorská prasata. (But that's the PHP way).

Slušný programátor, který má ohled na ty, co budou kód po něm číst (včetně jeho samotného), po provedení analýzy a vytvoření návrhu pro každou třídu „entit reálného světa“ vyskytující se v návrhu vytvoří v programovém modelu odpovídající třídu a zachytí jejich vzájemné vztahy.

Ne tak programátoři v PHP. Zde je slušností co nejvíce poctít svátost boha Arraye a pokud je to byť jen trochu možné, pak jej použít, nejlépe hned v několika významech. Co na tom, že chceme reprezentovat strom obsahující objekty, které mají identifikátor a kolekci čísel? Jednoduše uděláme schizofrenní „Array()“, který má pod indexem ["id"] identifikátor, pod indexem ["numbers"] další Array s čísly a pod číselnými indexy ukryjeme potomky uzlu. Nebo obráceně? To je jedno… That's the PHP way!

FALSE – taktní, diskrétní a nevtíravé (ne)oznámení chyby.

Pokud existuje sebemenší šance, že dojde k chybě, slušný programátor vyhodí výjimku, kterou při pozdějším volání metody prostě nelze opomenout a musíte ji ošetřit – jinak se vám kód nepřeloží.

PHP skriptař však po vzoru nativních PHP funkcí vrací

Z těchto možností vybere náhodně. That's the PHP way!

Snad nikdo nepoužívá trigger_error(...) – jednak je to víc písmenek než return FALSE; a jednak by se pak někde musel mořit se set_error_handler(), a to je kopice psaní… radši vrátíme ten fóls. O tom, že později se na kontrolu chybové návratové hodnoty vykašle, nemusíte ani chvilku pochybovat; a pokud přeci jen, tak nejspíše vyplodí nějaký bug kvůli typové konverzi.

Reference

Ti opravdoví PHP experti (řekněme PHP-developer senior) však využijí pokročilou funkci jazyka, a to jsou reference! Jednoduše narvou návratové hodnoty do parametrů, a programátore, hledej:

If the value returned in errno is 0 and the function returned FALSE, it is an indication that the error occurred before the connect() call. This is most likely due to a problem initializing the socket.

Kde já jsem tohle viděl? Á, už vím! Einstein kdysi vymyslel takovou logickou hru:

Je pět pět parametrů, každý nese hodnotu nějakého typu. Když návratová hodnota boolean a v prostřední hodnotě je nula, potom včelař nebydlí v modrém domě. Nastal chybový stav?

Skutečně by nebylo lepší toto?

try{
  fsockopen(...);
}
catch( IOException ex ){
  ...
}

Array() – univerzální návratová hodnota.

Programátor v objektově orientovaném jazyce, pokud potřebuje z funkce více informací, než stačí pokrýt skalární hodnota jednoho typu, vytvoří si pro přenos informace třídu a vrací si objekt daného typu. Konec konců, když už se mu takový objekt odněkud vrací, pravděpodobně se jedná o třídu entit z reálného světa a tedy ji využije i jinde v modelu aplikace.

Lepič PHP kódu však má k dispozici mnoho úžasných vlastností jazyka PHP, jako třeba dynamickou typovost, a tak třeba jednou vrací string a jindy integer.

A pokud by nestačily ani všechny typy, co jich PHP má, tedy skalární hodnoty různých typů v kombinaci s FALSE a null, použije se prostě Array jako hash a do něj se pod nějaké indexy (někdy stringy, někdy divoké stringy, někdy čísla – to je fuk) narveme, co chceme.

That's the PHP way.

* Oficiálně není zaručena zpětná kompatibilita

V jednom nejmenovaném velkém českém portálu jedou doteď na PHP 4. „Ježiši!“, říkáte si. A máte pravdu! Jsou tam snad masochisti? Proč??

Odpověď je snadná:

Protože kdysi jakýsi manažer učinil rozhodnutí, že pojedou na PHP. Rok po tomhle rozhodnutí ho vyhodili a dodnes jeho volby litují, když při pohovoru musí uchazeče zkoušet z PHP 4 a jeho chyb v návrhu (vlastností, chcete-li) a místo přepisu do PHP 5, který zoušeli, ale stálo by je to několik měsíců přepisování (s výhledem dalšího přepisu do PHP 6, 7, 8… se již raději poohlížejí po technologii, kde zpětná kompatibilita není jen prázdná fráze.

Takových příkladů by se jistě dalo najít víc, ale asi to nemá smysl vypočítávat, protože zase můžete kontrovat Wikipedií a dalšími úspěšnými weby, které zůstávají u PHP (aspoň u prezenční vrstvy).

Obvyklá odpověď PHPčkářů je, že pokud by člověk nepsal jako prase, tak kód bez problémů běží i na nové verzi. To je samozřejmě naprostý nesmysl, který může pronést jen někdo, kdo se v používání PHP nedostal dál než k lepení ukázek zkopírovaných z manuálu PHP. Už jen změny v objektovém modelu a práci s referencemi činí ze starého kódu odpad, který je natolik nekompatibilní, že spíš než refaktorizace se vyplatí redesign a nová implementace.

* Programátor nemá zaručené cílové prostředí, mnoho věcí přímo ovlivňujících chování PHP lze změnit pouze mimo soubory projektu (v konfiguračním souboru php.ini)

Zde je to celkem jasné, každý lepší skriptař PHP už se potýkal s otázkou zapnuté / vypnuté direktivy magic_quotes_gpc. Vstup se zpracovává ještě před spuštěním skriptu, tudíž direktivu lze ovlivnit pouze mimo kód PHP, a ne vždy tu možnost máte.

U lepších technologií je dán standardní způsob distribuce projektu, který definuje prostředí, do kterého aplikaci vkládáte, a jeho součástí je i možnost nastavit prakticky cokoliv v rámci zdrojových souborů projektu.

* Projekty se musí šířit výhradně formou zdrojových kódů

Ano, existuje sice jakási extenze „BPEL“, a přiznávám, že jsem ji nezkoušel. Ale po mých zkušenostech s takovýmito hračkami bych jako vždy došel zklamání, protože by to jednak nepodporovaly hostingy, a jednak bych to nerozjel na své vývojové platformě.

* Nativně nepodporuje UNICODE (připravuje se pro verzi 6 – už skoro tři roky)

Tohle je opravdu obrovská ostuda PHP a jeden z bodů, který dokazuje, že PHP je několik let vývoje za ostatními technologiemi.

* Nepodporuje jmenné prostory

Další obrovská ostuda a důkaz zaostalosti PHP; fakt nechápu, že to nezabudovali již do verze PHP 3.

* Nekonzistentní pojmenování nativních funkcí a nejednotnost v logice pořadí parametrů

Velice často zmiňovaná vada, vadí i těm nejzamilovanějším PHPčkárům (a snad i Jakubovi Vránovi :-)

* Nedostatečná sebereflexe – datové typy „Třída“/„Funce“

Zkrátka chybí objekty pro reprezentaci tříd, pokud vím. Nemůžu tedy udělat např.:

public createObjectOfClass( Class cls, HashMap params ){
  cls.construct( params );
}

Odkazování se na třídu pomocí stringů je jen work-around („That's the PHP way“) a při práci v IDE je dost napřekážku.

* Nemožnost odkazovat se na metody objektů jinak než konstrukcí s Array()

Pokud chci předat nějaký objekt a jeho metodu (ve smyslu delegáta z C#), v PHP se to dělá takto:

...MyFunc( Array( $myObject, "thatObjectMethod" ) );

Tahat do mechanismu volání metod Array je opravdu škaredý work-around („That's the PHP way“™) a ukazuje na nedospělost OOP syntaxe PHP.

  • Podivné fungování referencí – asi nejzrádnější askept PHP
  • Je značně zatížené svým vlastním historickým vývojem

Je pravda, že oproti katastrofálnímu stavu z PHP 4 je v PHP 5 situace mnohem lepší; stále však zůstávají nečekané a o to zákeřnější seky. Asi před půl rokem jsem jeden řešil s kamarádem na IM, když to najdu, přidám.

Týkalo se to předávání pole. Jak jistě víte, pole není objekt, proto pokud jej chcete ve funkci měnit nebo chcete zamezit (mělkému) kopírování, je třeba jej předat referencí. Stejně tak jej musíte referencí propagovat do dalších kroků zpracování. Jenže reference stále fungují stejně jako v PHP 4, tedy tak, že v tabulce proměnných vzniká nový alias pro stejnou proměnnou. Tento alias zůstává v tabulce i po opuštění funkce, a po jejím opětovném volání a přiřazení reference proměnné se pole zpracovávané v předchozím volání přepíše tím, které zpracováváte nyní.

To je tak nechutná chyba, že tohle byl jeden z posledních hřebíčků do rakve PHP. Není to jediná chyba, a pokud jste někdy v PHP zkoušeli vyvinout něco složitějšího, jistě jste narazili na podobnou.

Vzhledem k tomu, že ani v PHP 6 nebude Array normální objekt a opět budou přítomny reference, vede mě to k závěru, že stejné chyby budou i v této verzi („Because that's the PHP way.“)

* Verze 5 již podporuje OOP lépe, ale nativní knihovna funkcí nadále používá procedurální paradigma.

Výsledkem je mimojiné toto:

strtoupper(str_replace("!!",".",str_replace("ahoj","nazdar",strtolower(trim(" Ahoj lidi!! "))));

oproti:

" Ahoj lidi!! ".trim().toLowerCase().replaceAll("ahoj","nazdar").replaceAll("!!",".").toUpperCase();

Je to asi jako v přirozeném jazyce říkat:

Chci zvětšit písmena v tom, co vznikne, když nahradím dva vykřičníky za tečku v tom, co vznikne, když nahradím „ahoj“ za „nazdar“ v tom, co vznikne, když převedu na malá písmena to, co vznikne, když odeberu netisknutelné znaky z okrajů " Ahoj lidi!! " '

místo

Vezmu " Ahoj lidi!! „, z okrajů odeberu netisknutelné znaky, převedu to na malá písmena, "ahoj“ nahradím „nazdar“, dva vykřičníky nahradím tečkou a převedu to na malá písmena, a to je výsledek.

U abstraktních datových typů Javy (zahrnující seznam, množinu, mapu, atd…) spatřuji hlavní výhodu v minimalizaci rozhraní daného abstraktního typu a v tom, že jsou definované jako rozhraní, nikoliv jako jediná implementace, protože to značně ulehčuje práci programátorovi různých knihoven.

Nedávno jsem si například během asi půl hodiny naprogramoval Mapu, která má jako backend tabulku v transakční databázi, a můžu jí používat všude, kde někdo očekává jako parametr Mapu.

To by v PHP s Array udělat nešlo – jedině na úrovni C implementace PHP. Šlo by to také naprogramovat jako třídu – ale potom to zas nebude kompatibilní s Array a nepůjde na to použít např. ksort().

Závěr

Má vůbec cenu, abych pokračoval?

Možná stačí už jen předat slovo

... read more →
2018-07-31

Poznámky a postřehy

Poznámky a postřehy

Zde najdete divokou směsici nápadů a myšlenek, od všednich přes technické po ryze filozofické, od vážných po naprosté bludy.
Vše bez záruky.

Most used passwords

Most used passwords from igigi's web.

Comparison of SSD vs. HDD disks – JBoss AS compilation

simple test performed on SSD disk Corsair X32.

Co je špatně v Českých Budějovicích?

Nemůžu si pomoct, ale v Českých Budějovicích mají radní opravdu zvláštní priority.

Nedávno rozhodli, že obyvatelé města ze všeho nejvíce potřebují splavnit úsek řeky Vltavy od centra města k Hluboké nad Vltavou. Nechali tedy za desítky miliónů vybagrovat bahno ze dna. Potom přišla povodeň, která vybagrované haldy opět spláchla do řeky.

A nyní, když se v rozpočtu nedostává peněz na „důležité“ věci jako je městská policie (o které se dozvíte na stránkách mestskapolici­e.unas.cz), radní zruší všechny dva noční autobusy.

Opravdu geniální!

Ještě štěstí, že už v tom kocourkově nežiju.

Náckové nejsou pravičáci, ale levičáci!

Prosím všechny novináře, zejména ty, kteří píšou úvodní hlášky ke zprávám, aby se vzdělali v pojmech levice a pravice.

Pravice, to jsou lidé, kteří požadují menší zásahy státu a větší svobodu jednotlivce. Krajní pravice jsou anarchisti.

Levice, to jsou lidé, kteří se o sebe nedokážou sami postarat, nezvládají samostatně myslet a hospodařit s vlastním majetkem, a potřebují nadiktovat, co je dobré a co špatné. Krajní levice jsou komunisté. Když se k tomu přidá krajní nacionalismus, jde o nacisty.

Zejména Česká televize soustavně uráží všechny svobodomyslné lidi, když ultralevičáky – tedy nacisty – řadí k jejich – zcela opačnému – názorovému proudu.

//2008–10:// Tak nám zvolili ČSSD

Nedá mi to nereagovat na výsledek krajských a senátních voleb. A vzhledem k tomu, že se jedná o osobní web, můžu si zde dovolit silná slova.

Každý, kdo volí ČSSD, je buď hodně hloupý a věří slibům této mafiánské strany, nebo je líný, nechce se mu pracovat a věří, že ČSSD zde zakonzervuje zbytky socialismu, nebo je součástí kolotoče a veze se v tom s nimi.

ČSSD je prostě strana, jejímž programem je zneužít ty méně inteligentní voliče jako výtah k penězům všech. Bohužel zde asi pláču na špatném hrobě, protože nepředpokládám, že kdokoliv dost inteligentní na to, aby používal internet a zajímalo ho programování, by volil ČSSD. Nicméně všechny voliče ČSSD varuji, že jestli zvolí ČSSD i do parlamentu, nastane další vlna odchodu inteligence národa do zahraničí, a pro dementy, kteří volí ČSSD, tu opět zbyde méně lidí, kteří na ně budou pracovat.

Po MSN se šíří phishing – yoimgz.com

Uživatelům MSN protokolu dnes chodí URL na server yoimgz.com. Na nic neklikejte, jedná se o phishing.

Phishing spreading over MSN IM network

Today, users of MSN communicator receive links to server yoimgz.com. Don't click it and do not enter anything – it's a phishing.

Návod na vázání uzlů u kravat

Kdo si má pořád pamatovat, jak se to šmodrchá? Já si pro jistotu dal návod na uvázání kravaty na web.

Dojmy z Ubuntu 8 – Hardy Heron

Své dojmy z přechodu na Linux v podobě Ubuntu 8 popisuji zde.

Jabber plugin for Miranda IM does not work under Windows XP 64-bit edition

Jabber plugin for Miranda seems not to work with 64-bit version of Windows XP.
However, Jabber addon in the developement branch, Miranda 0.8, works fine.
The same for Linux x64 and Wine, which supports only 32-bit applications (AFAIK). Download here: Miranda IM developement version

ATI Debevec Demo Music – DebevecRNLLoop.wav

I'm looking for the music used in ATI demo application „Rendering With Natural Light (RNL)“ (a real-time implementation of Paul Debevec's 1998 S­iggraph paper), available at http://ati.amd.com/…s/r9700.html.

Can anyone identify the tune?

Soudný den, sečtení činů a věčný život

Křesťané (a kdoví kdo ještě) mají jako součást svojí víry dogma, že nastane soudný den, při kterém přijedou čtyři jezdci apokalypsy, činy každého jednotlivce budou sečteny a ty hodné čeká věčný život.

Jako i ostatní věci velmi obrazně popsané v Bibli se i tato dá vysvětlit všelijak. Často se v historii potvrdilo, že mnoho „proroctví“ vzniklo buď špatným překladem, nebo pokřivením a antidatováním (ať už mylným či záměrným) popisu skutečných událostí.

Dovedu si docela dobře představit, význam soudného dne, sečtění činů a věčný život ve skutečnosti reprezentují osudný den, sečtení činů ve smyslu dosavadního vývoje lidstva a jeho aktuálního stavu, a věčný život je ve skutečnosti naděje na udržitelný rozvoj civilizace.

Mnoho textů v Bibli pochází od židovských i jiných filozofů, kteří se jistě zabývali i otázkou, v jakých kolejích se má lidstvo ubírat, aby nezahubilo samo sebe. A tak vznikla myšlenka, že může nastat situace kritická pro celé lidstvo, osudný den, kdy každý čin ve prospěch lidstva může mít vliv na další vývoj. A proto by každý měl konat s vědomím, že jen dobré činy umožní civilizaci v onen osudný den přežít, a tedy věčný život bude umožněn jen těm lidem (= takové společnosti), kteří budou jednat v její celkový prospěch.

Nejsem ani amatérský teolog, ani záhadolog, jen mi s blížícími se státnicemi přišla na mysl apokalypsa :-)
Pokud vás toto téma zaujalo, dobrý článek, potažmo web najdete zde: http://www.myty.info/view.php?…

Nedokonalost indexu Google

Google umožňuje vyhledat frázi uzavřením do uvozovek. Fráze znamená, že se slova v dokumentu vyskytují ve stejném pořadí, jako v uvozovkách. Bohužel Google při tom ignoruje výskyt čehokoliv jiného, třeba interpunkčních znamének.

Chtěl jsem vyhledat Pavla Hejtmana, odborného asistenta z Jihočeské Univerzity. Co čert nechtěl, hejtmanem Karlovarského kraje je jakýsi Josef Pavel, a web je proto plný výskytů posloupností slov typu „…řekl Josef Pavel, hejtman Karlovarského kraje.“ Když potom do Google zadáte "Pavel Hejtman", veškeré výsledky (kam až jsem vydržel proklikávat) odkazují právě na takovéto texty, a Pavel Hejtman jako by neexistoval. Naštěstí Pavel Hejtman je odborný asistent s akademickým titulem, proto je možné jej vyhledat aspoň pomocí Pavel Hejtman PhDr.

Neil Armstrong na Měsíci vyvěsil Bílou vlajku proti radaru

Hnutí Nenásilí informovalo o podpoře amerického astronauta v boji proti radaru v Brdech. NASA údajně uskutečníla mimořádný neplánovaný let na Měsíc, aby zde Neil Armstrong s dvěma členy vesmírného výboru hnutí Nenásilí mohli vyvěsit Bílou vlajku, symbolizující odpor proti imperialismu a proti závodům ve zbrojení se strany států pod vedením pitomců a v budování obranných systémů na straně zemí řídících se zdravým rozumem.

Více informací najdete na adrese http://www.nenasili.cz/…-radaru.html.

SETI@home podruhé

Vždy po koupi nového počítače si říkám, že je škoda, aby taková mašina běžela jen tak. Pustím tedy SETI at home. Navíc mi to v zimě docela pěkně vytopí pokoj.

Po nějaké době mašina zastará a já si říkám, zda přínos projektu SETI ospravedlní energetickou (a tedy i ekologickou) zátěž. Jaký je vlastně přínos projektu SETI?

  1. Výzkum v oblasti distribuovaných výpočtů – proof of concept
  2. Sociální dopady – jakás takás hrdost na svou zemi / univerzitu / firmu / tým / whatever…
  3. Snad nějaký dopad na astronomii, nevím ale jaký.

Co se týká samotného primárního účelu SETI@home, tedy hledání mimozemské inteligence, zatím kde nic, tu nic. Zatím tedy nevíme nic – ani, zda mimozemská inteligence existuje, nebo zda neexistuje. V tomto směru tedy zatím výsledky žádné. (Je také otázka, co skutečně projekt zpracovává – podle konspirační teorie mého kamaráda luští odposlechy systému –ECHOLON– ECHELON.)

Ospravedlňují tedy dosavadní výsledky mojich cca 200 W? Osobně jsem v tomto hodnocení trochu náladový. Nedávno jsem od SETI@home přešel na prokejt Rosetta@home. Po pár měsících mi ale provozovatelé SETI@home poslali mail, že nedávno jsem z projektu odešel, ale teď na přijímači v Areceibo pořídili zcela nový dekodér či co, který je schopný nahrávat až ze sedmi lokací na obloze najednou, a proto potřebují každý TerraFLOP. No budiž, znělo to tak přesvědčivě a prosebně, že jsem se nechal „ukecat“ :-)

Takže momentálně mám SETI@home puštěné 24 hodin denně, snad to k něčemu bude. Projekt Rosetta mě moc nepřesvědčil; SETI sice nemá žádné výsledky, ale aspoň o tom pravidelně a na poměrně slušné úrovni informují. Rosetta nemá žádné výsledky, ale to jen usuzuji z toho, že na webu projektu nejsou informace o tom, zda něco objevili, či nikoliv. Proto je pro mě projekt SETI@home důvěryhodnější a „výpočtuhodnější“.

Proč nikdo nepoužívá prohlížeč Opera

Prvně, omlouvám se několika promile lidí, kteří operu používají, například Zdeněk Roule, Satan a jejich přizpůsobivé okolí (konečně jsem je oba dostal na internet :-) )

Nicméně, z perspektivy tohoto grafu Operu skutečně nikdo nepoužívá.

Velmi krátce jsem se zamyslel, proč jsem ji kdysi nezačal používat i já, ještě v době, kdy Mozilla suite nebyla tak dokonalá, a Opera již byla zadarmo.

  1. Kvůli bannerům. Být zadarmo je pěkná vlastnost, ale aby se mi několik hodin denně vypalovaly do sítnice barevné blikající věci, na to já nejsem. Pravda, byly různé cracky, ale kdo by se s tim mořil – zas tak špatná ta Mozilla Suite nebyla.
  2. Výchozí skin. Nemůžu si pomoci, výchozí skin Opery je hnusný (YMMV). Hnusně šedivý s hnusnými hnusně zelenými ovládacími prvky – zkrátka, nedá se na to koukat.
  3. Pluginy. Pro Mozillu, potažmo Firefox, vzniklo již po krátké době existence (rozuměj od doby, kdy jsem ji začal já používat, tedy snad někdy ve verzi 0.7.x) tolik moc skvělých rozšíření, že se takovému stavu nemůže titěrná komunita fanoušků Opery –nikdy– ++v dohledné době++ přiblížit. Pro webového vývojáře je tato stránka věci zásadní.

Takže, důvod 1) padl, důvod 2) se drží a možná padne, důvod 3) will probably prevail forever. Nicméně pokud má Opera aspoň nahradit MSIE (libovolnou existující verzi – všechny jsou špatné), potom jí držím palce. Snad se někdy dostane aspoň na rozlišovací úroveň onoho grafu :-)

//Update:// Neoblíbenost Opery je tématem na http://www.lupa.cz/…zase-na-nic/. //Update:// Také tématem na http://pixy.cz/…ivate-operu/
a na http://www.misantrop.info/586891-pera.php.

SETI@home want's you back

Před časem jsem seznal, že projekt SETI@home již funguje dost dlouho na to, aby přinesl aspoň „nějaké“ výsledky. Zatím však kde nic, tu nic. Ačkoliv existenci ufonů připouští již i Vatikán, projekt SETI@home zatím církvi radost nedělá – žádní ufoni (přesto že Jiří Paroubek nabídl marťanům koaliční dohodu), žádná komunikace s blízkými hvězdami, ba ani prachsprosté podezřelé pípnutí nebylo identifikováno. Rozhodl jsem se tedy, že nebudu nadále plýtvat cca 120 W na bezvýsledné výpočty a projekt opustím.

Jenže, po pár měsících mi napsali opravdu dojemný dopis, no posuďte sami:

Dear Astar Seran:

We'd like to invite you to reconnect with SETI@home. Our records show that you've been with SETI@home since 09 February 2008, but it's been 104 days since you last returned a work unit. We want you back, and here's why:

These are exciting times for SETI@home. Last year we implemented a new SETI@home data recorder at the Arecibo radio telescope in Puerto Rico. This recorder is attached to a state-of-the-art multibeam receiver, so we can now measure signals from 7 positions on the sky at once, with greater sensitivity to weak signals compared to the data from the flat feed antenna we've used since 1999. We've greatly increased the sensitivity of our data analysis, and the likelihood that we'll find the first signs of extraterrestrial life. We're also close to releasing a second application, Astropulse, which will look for extremely short pulses of astronomical (and possibly intelligent) origin.

With these new developments comes an increase in required computing power, for which we depend on people like you. We hope you will consider signing back on with SETI@home, and help in this wonderful scientific venture.

Jistě uznáte, že když nainstalovali tak skvělý přijímač, musím jim dát ještě šanci. Zvlášť jako osoba spjatá s masovým rozšířením SETI@home v ČR :-)

Kdo si vzpomene, kde byla tato ikonka vystavená a přilákala kolem 20 000 návštěvníků?

Výrazy, které na google nejsou

Je s podivem, že při vší té obsáhlosti webu, potažmo internetu, na Google stále nenajdete některé (zcela nezbytné) fráze.

Již se mi stalo několikrát, že jsem zadal frázi, u které jsem se bál spíše velkého počtu odkazů, ale rozhodně by mě nenapadlo, že se v indexu Google (který má nejobsáhlejší index ze všech vyhledávačů) vůbec nevyskytují.

Tak například:

Proč ředkvičky pálí?

Zajímalo mě, proč ředkvičky pálí. Jediný trochu relevantní odkaz vede na otázku diskutérky –

„Proč pálí ředkvičky jak sviňa? Já myslela, že to pálí proto, že jsou nerovnoměrně zalité. ale to já nemám. Nuže?“

Takže vím, že ředkvičky nepálí proto, že by Tigra neuměla zalévat zahradu.

Napadlo mě, že by to mohlo být omezeností českého internetu, kde najdete gigabajty diskuzí o tom, jestli je Paroubek blbec nebo velký blbec, ale o ředkvičky se nezajímá. Zkusil jsem tedy do Google zadat radish burns, radishes burn, why radishes burn. Bez výsledku.

Potom jsem si vzpomněl, že na otázky by se měl specializovat server Ask Jeeves. Zkusil jsem se ho tedy optat: Please, Why radishes burn? A ejhle, pod zadávacím polem mám nápovědu – mám se zeptat, Why Are Radishes Hot. Jenže na tento dotaz opět dostávám odkazy na stránky, které otázku stavějí takto:

Q. What causes my radishes to be „hot“?
A. The „hotness“ of radishes results from the length of time they have grown rather than from their size. The radishes either grew too slowly or are too old.

Nebo:

Q: What makes radishes hot? My radishes this year are almost too hot to eat.
A: Radishes get hot for a number of reasons. If they are too old they are hotter, and if they were grown under low fertility or if they got too dry, and their growth was not as fast as it should have been, then they turn hot.

Takže jsme zase tam, kde jsme byli. Já chci vědět, která látka v ředkvičkách pálí. Vite někdo, proč ředkvičky pálí?

Update: Tak výsledky vyhledávání se lehce změnily a do popředí se dostala odpověď Emeritního profesora Zahradnické fakulty Mendelovy zemědělské a lesnické univerzity Karla Kopce z Lidových novin:

Ředkvičky při krájení nebo rozkousání uvolňují látky, které jim dávají typickou vůni a chuť i větší či menší štiplavost (pálivost). Ředkvičky totiž obsahují glukozionoláty, z nichž se v porušených buňkách uvolňují aromaticky i chuťově výrazné složky – izothiokyanáty. Je jich řada a kromě chuťových vlastností mají také antimikrobiální účinky a výrazný vliv na lidské zdraví. Přispívají ke zlepšení imunity, omezují riziko některých chorob, podporují stravitelnost ostatních pokrmů. Právě proto se doporučuje zvýšit konzumaci ředkviček a ředkví až na jeden kg ročně.

Tak super, už to vím a universum se opět dostává blíže k rovnováze.

Jaká je výhřevnost vosku?

Další věcí, která mě zajímala, je výhřevnost vosku. V domě nám už netopí, okna profukují, a tak se stane, že mám na pokoji 17 stupňů i při neustále puštěném počítači. Kamarád mi poradil, že když nechá na pokoji hořet čajovou svíčku, tak během zhruba čtyř hodin, po které svíčka vydrží, vzroste teplota v pokoji tak, že musí větrat. Jenže jeho pokoj má 16 m2. Já jsem zapálil pole 6×6 čajových svíček, ale teplota vzrostla jen o půl stupně za hodinu. Proto jsem si chtěl ověřit, jak by se měla teplota vyvíjet teoreticky. Bohužel, výhřevnost vosku jsem na internetu nenašel. Stačila by mi jen orientační… nevite? :-)

Vícerozměrné jazyky

V teorii formálních jazyků se vyskytuje pojem „Vícerozměrné jazyky“. Pokud si ale tento termín v češtině zadáte do Google, mlčí.

Je třeba zadat „multidimensional language“ a dozvídáme se, že vícerozměrný jazyk je takový, jehož výrazy jsou tvořeny ve více rozměrech. Nic víc jsem ale nenašel – google dává pořád dokola tuto stejnou slovníkovou definici. (Kandidát na pojem ve wikipedii, nechcete se toho někdo ujmout a vytvořit wiki článek?)

Moucha košovka

Až do zaindexování tohoto článku se na Google vyskytuje jediná stránka na tato dvě slova a žádné stránky pro celou frázi. Muška košovka je moucha octomilka (viz Octomilka na Wikipedii).

Trojité rovnítko, trojité rovná se

Další nenalezené vyhledávané fráze možná přibudou časem. Teď mě jen zajímá, kolik lidí na světě je kdy bude vyhledávat.

Analytik-programátor otročí za jídlo, šaty a vzduch

Nabídka pracovního místa

Ještěři z pekel hledají programátora na pozici analytik-programátor.

Hledáme: Nekreativního otrockého programátora, nejlépe s čipem v těle.

Nabízíme: Jídlo, šaty a vzduch.

Popis pozice:

Více informací na www.vesmirni-lide.cz.

Vazba diplomové práce v Českých Budějovicích

Opět se blíží doba, kdy si diplomanti musejí nechat svázat diplomovou práci. Chtěl bych tedy všechny studenty varovat:

Nedávejte si diplomku svázat k firmě ZDECO!

Nejsem sám, kdo měl s touto firmou, sídlíci Na Sadech, potíže. Vazbu jedné DP zkazili (nevložili zadání), druhou zase svázali tak, že papíry pár minut po převzetí vyjely z desek. Tím se pochopitelně papíry zmačkaly a diplomka zničila. Chtěl jsem tedy vrátit peníze a uhradit škodu. Byli proti, jediné jejich přípustné řešení bylo, že mi do stejných desek znovu secvaknou nové listy. Nefér firma, sdružení obrany spotřebitelů na ně.

Klíčová slova: svázání, vazba, diplomová práce, diplomka, České Budějovice, desky, Jihočeská univerzita, ZDECO, Na Sadech.

Vypouštění vnitřního draka

Zajímavé. Spammeři procházejí literárním vývojem.

Mnozí si pamatují, že na začátku spamu, kdy jsme ještě maily stíhali třídit ručně bez použití filtrů, chodily suché výzvy typu „Enlarge your penis“. To nemohlo zaujmout snad nikoho kromě debilů, na které ale asi kampaň mířila, takže vpořádku.

Později první nastala vlna obrany proti spamu, založená na primitivní metodě „předmět / odesilatel / zpráva obsahuje slovo …“ → letí do koše. Krásné, jednoduché, ale fungovalo nanejvýš pár měsíců.

Protože poté začali spameři nahrazovat různé znaky kombinacemi jiných, které je připomínají. Nejprve blízce („EnIarge your penis“), potom vzdáleně („Buy cheap V|agra“). Potom se spameři rozdělili na dvě větve – ti sofistikovanější, pro něž je spam výnosným obchodem, začali používat pokrokové metody. Ti méně pokrokoví zůstali u staré metody, jen ji dotahovali do krajností: Bai C|-|34-p Uu|aaaaagg RRRaaa!, C|a L|S, kde ještě tušíte, že si máte nutně koupit levnou ViiaaggRRuu nebo Cialis, ale když mi pak příjde výzva, uh Buoy Cheap See - Alice, už je to skoro jazykový hlavolam. Takový spam už přece není pro blbce :-)

Ovšem i na takové se později bayesovské filtry a antispam algoritmy naučily, a tak těm lepším spammerům opět nezbylo, než sáhnout k jinému kroku: Omezit kvantitu a zvýšit kvalitu.

A tak mi již denně nechodí dvacetkrát Unrecognizable Rolex replica, ale mám ve schránce první nesmělý náznak literárního útvaru:

Release your inner dragon with the help of bluepill!

Mmm… představil jsem si sám sebe jako mužskou verzi té žluté ninja-holky z Kill Billa, jak ve stylu Jamese Bonda zachráním nějakou šikmookou kočku a pak na ni vypustím svého „vnitřního draka“ :D Plný očekávání dalšího kvalitního obsahu jsem mail otevřel… ale zklamal mě. Nedočkal jsem se ničeho víc než

If you cannot act the way you want, take some blue-coloured pills!

Tak to je, pánové, trochu slabé. Až mi napíšete aspoň desetistránkovou motivační povídku, můžeme začít vyjednávat o nějaké té cheap částce – třeba dva centy za příběh. Do té doby vydělávejte nadále na blbcích, co koupí a sní „modré pilulky“ z pochybných zdrojů.

Tip na cestování hyperprostorem

Problémem mezihvězdného cestování je nutnost těleso urychlit na rychlost přijatelnou k dostatečně rychlému přesunu, a potom jej zase zabrzdit. Co kdybychom ovšem využili princip kolotoče?

Mohli bychom v jednom bodě (třeba i našeho prostoru) „upoutat“ „lano“, na konec lana připoutat těleso, které má cestovat, přemístit jej (stále v našem prostoru) na vzdálenost lana, a potom ho začít roztáčet. To by znamenalo udělit mu takovou energii směrem do jiného prostoru, která by stačila k jeho přemístění do výchozího bodu opisované „kružnice“. Po jeho opětovném objevení v našem prostoru ve výchozím místě bychom mu udělili další impulz, a takto jej postupně urychlovali.

Po dosažení určité rychlosti oběhu by už byl problém jenom „nastoupit“ a „vystoupit“. Jsou dvě možnosti:
Jednak postavit obíhajícímu „dopravnímu prostředku“ náklad do cesty. Vypadalo by to asi tak, jako kdyby bagr jel nadzvukovou rychlostí a někde cestou nabral písek. To by jistě nákladu příliš neprospívalo.
Druhou možností je před nástupem náklad urychlit ve směru zbylého rozměru na rychlost dopravního prostředku. Energetická náročnost by ale byla asi stejná, jako na zrychlení a ubrždění nákladu při přímé cestě naším prostorem. Je celá tato teorie tedy k něčemu?

„Dopravní prostředek“ by naším prostorem procházel jen velmi krátkou dobu. Problém urychlení nájkadu by tedy bylo vyvinout dostatek energie v krátkém čase. Co ale udělat další takové kolečko, tentokrát menší, a jen za účelem naložení nákladu? Jako oběžný bod by mohla sloužit nějaká těžká hvězda.

Celé to pochopitelně počítá s rozvinutým dalším rozměrem, nikoliv smrsknutým, jako teorie superstrun.

A teď hlavní otázky:

  1. Jak vytvořit lano? Gravitací?
  2. Proč to neudělat ve známých rozměrech?
  3. Má vůbec náš vesmír více jak tři rozměry?

Motiv zápisu tohoto s největší pravděpodobností blábolu hledejte v teorii myšlenkonů Terryho Prachetta :-)

Hledám řešení úlohy

Hledám řešení této otázky:

Máme N-rozměrný prostor. Kolik (N-1)-rozměrných prostorů rozdělí onen prostor na X N-rozměrných podprostorů?

Nevím, kde hledat odpověď. Víte (ji) někdo?

//Update:// Mám řešení. Dík patří Karlovi Kyrianovi za pomoc. Řešení jsem zpracoval ve svojí diplomce.

V jednorozměrném prostoru dělí každá nadrovina (bod) prostor přímky tak, že přibude další jeden podprostor. Ve dvourozměrném prostoru vzniká s každou přidanou přímkou vždy o jeden prostor více než s předchozí. Ve trojrozměrném prostoru potom vzniká s n-tou přidanou rovinou o tolik více podprostorů, kolik podprostorů vzniklo ve dvourozměrném prostoru při přidání n-té přímky. Obecně potom pro N-rozměrný prostor platí, že přidáním n-té nerovnoběžné nadroviny přibude tolik podprostorů, kolik celkem jich přibylo rozdělením N-1-rozměrného prostoru n nerovnoběžnými nadrovinami. Rekurentní výpočet by potom mohl vypadat takto:

Případně přímý výpočet vypadá takto:

Potřebujeme ovšem znát opačný výpočet – známe dimenzionalitu prostoru, víme, kolik chceme výsledných podprostorů, a chceme vědět, kolik nadrovin jej takto rozdělí, resp. kolik máme použít neuronů na první vrstvě. Výpočtem se zde nebudeme podrobně zabývat, stačí nám jeho odhad. Výše uvedený výpočet se dá odhadnout jako  

Vyjádření n potom vypadá takto:

kde (pro připomenutí) n je počet nadrovin, N je dimenzionalita prostoru, p je počet podprostorů a e je Eulerova konstanta.

Ve výpočtech zacházíme s dimenzionalitou prostoru. Ta je rovna počtu vstupů sítě.

ICQ Hoax / phishing

Chodí nový ICQ phishing: New ICQ phishing appeared:

Hello,

Your NEW ICQ password is: A4T4jXMh

Remember – your ICQ password is case sensitive.

After you login to your ICQ number, you might want to consider changing your password to a more complex one.

Your new password must contain 6–8 characters. It should include English upper and lower case letters and numbers.

Try to select a random password that will be hard for others to guess. (Example: …)

Here's how you change your password: In ICQ 5: Click the Main Menu button > Preferences and Security → Password. In ICQ Pro versions 2000a through 2003b: Click the ICQ/Main button->Security & Privacy Permissions->Password. In ICQ 6: Click the Main menu button > select ‚Options‘ > under ‚Privacy & Security‘, select ‚Privacy‘ > click ‚Change my password‘.

Heslo si pochopitelně neměňte, buď je to kachna, nebo podvod. Of course, do not change the password – it's either a fraud or an hoax.

... read more →
2018-07-31

Programování

Programování

V sekci Programování najdete texty, které vyprodukuji na toto téma. To zahrnuje nejen jazyky a technologie jako PHP, Java a J2EE, C# a .NET, XSLT, SQL, ale i různá paradigmata (OOP, AOP) a oblasti výzkumu (neuronové sítě).

Obecně

Linux filesystem cache flush

# Will clear all the fs cache. Do a ’sync’ before to flush more caches.
echo 1 > /proc/sys/vm/drop_caches

http://mtj.wordpress.com/…-read-cache/

Java

<!--

-->

PHP

SQL a MySQL

Web, JavaScript, AJAX, Canvas

Neural Networks and Artifical Intelligence in General

  • Neural Networks
  • Criss-cross – a school project. An attempt for a AI for the criss-cross game, with re-inforcement learning.
  • Imagenetics – Images generated by genetic algorithms, rated by the user (that means, you :-)

Různé

... read more →
2018-07-31

Ondřej Žižka – Diplomová práce – Návod na zprovoznění

Ondřej Žižka – Diplomová práce – Návod na zprovoznění

SQL skripty

Všechen SQL kód potřebný ke vytvoření databáze je v adresáři sql/ v těchto souborech:

  • JR - Procedury a funkce pro DP.sql
  • JR - Tabulky s importovanými daty pro DP.sql
  • JR - Tabulky s převedenými daty pro DP.sql
  • NN - Procedury a funkce pro DP.sql
  • NN - Tabulky s daty.sql

Soubory s předponou NN obsahují SQL pro rekonstrukci implementace neuronových sítí. Soubory s předponou JR obsahují SQL pro vytvoření databáze jízdních řádů a příslušných uložených procedur.

Další dva soubory obsahují ukázkové naučené neuronové sítě:

  • JR NN - Naučená síť pro zastávku 5.sql
  • NN - Naučená síť XOR.sql

Instalace MySQL, vytvoření databází a nastavení práv

Nejprve je třeba nainstalovat standardní distribuci MySQL 5.0 nebo vyšší (stahujte zde).

Poté je třeba vytvořit dvě databáze a nastavit uživatelská práva pro uživatele, který je bude používat. Následující kód vytvoří databáze neural_network a jizdnirady_cb a nastaví veškerá práva k nim uživateli OndrejZizka, který se může připojit odkudkoliv (‚%‘):

CREATE DATABASE neural_network;
CREATE DATABASE jizdnirady_cb;
GRANT ALL ON neural_network.* TO OndrejZizka@'%' IDENTIFIED BY 'BezpecneHeslo';
GRANT ALL ON jizdnirady_cb.*  TO OndrejZizka@'%' IDENTIFIED BY 'BezpecneHeslo';

Tyto úkony lze pohodlně provést v GUI nástroji MySQL Administrator, případně vykonat SQL příkazy v nástroji MySQL Query Browser, viz níže.

Rekonstrukce databáze z SQL souborů

SQL skripty jsou vytvořené nástrojem MySQL Administator, oficiálním nástrojem pro administraci databázového systému MySQL (stahujte zde).

Nejsnazší cesta, jak z nich vytvořit svoji kopii databáze, je použít právě tento nástroj. Nezkoušejte načíst procedury v nástroji phpMyAdmin – ten je plný chyb a nezvládne skripty správně přeparsovat.

Pozor! Pokud se vaše databáze pro neuronové sítě nejmenuje neural_network, je nutné ručně upravit SQL skript ukládaných procedur pro databázi jízdní řády! Toto se bohužel nedá v současné verzi MySQL nijak obejít.

Úpravu proveďte takto:

  1. Otevřete soubor JR - Procedury a funkce pro DP.sql v editoru, který zvládá kódování UTF-8 bez signatury (pro Windows např. Visual Studio nebo PSpad).
  2. Nahraďte veškeré výskyty řetězce neural_network. názvem vaší databáze a tečkou.
  3. Uložte soubor v kódování UTF-8 bez signatury (na obrázku je ukázka uložení ve Visual Studiu).

Poté upravenou verzi skriptu načtěte do MySQL místo původní verze.

Prohlížení dat

Výše jmenovaný balík GUI nástrojů zahrnuje také MySQL Query Browser, šikovný nástroj pro práci s databázovým systémem MySQL.

Výčet jeho vlastností a dovedností je dlouhý. My se pro účely demonstrace kódu této diplomové práce omezíme na podstatné.

Po spuštění stiskněte F11 – to zvětší konzoli pro SQL příkazy.

Nejprve předznamenejme, že MySQL používá koncept „aktuálně vybrané databáze“. Pokud voláte nějakou proceduru nebo pracujete s tabulkou, ujistěte se, že buď používáte plně kvalifikované jméno, nebo se daný objekt nachází ve vybrané databázi.

SQL příkazy vykonáváte tak, že na něj najedete kurzorem (nikoliv ukazatelem myši) a stisknete Ctrl + Enter. Výsledek (resultset) se zobrazí v dolní části

Můžete prozkoumat obsah tabulek jízdních řádů těmito SQL příkazy:

SELECT * FROM mhd_jizdy LIMIT 100;
SELECT * FROM mhd_jizdy_stani LIMIT 100;
SELECT * FROM mhd_linky;
SELECT * FROM mhd_kody;
SELECT * FROM mhd_trasy LIMIT 100;
SELECT * FROM mhd_trasy_uzly LIMIT 100;
SELECT * FROM mhd_zast LIMIT 100;

Zde je například výpis zastávek a jejich geografických po­zic:

Po importu dat z výše uvedených souborů obsahují tabulky všechna data jízdních řádů, na kterých jsme kód testovali.

Z tabulek je možné vhodnými SELECTy získat jakékoliv informace, které chceme znát – například:

  • trasy projíždějící danou zastávkou a počet zastávek do konce příslušné trasy
  • zastávky dané trasy
  • zastávky a časy stání dané jíždy
  • odjezdy spojů dané linky z dané zastávky
  • první následující jízda přijízdějící do dané zastávky od daného okamžiku

Zde je ukázka výpisu všech linek projíždějících zastávkou Žižkova:

Tabulky neuronových sítí prozkoumáte takto:

SELECT * FROM neural_network.nn_networks;
SELECT * FROM neural_network.nn_net_neurons;
SELECT * FROM neural_network.nn_net_synapses;

Po importu obsahují tabulky několik testovacích neuronových sítí.

Ladící zprávy pro algoritmy jízdních řádů, resp. neuronových sítí, najdete v tabulkách neural_network.lib_logg, resp. jizdnirady_cb.lib_logg:

SELECT * FROM neural_network.lib_logg;
SELECT * FROM jizdnirady_cb.lib_logg;

Volání API

Jak se konkrétní procedury používají je popsáno jednak v technické zprávě diplomové práce, jednak v komentářích v kódu jednotlivých procedur, a také na webu autora – jízdní řády, neuronové sítě.

Proto zde jen několik příkladů, jak SQL příkazy používat.

Standardně Query Browser po každém dotazu uzavře spojení s DB. Proto nejprve spusťte transakci – dočasné tabulky tak zůstanou k dispozici po volání procedury. Transakci spustíte buď příkazem START TRANSACTION; (a stisknutím Ctrl+Enter) nebo tlačítkem Transaction v horním pruhu programu. Vedle něj se po spustění transakce objeví tlačítka pro potvrzení nebo zrušení transakce. Stejného efektu lze docílit provedením příkazů COMMIT; nebo ROLLBACK;.

Kód pro vyhledávání v jízdních řádech

-- Vyhledání spoje ze zastávky 115 do zastávky 465, maximálně 2 přestupy.
CALL mhd_VyhledejSpoje(115, 465, NOW(), 3);
SELECT * FROM mhd_VyhledejSpoje ORDER BY pos;

Zde je ukázka vyhledání spojů mezi zastávkami Žižkova – Budvar – U pily – Nemocnice – U chromých:

Kód pro neuronové sítě

Se sítěmi lze provádět v podstatě tři operace: Vytvářet je, provést jejich výpočet, a učit je.

Na následujícím obrázku jsou zachycené první dva kroky.

Nejprve vytváříme neuronovou síť s architekturou 2,2,1 (vhodná pro řešení XOR):

-- Vytvoření neuronové sítě
CALL nn_CreatePerceptron('2,2,1','XOR', 0.10, 0.5, @out_NetID);

Pro vzniklou síť provádíme její výpočet a uchováváme hodnoty vnitřních neuronů:

-- Výpočet neuronové sítě
CALL nn_ComputeNet(1, '-1, 1', TRUE);

-- Zjistění výsledků výpočtu
SELECT * FROM nn_ComputeNet;

-- Výstupní hodnoty všech neuronů
SELECT * FROM nn_ComputeNet_InternalValues;

Výsledkem jsou tyto struktury:

id_neuron val
5 0.984122623404696
id_neuron val
1 –1
2 1
3 0.0166427942550775
4 0.972952595778587
5 0.984122623404696

Na základě vzniklých hodnot můžeme provést jeden krok učení:

-- Učení neuronové sítě
ALTER TABLE nn_ComputeNet RENAME TO nn_CorrectWeights;
ALTER TABLE nn_ComputeNet_InternalValues RENAME TO nn_CorrectWeights_InternalValues;
CALL nn_CorrectWeights(iNetID, '1', @dLearn, @out_dErrorSum);

Po provedení procedury (a případně potvrzení transakce) jsou váhy sítě upravené algoritmem backpropagation podle předchozího stavu sítě, dočasně uložených výstupních hodnot všech neuronů sítě a požadovaných hodnot výstupní vrstvy.

Pro pohodlné vyzkoušení učení neuronové sítě je k dispozici procedra nn_TeachXOR_Dynamic( //ID//, //cílová úroveň chyby//, //maximum kroků//). Kód v následující ukázce učí síť vytvořenou výše uvedeným postupem na cílovou úroveň chyby 0,0001 v maximálním počtu 10 000 kroků:

-- Učení neuronové sítě pro XOR
CALL nn_TeachXOR_Dynamic(3, 0.0001, 10000);

Kód učení neuronových sítí pro heuristiku vyhledávání spojů

V diplomové práci používáme neuronové sítě k určení vhodné trasy pro dosažení cílové zastávky v nejlepším čase.
Zde je kód pro vytvoření a učení neuronové sítě pro zastávku 5:

-- Vytvoření sítě pro zastávku 5 se třiceti neurony v jedné skryté vrstvě:
CALL mhd_nn_CreateNetForStation(5, '30');

-- Učení právě vzniklé sítě pro zastávku 5 do cílové
-- úrovně chyby 0.0001, maximálně po 40 000 kol učení:
CALL mhd_nn_TeachStationNet(5, LAST_INSERT_ID(), 0.0001, 40000);

Všechny procesy se v naší implementaci zaznamenávají do logu. To je užitečné zejména pokud něco nepracuje podle očekávání. Většinou je chyba na straně uživatele a v logu je zapsán její příčina (ve sloupci level je hodnota error nebo warning).

Zde je ukázka záznamů z učení neuronové sítě zastávky s ID 530:

Další vysvětlení najdete ve výše jmenovaných zdrojích – v diplomové prácí, ve zdrojových kódech jednotlivých procedur a na webu autora.

Případné dotazy směřujte na mail ondra@dynawest.cz nebo JabberID ondra.zizka@jabber.cz.

... read more →
2018-07-31

Nabídka: byt 3+1 v Českých Budějovicích

Nabídka: byt 3+1 v Českých Budějovicích

Nabízím byt 3+1 v panelovém domě v klidné části českých Budějovic – sídliště Vltava.

Základní informace

  • dům po celkové rekonstrukci – střecha, zateplení, výměna oken a stoupaček.
  • 7. patro
  • 3 pokoje orientované na sever, jeden na jih
  • balkon
  • družstevní forma vlastnictví

Poloha bytu

Byt se nachází na severním konci sídliště vltava. V okolí:

  • prodejna Globus
  • zastávka Sídliště Vltava – MHD č. 9, 14, 15, 19
  • chráněná přírodní rezervace Vrbenské Rybníky
  • v domě je přípojka kabelové televize a několik společností zde nabízí vysokorychlostní internet.

Družstevní vlastnictví

Družstevní vlastnictví někteří lidé iracionálně považují za cosi méněcenného a špatného. Oproti osobnímu vlastnictví má ale mnoho výhod:

  • Souhlas s nastěhováním musí udělit družstvo. S tím obvykle není problém, ale navíc to ochrání dům před nastěhováním problémových nájemníků.
  • Celkové lepší fungování domu – lidé se lépe domluví na nutných opravách, společných rekonstrukcích.
  • Chod domu si obvykle některý z obyvatel vezme „na starost“ – rychleji se tak vyřeší běžné provozní poruchy (poruchy výtahu, prasklá voda, atd.).
  • Menší anonymita – pravidelné schůze družstva (pochopitelně s dobrovolnou účastí) umožní nájemníkům se poznat lépe než přes zdi domu.
  • Pro sdružení vlastníků banky často neposkytují hypotéky – viz níže.

Jinak je družstevní vlastnicví stejně cenné jako osobní – byt není „někoho jiného“. Veškeré peníze, které platíte, jdou do oprav domu či investic do domu.

Někdo má dojem, že družstvo jej může „nutit“ platit na rekonstrukci, o kterou nemá zájem, kdežto s bytem v osobním vlastnictví si může dělat, co chce. To ale není pravda: V domech s více než 5 byty je ze zákona povinnost ustanovit sdružení vlastníků bytových jednotek, které bude spravovat dům podobně jako družstvo, a nájemníci jsou povinni se podřídit hlasování sdružení vlastníků.

Navíc pro společenství vlastníků banky obvykle neposkytují hypotéky:

Pro sdružení/spole­čenství vlastníků bytových jednotek hypoteční úvěr neposkytujeme. Je však možné na obchodním místě banky individuálně projednat tzv. investiční úvěr poskytovaný pro oblast SME (úvěry pro společnosti a osoby samostatně výdělečně činné). Tento typ úvěru je ale skutečně nutné individuálně projednat, a to včetně podmínek. Marek Richter, vedoucí týmu hypotečních úvěrů Raiffeisenbank

Při koupi bytu v osobním vlastnictví v polorozpadlém paneláku tedy kupujete časovanou bombu a je pravděpodobné, že rekonstrukce domu neproběhne v dohledné době.

Každopádně, tento byt je v rekonstruovaném domě, žádné další společné investice se nechystají, a výše příspěvků do fondu oprav jsou pevně nastavené. Spolupráce s družstvem je dlouhodobě dobrá a k plné spokojenosti obyvatel.

Ostatní

Prodej bytu nijak nespěchá, proto dokud vidíte tuto nabídku, je platná.

Využijte možnosti koupit byt bez zbytečných poplatků realitní kanceláři.

Pište na některý z kontaktů na stránce kontakty.

... read more →
2018-07-31

Výhody a nevýhody PHP

Výhody a nevýhody PHP

Update: V návaznosti na tento článek vznikl další – Je Java jako Linux nebo jako Windows?

Update: Abych nezůstal u teorie a subjektivních hodnocení PHP, přidám ukázku jednoho webu napsaného v PHP – a to hned web zabývající se programováním.

Update: V posledním (aspoň doufám) článku na toto téma vysvětluji jednotlivé body ze seznamu nevýhod.


Na webu je mnoho flejmů, zda je PHP lepší / horší než Java a .NET atd. Ostatně, nejjednodušší způsob, jak rozpoutat flejm, je zajít na hodně čtený blog nějakého PHPčkáře a zeptat se místních, že jste nováček a jestli je PHP lepší než Java. Mimojiné se na tom otestuje složení čtenářů – tj. nakolik jsou zastoupeni čistokrevní PHPčkáři s klapkami na očích, kteří nemají šajna o MVC, O/R a kolikrát ani pořádném OOP návrhu.

Nicméně nenašel jsem (pravda, zas tolik jsem nehledal) nějakou pořádnou moderovanou diskusi, případně článek, o výhodách a nevýhodách PHP.

//Update:// Našel jsem celkem dobrý článek na http://spyced.blogspot.com/…p-sucks.html. Sice je poněkud starší, ale jádro pudla zůstává. Je o dost ostřejší a než tento můj článek, takže PHPčkáři – bacha! :-) A všimněte si, že J2EE autor označuje za neelegantní stejně jako PHP.

Trochu se porozhlížím, kamže půjdu pracovat na fulltime. Do toho mě oslovil bývalý spolužák, že prý si mě všimnul na přednáškách Seznam.cz a že jejich firma naléhavě hledá programátory PHP a jestli bych k nim nešel. Já na to, jestli dělají v Javě, a že prý ano, ale hledají PHP programátory. Slíbil jsem, že se tedy ozvu jeho šéfovi a pokecáme. Pak jsem na to ale pozapomněl a šéf se ozval sám (asi hledají opravdu naléhavě :-)

Popravdě jsem mu vyložil, že PHP umím dobře, prakticky do detailů, no což to budu opisovat – zde je má odpověď:

Dobrý den,

Vaše nabídka mě zaujala. Shrnu svoji situaci:

V PHP vyvíjím (komerčně) už několik let. Možná právě proto mě to ale velice silně táhne k Javě a J2EE […]. Dále mám zkušenosti s [… … …] .

Kolega XY mi už také psal, zvažoval jsem, že se ozvu, ale říkal, že váš J2EE tým je asi spíše plný.

Mohl bych tedy pracovat jak jako vývojář PHP, tak J2EE, nicméne druhé o mnoho raději […]. Nabídku pracovního místa už mám, proto by mě zajímaly další podmínky – můžeme je případně probrat po telefonu.

V příloze posílám své CV, pokud by bylo třeba.

S pozdravem Ing. Ondřej Žižka

Asi půl hodinu na to se mi šéfík ozval po telefonu a domluvili jsme si schůzku. Na té jsem se dozvěděl, že získali kontrakt od firmy ABC, jíž dělají pokladní systém v J2EE a registrační web v PHP. A že na PHPkové weby mají svůj PHP framework (a v tu chvíli jsem si říkal – ajejej, další „svůj PHP framework…“) a že jej chtějí rozvinout. Ptal jsem se, co umí, jak funguje a oč jej chtějí rozvinout. A dozvěděl jsem se, že:

  • začali jej vyvíjet jako redakční systém
  • přesto to ale nyní není něco jako Joomla, naopak, něco diametrálně odlišného (jestli jo, tak jedině dobře)
  • umí trochu MVC ve stylu Struts
  • zkoušeli dělat O/R mapování, ale je to moc složité
  • chtějí framework refaktorovat (oddělit moduly, zmenšit velikost a snížit počet styčných ploch, redesign)
  • chtějí zapracovat na Ajaxové části
  • chtějí zabudovat podporu webových služeb
  • chtějí zabudovat mechanismus šablon
  • atd atd.

Potom se stočila řeč na to, jestli bych mohl dělat Java juniora, a později, proč bych nemohl, respektive proč chtějí vyvíjet v PHP a poč vyvíjet framework pro PHP, který:

  • který bude pokrývat 2% funkčnosti existujících (Java a J2EE) frameworků
  • který budou vyvíjet jejich vlastní programátoři za v součtu slušnou částku
  • který nehodlají uvolnit jako opensource ani prodávat (vyplynulo)
  • který bude po dlouhou dobu neodladěný a bude mít „dětské nemoci“

a nakonec – a to především –

  • proč vůbec vyvíjet v PHP.

No diskuse to byla těžká, protože šéfík (nic proti němu, zdál se jako moc fajn chlap) je programátor – teoretik z Masarykovy univerzity, který zná PHP i J2EE „z manažerského pohledu“, a třetí účastník – jejich PHP senior – neví o Javě a J2EE nic (také nic proti němu, fajn kluk :-)

Zkrátka jejich postoj je takový, že PHP je skvělá technologie na jednodušší věci, jako je frontend pro Javovský backend, resp. nad databází. Inu dobrá, já jim to neberu, ale během celého rozhovoru mi hlavou běhaly vzpomínky na nejrůznější veselé příhody (dalo by se přeložit jako „gay incidents“ :) s PHP:

Proč neprogramovat v PHP

  • Záhadné chyby mezi minor verzemi
  • Nutnost překopat celý systém při přechodu na novou major verzi
  • „Krása“ procesu deployování uploadem na FTP či obdobným
  • Dlouhé hodiny hledání obezliček a work-aroundů, jak obejít tu kterou vlastnost PHP
  • Vytváření OOP wrapperů pro procedurální PHP funkce typu mysql_*
  • Přepisování stohů zdrojáků při refaktoringu, protože PHP je bordelářský jazyk a programátora vyloženě svádí programovat jak prase
  • Stovky případů hledání chyby, kdy se ukázalo, že za vším stojí přepis v názvu proměnné
  • Ošetřování rozdílnosti implementace ve Windows a na Linuxu
  • Desítky zbytečných řádek kódu pro převod z/do UNICODE při práci s UNICODE stringy
  • AAAAAAAAAAAAA­AAAAAAAAA!!!!!!! Už nééééééé!

Prostě při pomyšlení, že bych měl jít vyvíjet framework v PHP, se mě jímaly úzkostné pocity. Jasně, potenciální PHP-fanatik mi bude oponovat, že kdybych psal rovnou dobrý kód, tak jsem v pohodě. Ale není to pravda, a to hned několikrát:

  • PHP dobrý OOP kód nedovoluje, protože všechny core funkce jsou procedurální a mixovat je s OOP je hnus.
  • PHP hezký kód nedovoluje, protože core funkce nevyhazují výjimky, a ify jen kvůli ošetření chyby je pravěká metoda táhnoucí se snad ještě z dob Alana Turinga.
  • Nekvalitní zpracování OOP v PHP zásadně podkopává možnost používat zcela základní OOP principy.
  • PHP vás přímo tlačí do kouta s imperativem „Delej hnusný kód!“, když zcela ignoruje možnost naprogramovat kolekce objektově a v návaznosti na teoretický rozbor věci, a místo toho naprosto vše cpe do Array: pole, hash, frontu, zásobník, množinu… což ještě někteří vydávají za výhodu.
  • I kdybych psal krásný kód, nikde není žádná záruka, že v příští verzi budu muset vše opět přepisovat – neexistuje norma PHP ani oficiální plán vývoje! PHP prostě jen bude vykrádat Javu, takže v PHP 7 nabeton budou anotace.

Srovnání s Javou

Naproti tomu, když programuji v Javě, dobrý kód vzniká skoro sám (už se neubráním srovnání):

  • Vyplatí se pro sebemenší blbinu vytvořit třídu.
  • Pokud dělám třídu pro potřebu jiné, dám ji do souboru k ní a zůstane tedy skrytá a nezabordelim si adresář (balíček).
  • Pokud ji ale potřebuju jinde, přesunu ji do zvláštního souboru a už je k dispozici.
  • Samotné JRE je vzorem dobrého návrhu, a čistě jeho používáním se podvědomě naučíte návrhu:
    • Abstrahovat problémy (úlohy) a tvořit jim rozhraní – viz interface List a implementaci ArrayList
    • Rozdělovat svoji aplikaci do namespace (balíčků) – viz např. java.utiljava.lang
    • Využívat výjimky tam, kde je to vhodné, a zjednodušovat jimi API jednotlivých modulů
  • Co naprogramujete s jedním JDK, je skoro na 100% jisté, že přeložíte i v další verzi
    • JRE má totiž narozdíl od PHP promyšlený návrh a nemusí se zásadní věci měnit každou major verzi
    • Pokud už se stane, že cosi nevyhovuje, je to označeno za „deprecated“, ale ponecháno a nová verze je v jiném namespace;
    • Přesto však nová verze využívá maximum ze staré verze, a vy tak při dalším vývoji můžete snáze navázat a začít používat nové možnosti (viz AWT a Swing) místo totálního přepsání (viz mysql_* a PDO)
    • Když už by se náhodou stalo, že byste něco nepřeložili (jako se mi stalo v případě MySQL Connector/J), můžete aspoň používat binárky a vesele psát pro novou verzi.
  • Nové verze různých projektů (knihoven a frameworků) využívají anotace, takže kód je ještě čistší a zářivější
  • S využitím „injection“ (např. ze Springu) vám navíc ještě odpadají desítky jednotlivých řádků kódu, které jsou jaksi samozřejmé, ale přesto musí být (získání spojení, otevření transakce, ověření přístupových práv…)

Prostě při prvním komerčním projektu v Javě moje srdénko jen zaplesalo nad tím, jak neuvěřitelně hladce to jde od ruky.

Složitost programování v J2EE

A ještě ke složitosti J2EE.
Když srovnám PHP a JSP, tak to jsou zhruba srovnatelné technologie:

  • nějaká core knihovna funkcí,
  • a nějaký jazyk vkládaný do HTML.

Jenže tam, kde PHP končí, tam J2EE teprve začíná. Pokud skutečně rezignujete na leta vývoje a nechcete se učit tagy ze Struts nebo anotace z JPA / Hibernate, prosím – můžete vše poctivě datlovat jako v PHP, psát si SQL dotazy (jednoduchost přístupu k výsledkům dotazu v PHP přes pole zajistí iBatis) a třeba si i prasit kód rovnou do HTML souborů.

Jenže v J2EE máte možnost jít dál. Co máte v PHP? Ano, je zde pár povedených věcí… Smarty, Zend Framework, CakePHP. Ale ty stejně jedou nad shnilým jádrem.

Pokud někdo říká, že PHP se naučíte rychleji než J2EE, tak já říkám ano, protože v PHP skoro není co se učit.

Když jsem s J2EE začínal, také jsem se zalekl té neuvěřitelné haldy nových pojmů, specifikací, zkratek, XML konfiguračních souborů a postupů; dále nutnosti použít IDE nebo aspoň buildovací nástroj (Ant), naučit se spravovat něco jiného než Apache HTTPD…

Ono totiž PHP je jen taková lehká nadstavba nad CGI – nad něj dává jen relativně jednoduchou syntaxi a spoustu knihoven použitelných z této syntaxe. Jenže když jde do tuhého a úroveň vašich projektů se vznese nad příklady z manuálu PHP, stejně musite začít řešit (hodně na přeskáčku):

  • Fyzickou strukturu webové aplikace – aneb adresáře, kam co dát
  • Zjednodušení správy obsahu v databázi
  • Verzování záznamů v databázi
  • Konfiguraci chování a struktury webu nad úrovní kódu
  • Abstrakci nad různými databázemi
  • Interakci s backendem, případně sjednocení API s GUI částí enterprise aplikace
  • Možnosti pokročilé konfigurace aplikace
  • Centrální repozitář objektů poskytujících nějaké služby
  • Clusterování

atd.

A zatímco J2EE vás těmito „nesmysly“ zavalí hned zpočátku, protože postupy jsou standardizované a často se věci rovnou řeší „složitě“ s výhledem na budoucí rozvoj, PHP vás nechá, ať si děláte co chcete – zlepšující se programátoři časem začnou vytvářet „vlastní framework“, vlastní normu pro strukturu aplikace, vlastní knihovnu pro automatické ukládání objektů do DB, a tak dále, zatímco naprostí začátečníci – neprogramátoři mohou třeba takto (viz část „Přiřazení prvků v šabloně“):

Často potřebujeme vybrat data z databáze a následně je předat šabloně. Na začátku je tedy SQL dotaz:

$result = mysql_query("SELECT nazev, titulek, text, cena FROM tabulka WHERE id='$id'");

Jak nyní předat data šabloně?

Nejjednodušší řešení je předat rovnou pole:

$smarty->assign('data',mysql_fetch_assoc($result));

Nyní se pokusím oprostit od Javy a zaměřit se čistě na PHP. Kdyby se někde v dalším textu vyskytlo slovo „Java“, klidně mi dejte virtuální facku :)

Zkusím tedy shrnout, jaké má PHP výhody a jaké nevýhody. Zkusím při tom zaujmout pokud možno nezaujatý postoj, i když případného čtenáře o tom po přečtení předchozí kritiky asi nepřesvědčím.

Komentáře nevedu, ale jestli se vám něco v následujícím výčtu nezdá, napište mi mail a já zde provedu veřejné pokání a omluvu sloníkovi elePHPantovi :)

Výhoda a nevýhoda jsou relativní pojmy. Proto navrhuji jako „baseline“ pro srovnání použít ostatní technologie použitelné na podobné účely jako PHP, tedy: ASP.NET, ColdFusion, Java EE, Perl, Python, Ruby (on Rails). Naopak neuvažoval bych kombinace typu C + CGI (příliš složité programování), Apache SSI (příliš omezená funkčnost), Caché Server Pages (příliš nesmyslná technologie), XML + XSLT + JavaScript (principiálně příliš jinde), ASP (zastaralé) a podobně.

Takže – posuďte sami:

Výhody PHP

Technologie PHP má spoustu výhod, díky které se rychle stalo populárním. Mezi ně patří např.:

  • Velká rozsáhlost funkcí k dispozici přímo v základní instalaci
  • Další nativně implementované funkční celky snadno instalovatelné z repozitáře PEAR
  • Další knihovny instalovatelné z repozitáře PECL
  • Nativní podpora mnoha databázových systémů
  • Zpočátku strmá křivka učení
  • --Je multiplaforní– S tou multiplatformností to není tak žhavé. Zkuste si třeba PHP na Novellu. Spíše bych řekl: Jede víceméně stejně na Linuxu a na Windows.
  • Časem vznikla velká celosvětová komunita vývojářů a mnoho dobrých svobodných projektů, zejména publikační systémy a Texy! :-)
  • Velmi široká nabídka hostingu, levné ceny díky konkurenci
  • Dobrý, aktuální a úplný manuál s příklady
  • Někdy se hodí stručný model zpracování nedefinovaných hodnot a null
  • Stručný přístup k prvkům hash-mapy přes operátor []

Nevýhody PHP

Na druhou stranu, PHP má také značné nevýhody, pro které jej mnozí kritizují a někdy i opouštějí; mimo jiné tyto:

  • Až do verze PHP 4 nepříliš povedená podpora objektově orientovaného programování s mnoha záludnostmi
  • Verze 5 již podporuje OOP lépe (i když stále velmi mizerně), ale nativní knihovna funkcí nadále používá procedurální paradigma
  • Nativní funkce nejen nepoužívají objektový přístup, ale ani nepodporují výjimky (set_error_handler() je pouze slabá náplast)
  • Některé rysy jazyka svádějí ke špatným stylům programování (např. přílišné užívání polí a hash-map)
  • Nekonzistentní pojmenování nativních funkcí a nejednotnost v logice pořadí parametrů
  • Nativně nepodporuje UNICODE (připravuje se pro verzi 6 – už skoro tři roky)
  • Dosud neexistuje formální specifikace syntaxe jazyka a jeho chování (jedinou úplnou definicí je interpreter)
  • Tím pádem existuje jediný interpreter
  • Způsob, jakým PHP funguje, principiálně brání efektivnímu řešení mnoha úloh (např. objektově-relační mapování)
  • PHP nemá danou politiku vývoje, místo toho nadále jen kopíruje prvky jiných jazyků
  • Je značně zatížené svým vlastním historickým vývojem
  • Oficiálně není zaručena zpětná kompatibilita
  • Programátor nemá zaručené cílové prostředí, mnoho věcí přímo ovlivňujících chování PHP lze změnit pouze mimo soubory projektu (v konfiguračním souboru php.ini)
  • Nepodporuje paralelní výpočet a synchronizaci (vlákna)
  • Nepodporuje škálování pomocí prostředí sdíleného na více serverech
  • Ve standardní sadě nástrojů není nástroj pro tvorbu dokumentace
  • --Nedostatek– Nemnoho kvalitních frameworků (Pozor! Drupal, Joomla, WordPress a spol. nejsou frameworky, ale publikační systémy / CMS).
  • Nelze snadno integrovat s jinými technologiemi (znovupoužití knihoven napsaných v PHP v jiném jazyce)
  • Ve standardní distribuci chybí ladící (debugovací) nástroj
  • Relativně složitá syntaxe oproti jiným technologiím použitelným na stejný účel
  • Po zpracování požadavku se „ztrácí“ kontext aplikace a při příštím je vytvářen jiný
  • Mimo jiné z toho plyne relativně slabý výkon
  • Velký počet zásadních chyb v počátcích nových verzí
  • Nepodporuje jmenné prostory (Skutečně, stále ještě mohou existovat obrovské projekty, kde se knihovny rozlišují prefixem.)
  • Podivné fungování referencí – asi nejzrádnější askept PHP
  • Donedávna chybělo rozumné jednotné rozhraní pro práci s databázemi, nyní PDO
  • Chybí anotace a aspektově orientované programování
  • Chybí možnost vynutit deklaraci proměnných, takže se dá omylem zapsat něco do jiné (nové) proměnné. Taková chyba se hledá VELMI těžko.
  • Nedostatečná sebereflexe – datové typy „Třída“/„Funce“, místo toho se na ně odkazujete přes stringy
  • Nemožnost odkazovat se na metody objektů jinak než neohrabanou konstrukcí s Array()
  • Kvůli slabé typovosti neobratné přetěžování funkcí a metod a jejich překrytí při dědění
  • Projekty se musí šířit výhradně formou zdrojových kódů
  • Neexistuje přímá podpora pro webové služby a pro vzdálené volání procedur obecně
  • Chybí solidní knihovna / nástroj pro logování

Jak je vidět, seznam výhod a nevýhod je trochu nevyvážený. Nyní čekám polemiku :-) ondra@dynawest.cz

//PS:// Ale pořád ještě to není tak strašné, jako s Caché – kdo zkoušel, ví :-)

Další články s podobnou tématikou:

  • Kam kráčíš, PHP? (2006, doporučuji přečíst i komentáře)
  • David Grudl o PHP

    4. Jaká je perspektiva PHP z Vašeho pohledu?
    Jsem PHP skeptik. PHP jakožto jazyk ztratil koncepci, rozšiřování se děje chaoticky. PHP jakožto knihovna se nehodí na tvorbu webových aplikací. Frameworky se to snaží suplovat.

Obrázky přejaty z http://www.nexen.net/…nt/index.php a http://shop.yourphppro.com/elePHPant.html.

(PS: Kdyby někoho zajímalo, proč je tento web v PHP, tak je to kvůli Texy! ;-)
PS pro Jana Škráška: Porty Texy? Ruby nemám rád, python neumím, .NET nechci a pro Javu ještě port není.

... read more →
2018-07-31

Ondra Žižka – personal website

Ondra Žižka – personal website

Welcome to my web page.

This is not a blog – rather a „private publication“ place.

No comments here – I don't want to spend my time deleting dumb post and spam. If you have anything to say or ask, just send me an email.

Ondra Žižka – osobní web

Vítám vás na své webové nástěnce.

Zas jednou jsem už nevydržel dávat věci dokola někam na FTP a rozhodl se pro potřeby zveřejňování lecčehos zřídit web.

Nečekejte blog. Berte to jako moje soukromé „zveřejniště“.

Proč tu nejsou komentáře?

Za krátkou dobu obnovené existence webu už mi přišel pár mailů, kde se autor ptal, proč nemám u článků komentáře. Důvod je jednoduchý:

  1. Komentáře bych nečetl.
  2. Spam.
  3. Kvůli časové souslednosti.
  4. Buď na web nikdo chodit nebude, a pak budou komentáře zet prázdnotou, a to je trapné :-)
  5. nebo na něj lidé chodit budou, a pak se tu časem nutně objeví zástupy truhlíků s opravdu dementními komentáři.

ad a)

Nemám ještě pořádný redakční systém, který by mi je někde pohodlně seštosoval, a možná ani mít nebudu, protože se pravděpodobně od webařiny přesunu k programování.

ad c)

Jelikož toto není blog, ale prostor pro publikování, literární útvary se zde čas od času mění. Zakládat nový článek místo úpravy dokumentu podle mě není vhodné. Případné komentáře by tedy komentovaly staré verze, a zatímco dokument by se v čase vyvíjel a odrážel aktuální stav věcí, komentáře by se s ním táhly jako Gott a Vondráčková s hudebním průmyslem (fuj, to bylo ale politicky nekorektní).

ad d), e)

Zatímco na „blozích“ se to řeší karmami, přihlašováním, hodnocením kvality, banováním a dalšími marnými technikami, já jednoduše komentáře nevedu.

Pokud někdo chcete komentovat, napište mi mail na ondra@dynawest.cz. Efekt to bude mít stejný – nadávky mě hluboce urazí a půjdu trucovat do kouta, zajímavé a relevantní tipy do článků přidám. Akorát spam takto vyfiltruju lépe :-)

Co zrovna dělám

Pokud zrovna nepracuji pro JBoss, zkoumám různé technologie:

V mezičase se prokousávám webovými Java technologiemi (J2EE).

Na co se chystám

  • Texy Java implementation
  • Gravity Road – tajný projekt ;-)
... read more →
2018-07-31

Quick and dirty mavenization of an existing project

Quick and dirty mavenization of an existing project

This is my lazy way to get anything to a Maven repo. Shown on my mavenization of the Sardine library.

See also: How to add existing project's jar to SVN-based Maven repository


  1. Download the binaries of the lib you want to mavenize.
  2. Create a script to put everything to the maven repo.

    Choose a group name for the library and it's deps.

    You should not use the lib's package names, because it could interfere later

    with the official artifacts, should it ever be mavenized.

    I usually use my project's name with the lib's name appended – org.jboss.qa.ews.sardine in this case.

    @ECHO off
    ECHO echo Edit this file before use. Check the -DartifactId and -Dversion params.
    ECHO return
    
    ECHO cmd /C mvn install:install-file -DpomFile=sardine-pom.xml -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\sardine.jar -DartifactId=sardine -Dversion=80
    
    FOR %%f IN ( sardine-80\lib\*.jar) DO ECHO cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=%%f -DartifactId=%%~nf -Dversion=%%~nf

    This will create something like this:

    echo Edit this file before use. Check the -DartifactId and -Dversion params.
    return
    
    cmd /C mvn install:install-file -DpomFile=sardine-pom.xml -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\sardine.jar -DartifactId=sardine -Dversion=80
    
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\ant-googlecode-0.0.2.jar -DartifactId=ant-googlecode -Dversion=0.0.2
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\commons-logging-1.1.1.jar -DartifactId=commons-logging -Dversion=1.1.1
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\httpclient-4.0.1.jar -DartifactId=httpclient -Dversion=4.0.1
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\httpcore-4.0.1.jar -DartifactId=httpcore -Dversion=4.0.1
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\junit-4.8.1.jar -DartifactId=junit -Dversion=4.8.1
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\svnkit.jar -DartifactId=svnkit -Dversion=0.0
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\svntask.jar -DartifactId=svntask -Dversion=0.0
  3. Create a pom.xml file, which will describe the mavenized library's depen­dencies.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.jboss.qa.ews.sardine</groupId>
  <artifactId>sardine</artifactId>
  <packaging>jar</packaging>
  <version>80</version>

  <name>Sardine mavenized</name>
  <url>http://www.jboss.org/</url>

  <dependencies>
  </dependencies>

</project>
  1. Most of the deps should be found in some existing Maven repository.

    Try to find as much as you can (the exact versions!), add them as a dependency to the pom.xml, and comment them out from the script.

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.0.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpcore</artifactId>
      <version>4.0.1</version>
    </dependency>
    
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
    </dependency>
    
    <dependency>
      <groupId>org.tmatesoft.svnkit</groupId>
      <artifactId>svnkit</artifactId>
      <version>1.3.2-1</version>
    </dependency>
    
    <dependency>
      <groupId>org.jboss.qa.ews.sardine</groupId>
      <artifactId>ant-googlecode</artifactId>
      <version>0.0.2</version>
    </dependency>
    
    
    <dependency>
      <groupId>org.jboss.qa.ews.sardine</groupId>
      <artifactId>svntask</artifactId>
      <version>0.0</version>
    </dependency>
    cmd /C mvn install:install-file -DpomFile=sardine-pom.xml -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\sardine.jar -DartifactId=sardine -Dversion=80
    
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\ant-googlecode-0.0.2.jar -DartifactId=ant-googlecode -Dversion=0.0.2
    @rem cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\commons-logging-1.1.1.jar -DartifactId=commons-logging -Dversion=1.1.1
    @rem cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\httpclient-4.0.1.jar -DartifactId=httpclient -Dversion=4.0.1
    @rem cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\httpcore-4.0.1.jar -DartifactId=httpcore -Dversion=4.0.1
    @rem cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\junit-4.8.1.jar -DartifactId=junit -Dversion=4.8.1
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\svnkit.jar -DartifactId=svnkit -Dversion=0.0
    cmd /C mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\lib\svntask.jar -DartifactId=svntask -Dversion=0.0
  1. Some of the libs probably only serve the build process, in this case, svnkit, svntask and ant-googlecode (I just guessed from the names).

    These are going to be removed too.

  2. As you see, only the library itself left for addition to a maven repo.

    So, perform this:

    mvn install:install-file -DpomFile=sardine-pom.xml -Dpackaging=jar -DgeneratePom=true -DgroupId=org.jboss.qa.ews.sardine -Dfile=sardine-80\sardine.jar -DartifactId=sardine -Dversion=80
  1. Go to your local maven repo and find the installed library there (t:\data\.m2\repository\org\jboss\qa\ews\sardine\sardine in my case).

    Copy it to some publicly accessible site, where it can be downloaded from using plain HTTP.

    I used Google Code SVN. svn --non-recursive might help you with this task.

Done.

... read more →
2018-07-31

Vybírám skriptovací jazyk pro systémové skripty

Vybírám skriptovací jazyk pro systémové skripty

Postupem času jsem přešel na Linux. Co mě zde ale nepřestává štvát, je Bash.

Bash je jazyk hrůzy. Ne tak hrozný, jako Caché ObjectScript, ale pořád dost hrozný:

# Bohužel jsem momentálně nenašel dostatečně odstrašující příklad :)
# V praxi ale narážím na naprosto nečitelný kód,
# Využívající těch nejškaredějších syntaktických konstrukcí,
# kde už člověk ztrácí přehled o tom, co je syntaxe find-u a kde je do ní vložen bash.

Jasně, chápu… je to jazyk určený hlavně pro práci v prostředí linuxu, a tedy pro práci převážně s GNU programy, které se vyvíjely v symbióze s Bashem. V interaktivním režimu je stále dobře použitelný pro jednořádkové příkazy. Pokud ale mám louskat několikastránkový skript, kde jsou takových jednořádkových příkazů desítky a každý je taková malá hra „hádej kolik syntaxí je zde použito“, házím flintu do žita.

Doba pokročila, a skoro začíná být důležitější podpora novodobých technologií, jako je Java, XML, webové služby, a v neposlední řadě je velmi příjemné, když lze využít výhod IDE – doplňování, refactoring atd.

Jak je patrné z těchto stránek, jsem momentálně fanda Javy – a to ačkoliv jsem si vědom (někdy až bolestně) všech jejích nevýhod. A jako každý (programátor), občas chci napsat stručný skript, který provede pár operací podle několika zadaných parametrů. Jít na takovou záležitost s Javou je přeci jen poněkud nevhodné – napsat všechnu omáčku, zkompilovat, evt. zabalit do jarka a spouštět stylem java -jar Skript.jar, a to ještě dělat při ladění, to přeci jen není ono.

Takže jsem začal hledat jazyk, který byl vhodný právě pro takové skripty, případně snad i na konzoli. Měl by tedy splňovat tato kritéria:

* Stručný – jít bez okolků na jádro řešení úlohy (jako bash).
* Jednoduchá syntaxe bez desítek výjimek, různých módů nahrazování, a speciálních významů kombinací hieroglyfů typu $? atd.
* Přes jednoduchou syntaxi by měl mít dostatek prostředků pro stručný zápis nejběžnějších operací, např. práce se seznamy.
* Podpora Javy – ideálně by měl umět pracovat s jakoukoliv třídou Javy, včetně takových jako Thread, Throwable atd.
* Pochopitelně by měl umět OOP, výjimky, kontrolu typů.
* Měl by být konzistentní v konceptech.

Jako bonus potom započítávám tyto vlastnosti:

* Nativní podpora XML – nejlépe jako součást nativní podpory práce se stromovými strukturami.
* Bez nutnosti kompilace.
* Různé vychytávky typu „vše je objekt“, uzávěry (closures), yield.
* Možnost uplatnit změny v kódu za běhu programu.

Kandidáti

Nyní proberme jazyky a technologie, které připadají v úvahu:

* PHP rovnou diskvalifikuji z Těchto důvodů
* Python, resp. Jython
* Groovy
* Scala
* JavaScript
* JavaFX
* …navrhněte: ondra@dynawest.cz

Konkurz

Tímto zahajuji výběrové řízení a začínám se poohlížet po vlastnostech jednotlivých jazyků. Pokud bude čas, rozepíšu se o tom, proč který jazyk ano či ne.

... read more →
2018-07-31

JBoss Microcontainer with JBoss AOP – Howto with sample application

JBoss Microcontainer with JBoss AOP – Howto with sample application

A very brief intro to JBoss AOP.

Prerequisites

This tutorial is a follow-up to the JBoss Microcontainer intro – read that first if you haven't yet.

What is AOP good for?

AOP (Aspect Oriented Programming) is a concept of moving a „programatic envelopes“ away from the methods. What I call a programatic envelope is that kind of annoying code you have to repeat at the end or/and the beginning of many methods.

Usual textbook examples of AOP usage are:

  • Opening and closing of a transaction
  • Locking and unlocking of synchronization locks
  • Logging of debug messages
  • Measuring the time of method execution

However, AOP is particulary useful for frameworks for their need of generalization. It can help it to put the envelope code around method which it still does not know.

How does AOP work?

First, you mark some Java constructs (methods, fields, constructors, …) to be AOP'ed (encapsulated with your envelope code).
Then you need so-called „aspect“ – that is the official name for envelope code.
Then you need some tool which will bind the aspect to those methods. This is done by advanced techniques like byte-code instrumentation and class reflection.

Why JBoss AOP (and not the others)?

JBoss AOP offers much more then the other AOP frameworks (like Spring AOP).

  • It can bind not only to methods, but also to constructors and fields.
  • As it's not proxy based, you don't need to treat objects only through interfaces.
  • You can weave any existing class without any code changes.
  • Annotation-based weaving – intercept Java constructs which are annotated by some anotation.
  • Weaving at compile time gives much better performance.
  • Configuration by annotations – if you don't like XML, you can set the aspects and bindings using annotations like @Aspect, @Interceptor, @Bind etc. See Chapter 6. Annotation Bindings.
  • Runtime weaving, called „HotSwap“ – allows bytecode of your classes to be weaved in runtime.

Terms

Copied from JBoss AOP reference docs.

Joinpoint
A joinpoint is any point in your java program. The call of a method. The execution of a constructor the access of a field. All these are joinpoints. You could also think of a joinpoint as a particular Java event. Where an event is a method call, constructor call, field access etc…
Invocation
An Invocation is a JBoss AOP class that encapsulates what a joinpiont is at runtime. It could contain information like which method is being called, the arguments of the method, etc…
Advice
An advice is a method that is called when a particular joinpoint is executed, i.e., the behavior that is triggered when a method is called. It could also be thought of as the code that does the interception. Another analogy is that an advice is an „event handler“.
Pointcut
Pointcuts are AOP's expression language. Just as a regular expression matches strings, a pointcut expression matches a particular joinpoint.
Introductions
An introduction modifies the type and structure of a Java class. It can be used to force an existing class to implement an interface or to add an annotation to anything.
Aspect
An Aspect is a plain Java class that encapsulates any number of advices, pointcut definitions, mixins, or any other JBoss AOP construct.
Interceptor
An interceptor is an Aspect with only one advice named „invoke“. It is a specific interface that you can implement if you want your code to be checked by forcing your class to implement an interface. It also will be portable and can be reused in other JBoss environments like EJBs and JMX MBeans.

What we're willing to achieve?

We want to catch all calls to methods that affect the fuel in the Car. To make this easily achievable with AOP, let's follow a convention that all changing methods are setters and all fuel-related properties names end with „Fuel“.

For the purposes of this example, we've changed the Car class to have two fuel-related properties:

public class Car {
  public int litresOfFuel;
  public int getLitresOfFuel() {    return litresOfFuel;  }
  public void setLitresOfFuel( int litresOfFuel ) {    this.litresOfFuel = litresOfFuel;  }

  public int reserveFuel;
  public int getReserveFuel() {    return reserveFuel;  }
  public void setReserveFuel( int reserveFuel ) {    this.reserveFuel = reserveFuel;  }

  public String toString(){
    return "Car \""+this.name+"\" with "+(this.litresOfFuel + this.reserveFuel)+" litres of fuel.";
  }
  ...
}

Creating an Interceptor („envelope“)

This is a simple interceptor that will just notify us when triggered.

package cz.zizka.ondra.jbmctest;

import java.util.logging.Logger;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.instrument.Untransformable;
import org.jboss.aop.joinpoint.Invocation;

public class FuelInterceptor implements Interceptor, Untransformable {

  private static final Logger log = Logger.getLogger( FuelInterceptor.class.getName() );

  public Object invoke(Invocation invocation) throws Throwable
  {
    Object target = invocation.getTargetObject();
    if( target instanceof Car ){
      log.info("The fuel is being changed for the car '"+((Car)target).getName()+"'.");
    }
    return invocation.invokeNext();
  }

  public String getName() {
    return FuelInterceptor.class.getName();
  }
}// class FuelInterceptor

Binding the interceptor to the method calls

For the syntax of AOP pointcuts, see JBoss AOP documentation.

The syntax for our purpose stated above would be:

execution(* cz.zizka.ondra.jbmctest.Car->set*Fuel(..)

The AOP settings go to a special XML file having <aop> as it's root element, and conforming to the JBoss AOP XSD.
From what I've found, this file must be either in META-INF/jboss-aop.xml of your .jar, or anywhere on the filesystem, but you'll have to point to it by the -Djboss.aop.path JVM argument – see 10.2.1. Precom­piled instrumentation and 5.2. Resolving XML.

To let maven put this file to your .jar, store it in src/main/resources (the default path for resources), giving the resulting path src/main/resources/META-INF/jboss-aop.xml.

So let's bind this interceptor to some method calls. In this case, we're binding it to all methods of the Car class whose name has the pattern set*Fuel.

<?xml version="1.0" encoding="UTF-8"?>
<aop>
   <bind pointcut="execution(* cz.zizka.ondra.*->set*Fuel(..))">
       <interceptor class="cz.zizka.ondra.jbmctest.FuelInterceptor"/>
   </bind>
</aop>

Alternatively, it should be possible to put the AOP settings to the JBoss Microcontainer XML (but I wasn't able to get it working):

<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd"
            xmlns="urn:jboss:bean-deployer:2.0"
            xmlns:aop="urn:jboss:aop-beans:1.0">

  <bean ... /> <!-- Car and garage beans -->

  <aop:interceptor name="FuelInterceptor" class="cz.zizka.ondra.jbmctest.FuelInterceptor"/>

  <aop:bind pointcut="execution(* cz.zizka.ondra.jbmctest.Car->set*Fuel(..)">
    <aop:interceptor-ref name="FuelInterceptor"/>
  </aop:bind>

</deployment>

Maven configuration

After setting Maven to use JBoss repositories (see the JBoss Microcontainer how-to), add these dependencies to your project:

<dependencies>
  <dependency>
    <groupId>org.jboss.microcontainer</groupId>
    <artifactId>jboss-kernel</artifactId>
    <version>2.0.9.GA</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.aop</groupId>
    <artifactId>jboss-aop</artifactId>
    <version>2.1.6.GA</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.microcontainer</groupId>
    <artifactId>jboss-aop-mc-int</artifactId>
    <version>2.0.9.GA</version>
    <scope>runtime</scope>
  </dependency>
</dependencies>

Also, add the JBoss AOP Maven plugin. It binds automatically to the compile phase. This will change the classes code to call your interceptors when a method is being called.

<plugins>
  <plugin>
    <groupId>org.jboss.maven.plugins</groupId>
    <artifactId>maven-jbossaop-plugin</artifactId>
    <version>2.1.3.GA</version>
    <executions>
      <execution>
        <id>compile</id>  <goals> <goal>compile</goal> </goals>
        <configuration>
          <includeProjectDependency>true</includeProjectDependency>
          <aoppaths>
            <aoppath>src/main/resources/META-INF/jboss-aop.xml</aoppath>
          </aoppaths>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Test code

public class JBossAopSampleApp {

  public static void main( String[] args ) throws Throwable
  {
    Car myCar = new Car("Red Devil");
    System.out.println( "I have a garage: "+car);

    // Put some fuel in.
    myCar.setLitresOfFuel( myCar.getLitresOfFuel() + 1 );
    myCar.setReserveFuel( myCar.getReserveFuel() + 1 );

    System.out.println( "I have a garage: "+car);
  }

}

The result

Now run the application, and you'll see that the interceptor is really being invoked.

I have a garage: Garage with a car: Car "Red Devil" with 0 litres of fuel.
16.11.2009 11:42:47 FuelInterceptor invoke INFO: The fuel is being changed for the car 'Red Devil'.
16.11.2009 11:42:47 FuelInterceptor invoke INFO: The fuel is being changed for the car 'Red Devil'.
I have a garage: Garage with a car: Car "Red Devil" with 2 litres of fuel.

Sample application

The application created in the examples above can be downloaded here: JBossAOPsample­.zip

... read more →
2018-07-31

WinLyrics – WinAmp lyrics plugin

WinLyrics – WinAmp lyrics plugin

Nový hosting?

Máme nabídku nového hostingu… na Gigawebu to občas vypadne (mysql i web), a už není nijak moc pružný…

přístup zde.

TODO list

Hodnocení lyrics

Dokumentace zde.

  • Do interface přidat možnost ohodnotit lyrics.
  • Stupnice:
    • Bez chyby, perfektní
    • Dobré
    • Použitelné
    • Nesmysly, hodně chyb
    • Totální odpad
  • Vliv na funkci:
    • Vyhledané lyrics se budou řadit také podle hodnocení daných lyrics. Jinak žádný.
  • Na server se pošle: ID lyrics, ID hodnotícího uživatele (případně session ID), a hodnocení.

Přihlašování

Dokumentace zde.

  • Lyrics se budou stahovat přes login a heslo.
  • Zamezí to crackům
  • Provedení: Dvě možnosti. Jednodušší a složitější.
    • S každým požadavkem posílat i jméno a heslo.
      • Heslo může být md5
      • Jenže jakmile někdo uvidí cizí request, může se za něj vydávat → šíření user name a hesla, a jsme kde jsme byli.
    • Druhá možnost: Autentizace a session numbers. Jak?
      • Klient se bude chtít přihlásit
      • Server pošle náhodný řetězec (challenge)
      • Klient jej spojí se svým heslem a pošle md5( challenge + md5(heslo) )
      • Na serveru bude uchované md5() hesla, provede se to samé
      • Pokud budou stejné, klientovi se pošle session ID v cookie. Od té doby s ním může po nějakou dobu pracovat.
      • Tímhle způsobem se nebude nikdo moci vymlouvat, že se přes jeho ID připojuje někdo jiný.
      • Pokud se tedy ID začne šířit, má problém :-)
      • Resp. povolíme použití jednoho ID jen z jedné IP adresy v rámci jedné session.

Autorství lyrics (credits)

  • Lidi mají tendenci do Lyrics dávat svůj podpis.
  • Tomu předejdeme tak, že jim umožníme tento údaj oddělit.
  • Při přidávání se také odešle jejich username, případně se použije session ID.
  • Na serveru se k lyrics přidá záznam o tom, kdo jej poslal.
... read more →
2018-07-31

My Linux Notes

My Linux Notes

Installing Trac 12 on Centos 5.5 – requires Python 2.6

SSH tunelling

Mapovani vzdaleneho portu na vzdalenem stroji na lokalni port:

ssh -L localPort:TargetPC:RemotePort PCsSSHaccountem

Zpristupneni lokalniho portu na zvoleny port vzdaleny:

ssh -R VzdalenyPort:LokalniPC:LokalniPort PCsSSHaccountem

Bash string operations

${parameter:-word}   # Provide a default if parameter is unset or null.

${variable%pattern}   # Trim the shortest match from the end.
${variable##pattern}  # Trim the longest match from the beginning.
${variable%%pattern}  # Trim the longest match from the end.
${variable#pattern}   # Trim the shortest match from the beginning.

Current script

scriptPath="$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")"
scriptDir=`dirname "$scriptPath"`

JAVA=/mnt/jqa/jdk1.6.0_18-x86_64/bin/java

$JAVA -cp $scriptDir/JiraBot-1.1.04.jar:`ls $scriptDir/lib/*.jar | awk '{ORS=":";print}'` org.jboss.jirabot.Main

Colorful prompt

PS1='${debian_chroot:+($debian_chroot)}\e[1;31m\u@\h:\w\$\e[m '

32 green
35 magenta
40 white
31 red
33 yellow
34 blue
# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ] ; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> \(.*\)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done

(from Tomcat's star­tup.sh)

##  Resolve a softlink.
function resolve(){

  PRG="$1"

  if [ "" == "$1" ] ; then
    return ""
  fi

  if [ ! -x "$PRG" ] ; then
    PRGW=`which "$PRG"`
    if [ ! -x "$PRGW" ] ; then
      RET=""
      return -1
    fi
  fi


  while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
      PRG="$link"
    else
      PRG=`dirname "$PRG"`/"$link"
    fi
  done

  RET=$PRG
  return 0
}

##  If called instead of sourced
if [ "resolve" == "${0: -7}" ] ; then
  if [ "" == "$1" ] ; then
    echo "Usage:  resolve <softlink>";
    exit
  fi

  resolve $1
  if [ "" == "$RET" ] ; then
    echo "$PRG not found."
  else
    echo $RET;
  fi
fi

Snippets

cvs -d:gserver:cvs.devel.redhat.com:/cvs/dist checkout httpd
tcpdump -w snap -s2000 -i eth0
keytool -list -keystore /qa/home/ozizka/opt/jdk1.6.0_18/jre/lib/security/cacerts
keytool -import -alias support.stage.redhat.com -keystore /qa/home/ozizka/opt/jdk1.6.0_18/jre/lib/security/cacerts -file stage-cert.pem
# Debian root
PS1='\[\e[1m\]\[\e[31m\]\u@\h \[\e[0m\]\[\e[32m\][\[\e[33m\]\t\[\e[32m\]]\[\e[33m\]\[\e[1m\] \w\[\e[32m\]\[\e[0m\] \$ '

# Debian:
export PS1='${debian_chroot:+($debian_chroot)}\e[1;34m\u@\h:\e[1;33m\w\e[1;34m\$\e[m '

# Generic:
export PS1='\e[1;34m\u@\h:\e[1;33m\w\e[1;34m\$\e[m '

# Plain:
export PS1='\u@\h:\w\$ '

export PATH=$JAVA_HOME/bin:$PATH
... read more →
2018-07-31

Úvod do J2EE

Úvod do J2EE

Komu tento úvod určen

Úvod píšu pro lidi, kteří (stejně jako dříve já) chtějí proniknout do J2EE, ale ztrácejí se v záplavě pojmů a zkratek. Předpokládám znalost webových standardů typu HTML, XML, HTTP a podobně, a dále znalost technologií Java 5.0+ – tj. jazyk, standardní knihovny J2SE, princip fungování tříd.

Úvod se snažím psát co nejpraktičtěji – popisuji tedy technologie v pořadí, v jakém jsem se s nimi setkal já (nebo v jakém by to aspoň bývalo bylo nejlepší).

Na komerčních knihách mě často štve, že jsou psané jak pro debily – každý detail odrbávají na dvě stránky. Já předpokládám, že jste inteligentní lidé, proto jeden fakt uvádím sice se snahou, aby bylo jeho vysvětlení srozumitelné a pochopitelné, ale uvedu ho jen jednou. Pokud moje vysvětlení nepochopíte, tak se omlouvám :-) a doporučuji Wikipedii, která pamatuje i na to, že člověk nemusí o daném tématu vědět vůbec nic.

Úvod je skutečně velmi povrchní a nenaučí vás žádné konkrétní postupy – je to zkrátka pomůcka pro zorientování se ve světě J2EE. Pokud již základní orientaci máte, potom je pro vás spíše oficiální J2EE tutoriál (v angličtině, rozsahem cca jako 600-stránková kniha).

Fajn, i když trochu starší, je také procvičovací tutoriál pro Eclipse IDE.

Co je J2EE

Zkratka J2EE (nověji Java EE) označuje skupinu technologií, která se používá pro vývoj tzv. „enterprise aplikací“ (čti entrprajs).

Co je enterprise aplikace není zcela jasně ohraničitelné, ale dá se říci, že to je aplikace, ve které se využívají pokročilé postupy jako clusterování (běží na více serverech / systémech / databázích …), distribuované transakce (transakce napříč clustery), fail-over (při výpadku převezme funkci jiná část systému), vzdálené volání, a další.

Typickými představiteli enterprise aplikací jsou například rozsáhlé podnikové systémy, bankovní aplikace, webové aplikace. Nás bude zajímat podmnožina J2EE používaná pro vývoj webových aplikací.

Na tomto místě je v knihách obvykle podrobný teoretický rozbor J2EE technologií; Avšak jak jsem předeslal, úvod se snažím psát co nejpraktičtěji, proto uvedu jen úplně nejnutnější pojmy a zkratky; zbylé haldy si necháme na později a vrhneme se rovnou na software.

Servlety

V době rozvoje Javy si její tvůrci a příznivci řekli, že by to mohla být šikovná technologie pro tvorbu dynamických webů – koneckonců jde jen o generování HTML a dalších kódů.

První přístup byl ten, že se vytvoří Java programy, které budou fungovat podobně jako CGI – dostanou na vstup HTTP požadavek a vrátí kód stránky. Tak vznikly servlety. Je to krapet složitější – servlet není přímo program, ale spíše třída, která má určité metody jako doGet(...) a doPost(...), které se pro každý požadavek volají. V parametrech dostanou informace o požadavku, o session, a referenci na objekt odpovědi.

public class HelloServlet extends HttpServlet {

  public void doGet (HttpServletRequest pozadavek, HttpServletResponse odpoved)
    throws ServletException, IOException {

    odpoved.getWriter().println("<html><body>Hello, world!</body></html>");
  }
}

Pak takovouto třídu zabalíte do JAR archivu spolu s konfigurákem WEB-INF/web.xml:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http:/java.sun.com/dtd/web-app_2_3.dtd">
  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>test.HelloServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
  </servlet-mapping>
</web-app>

Potom už jen archiv „deploynete“ a aplikace jede.

Jak vypadá deploynutí se liší podle serveru. Nejlépe to má udělané JBoss AS / JBoss Web, na kterém JARko prostě nakopírujete do adresáře deploy a hotovo. V Tomcatu je třeba jít do manažera aplikací a v něm .jar nahrát přes formulář.

Pochopitelně konfigurace každého servletu a generování HTML stránek přimo v Java kódu je dost otravné:

PrintWriter vystup = odpoved.getWriter();
vystup.write("<h1>Ahoj " + session.getAttribute("name") +"!</h1>");
vystup.write("<p>Takhle nějak se generuje stránka ze servletu.</p>");

Představte si takhle psát celou stránku. Proto se vývojáři poohlédli, jak se to řeší v jiných technologiích, například ASP nebo PHP (tehdy ještě pravěké verze), a viděli, že daleko lepší přístup je psát HTML stránku a do ní tu a tam vložit nějaký kód, kterého je obvykle spíše menšina. No a tak vznikla technologie JSP.

Servlety mají dodnes svoji nezastupitelnou roli. Je třeba si uvědomit, že webové aplikace negenerují jen HTML stránky. Na generování binárních výstupů nebo XML dokumentů (např. pro webové služby) se stále používá Servlet API.

JSP – Java Server Pages

<h1>Ahoj <%= session.getAttribute("name") %>!</h1>

Rovnou při vzniku měla mnohem více možností, než konkureční způsoby vkládání kódu do HTML (můj názor). A to především díky zvláštním tagům, jejichž interpretaci mají na starosti Java třídy. Takový tag vypadá například takto:

<html:link action="/logout">Odhlásit</html:link>

Zrovna tento tag není úplně dobrý příklad, zrovna mi padnul pod ruku. ***Dát lepší příklad. Lepší by byl třeba tento: (Poznámka pro znalé: Tento kód jsem si z hlavy vymyslel, neodpovídá přesně tagům JSTL knihovny.)

<cache:cache key="vypis_uzivatelu">
  <sql:query sql="SELECT * FROM users ORDER BY name" var="resultUsers" />
  <table>
    <c:foreach from="resultUsers" var="i">
      <tr><td><c:out value="${resultUsers[i]}"/></td></tr>
    </c:foreach>
  </table>
</cache:cache>

Ne, nelekejte se – neřeší se celá aplikační logika pomocí XML elementů (také to tak na mě z některých tutoriálů působilo). Elementy, které vidíte, jenom představují celkem pohodlné rozhraní ke knihovnám, které zajišťují jejich funkčnost. Například existuje knihovna pro cache, díky které stačí kešovaný kousek stránky obklíčit elementem <cache:cache> (může se jmenovat libovolně, jméno můžete sami upravit), a knihovna už sama zajistí buď provedení kódu vevnitř, nebo vytažení již uloženého výsledku.

V poznámce výše jsem zmínil knihovnu JSTL (JSP Standard Tag Library). Můžete se podívat na jeji stránky http://jakarta.apache.org/…c/intro.html. Ale to jsme pořád na nejnižší úrovni možností těchto elementů. Opravdu pokročilé knihovny (které už jsou obvykle součástí nějakého frameworku a spolupracují s jeho zbylými částmi) obvykle poskytují automatizaci vysoké úrovně typu obsluhy, vyplňování a validace formulářů, AJAXu, správy šablon, atd.

Další pěknou vlastostí JSP je jazyk EL – Expression Language, pomocí kterého můžete do stránky stručně začlenit nějakou dynamickou hodnotu (teď zrovna nevím, jestli to je zrovna takhle, píšu z hlavy):

Ahoj ${session.attributes['name']}

Možnosti jazyka EL samozřejmě nekončí výpisem nějaké hodnoty. Můžete vyjádřit aritmetické operace, různě formátovat, volat statické Java funkce, které si sami naprogramujete, a další. (PHPčkářům by to mohlo připomínat Smarty.)

Životní cyklus J2EE aplikace

Pro lidi, kteří znají jen PHP, je pojem „životní cyklus“ trochu novinkou. PHP má totiž životní cyklus úplně nejjednoduší možný:
Přijde požadavek, apache jej předá PHP, to zjistí, který skript má načíst, přeparsovat a vykonat, skriptu předá požadavek, pak se řídí instrukcemi ve skriptu, a nakonec skončí. Tento postup může být různě optimalizovaný, např. PHP může udržovat přeparsované skripty v paměti, použít jedno PHP vlákno vícekrát, a podobně.

Oproti tomu J2EE aplikace je opravdu aplikace v pravém slova smyslu:
Na serveru se spustí a běží, dokud ji neukončíte. Jednotlivé požadavky potom nejsou jejími jednotlivými spuštěními, ale jen voláním metod jejích tříd. Z toho plynou leckteré velké výhody.

Jako začátečník spatřuji jednu z největších výhod v tom, že stav aplikace nemusím někam ukládat do session či podobně, ale sám přetrvává. Pokud na serveru vytvoříte nějaký objekt a uložíte ho kamsi, tak tam přetrvá, dokud ho neodstraníte. Viditelný může být pro všechny session, pro všechny požadavky. Tuto vlastnost pochopitelně velmi hojně využívají téměř všechny frameworky, různé cache nástroje, správci zdrojů (např. spojení do databáze) atd. Samozřejmě se nejedná o náhradu perzistence; může ji však skvěle doplňovat.

Servery

Pokud chcete začít s vývojem webových aplikací s J2EE, přijdete zprvu asi do kontaktu s nějakým serverem, který je umí vykonávat. Takových serverů je mnoho od různých výrobců. Nazývají se kontejnery servletů (servlet containers), někdy je na ně nabaleno několik dalších „bundled“ technologií, a ty se potom honosí názvem aplikační server. U obyčejného kontejneru ale o nic nepřijdete – víceméně všechnu funkčnost si do něj můžete přidat sami, a profesionálové se k tomu u menších projektů dokonce přiklánějí raději.

Zde je seznam neznámějších:

  • Apache Tomcat (kontejner) – dost možná nejpoužívanější pro J2EE webové aplikace. Je součástí J2EE modulu pro NetBeans.
  • Jetty (kontejner) – „lightweight“ (jak rád říkám, lehkovážný :-) – menší nároky na paměť, rychlejší.
  • JBoss AS (aplikační server) – asi nejrozšířenější aplikační server; vyvíjí ho firma RedHat. Vyznačuje se vysokou modularitou na základě mikrojádra.
  • JBoss EAP (aplikační server) – „ostrá“ verze JBoss AS – důkladně otestovaný AS + framework Seam.
  • JBoss Web (kontejner) – odlehčená verze JBoss AS, určená pro účely, pro které se používá Tomcat. Snoubí se v něm jednoduchost kontejneru a výhody JBossu. Osobně jsem si jej docela oblíbil.
  • Sun Java system Application Server (aplikační server) – neohrabané jméno, proto jej často na webu uvidíte pod zkratkou SJSAS; jinak docela dobrý.
  • GlassFish (aplikační server) – komunitní verze SJSAS. Je součástí J2EE modulu pro NetBeans.
  • IBM WebSphere (aplikační server) – nezkoušel jsem.
  • BEA WebLogic (aplikační server) – nezkoušel jsem.
  • Caucho Resin (aplikační server) – nezkoušel jsem.

Více najdete na Wikipedii: Comparison of Application Servers.

V tomto úvodu se budu zabývat asi hlavně kontejnerem Tomcat, jelikož jeho správa je nejjednodušší. Průběžně budu upozorňovat na to, co v Tomcatu chybí oproti aplikačním serverům.

Nainstalujte si tedy některý z výše uvedených, doporučuji Apache Tomcat. Zapamatujte si uživatelské jméno a heslo pro administraci a port, na kterém apache poběží – jejich neznalost je častou příčinou delší prodlevy v postupu nováčků. Po instalaci a spuštění se rovnou podívejte na úvodní stránku. Dokumentaci zatím neřešte, je pro vás zatím moc složitá. Podívejte se na administrační část – odkaz „Tomcat Manager“ vpravo nahoře. Zadejte jméno a heslo, které jste si zapamatovali při instalaci. Standardně je to admin / adminadmin. U jednotlivých aplikací (zatím jich tu moc není) vidíte odkazy „Stop, Start, Reload, Undeploy“. Nemačkejte na ně – zrušili byste si možnost správy Tomcatu (bohužel to není blbuvzdorné). Trochu rozvedu, k čemu jsou – čímž se dostáváme k tématu, jak se J2EE aplikace dostávají na server.

Deploy = upload aplikace (zjednodušeně řečeno)

J2EE aplikace se obvykle na server umisťují v jednom souboru s příponou .war – Web ARchive. Ten má danou strukturu souborů a adresářů – ta je dost důležitá a budete se s ní setkávat často (hlavně když něco nepůjde). Například v Tomcat Manageru (ona stránka, kterou máte asi stále ještě otevřenou) provedete deploy pomocí uploadu WAR souboru na server. Proces ale nezahrnuje jen zkopírování – kontejner rovnou aplikaci také rozbalí, prohlédne konfiguraci, podle ní upraví prostředí pro aplikaci a svoje prostředí (zejména vytvoří zdroje typu připojení do databáze atd.), aplikaci spustí a zavolá její metodu init().

Aby to zas nevypadalo, že s Javou je svět krásný a ideální, tak musím uvést, že při tomto kroku bývají největší problémy: Na serveru kolidují verze knihoven kvůli hierarchii tzv. class-loaderů – to jsou nástroje pro načítání tříd do JVM a na serveru je jich hned několik. Když stejnou třídu (dokonce i ze stejného souboru) načte více classloaderů, z hlediska JVM jsou to jiné třídy, a pak dostanete třeba takovéto výjimky.

Začátečník (jak si dobře pamatuji) s tím může mít velké probémy, ale není to zas až tak strašné, pokud nastudujete trochu teorie – např. dobrý článek o classloaderech na Dagblogu, a znáte strukturu classloaderů vašeho serveru. Je to už ale trochu pokročilé téma.

Nejčastější chybou je duplikátní výskyt knihoven – jednou ve vaší aplikaci, jednou třeba v /lib adresáři serveru. To se často děje proto, že se snažíte vyřešit problém nekompatibilních verzí tříd. Proto také doporučuji webové aplikace napřed zkoušet na kontejnerech, u kterých je toto riziko menší.

Součásti Tomcatu

Začátečníky často mate spoustu názvů, se kterými se při práci s Tomcatem setkají – bohužel zejména při výpisu chyb, ale částo také při konfiguraci. Proto zde uvedu, co představují jednotlivá jména součástí Tomcatu. Samotné zmíněné technologie probereme dále. ***Možná přesunout dále, až za představení technologií.

  • Catalina – v podstatě Javové jádro serveru. Vykonává servlety, tedy samotný Java kód webové aplikace.
  • Jasper – ta část, která převádí JSP kód na Java servlety.
  • Coyote – stará se o HTTP komunikaci, zpracovává požadavky na volání servletů.

Tolik tedy zatím k serverům, a teď se podíváme po něčem, v čem budeme aplikace vyvíjet.

IDE – prostředí pro vývoj

Prostředí pro vývoj J2EE aplikací je opět více. Nejznámější jsou Eclipse a NetBeans. Začátečníkům rozhodně doporučuji NetBeans – na rozdíl od Eclipse obvykle vše funguje „z fleku“.

NetBeans mají přímou podporu Sunu a mají celkem slušnou komunitu. Navíc jde o projekt původem od českého kdysi-studenta; časem projekt koupil Sun a udělal z něj svoje –hlavní– mainstreamové vývojové prostředí – podobně jako má Microsoft svoje Visual Studio.

Stáhněte si tedy NetBeans, balíček Web & Java EE. V něm je zahrnutý i Apache Tomcat. Proč jsem vás tedy nechal stahovat samostatný Tomcat?

  • Tomcat zahrnutý v NetBeans se po zavření IDE ukončí.
  • U samostatného se lépe spravují knihovny, uživatelé a další nastavení.
  • Se samostatným jde z NetBeans pracovat stejně jako s tím vestavěným.

K vývojovému prostředí se ještě dostaneme, nyní k samotným technologiím.

Jednou z technologií, které jsou na J2EE nejlákavější, je perzistence objektů, či objektově-relační mapování. Ta slouží k automatickému „rozkládání“ objektů (hlavně) do relační databáze a jejich zpětné načítání. Dále je možné provádět nad objekty hromadné akce a dotazy pomocí jazyka podobného SQL. Objektům (resp. jejich třídám), se kterými v perzistenci pracujeme, se říká entity.

Hibernate

Nejznámějším nástrojem pro perzistenci je Hibernate. Ten používá jazyk HQL. Pro mapování, tedy k popisu, jak se objekty které třídy rozkládají do tabulek v databázi, sloužily dříve XML soubory.

<hibernate-mapping>
 <class name="ModelPlane" table="model_plane">
   <id name="id" column="id_model" type="java.lang.Long">
     <generator class="increment"/>
   </id>
   <property name="name" column="name" type="java.lang.String" />
 </class>
</hibernate-mapping>

V poslední době se ale rozmáhá pohodlnější způsob – @anotace.

@Entity
public class ModelPlane {

    private Long id;
    private String name;

    @Id
    @GeneratedValue
    @Column(name = "id_model")
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

Manuál k anotacím najdete zde – ovšem pokud skutečně zrovna začínáte, raději na to vůbec nekoukejte, nebo se rychle ztratíte. ***Odstranit? Spíše si přečtěte nadpisy, ať chytnete slinu na to vše, co Hibernate umí.

Hibernate lze použít i mimo J2EE – konec konců ukázkové aplikace jsou někdy obyčejné konzolové J2EE prográmky.

***Vložit ukázku SQL DML, mapovacího XML a Java kódu – např. faktury.

Detailní popis, jak Hibernate funguje a jak se s ním pracuje, vydá na mnohasetstránkovou knihu (viz Hibernate in Action). Proto vás jen odkážu na www.hibernate.org, kde najdete velmi dobrý tutoriál, ze kterého cca během dne pochopíte, oč jde a jak se to programuje.

JPA – Java Persistence API

Ani perzistence neunikla tendenci ve světě Javy vše standardizovat a vymýšlet společná aplikační rozhraní. Tak vznikl standard JPA, což je v podstatě trochu ořezané Hibernare API, ale také přinesl možnost místo XML souborů používat @anotace, což jsou (pro ty, co neznají) meta-informace zapsané přímo v kódu Java tříd za zavináčem:

@Entity
@Table(name="users")
public class User {
  @Id public int id;
  @Column( name = "jmeno" ) public String krestniJmeno;
  ...
}

Trochu kontraproduktivně to vneslo bordel do názvosloví (vzniklo mnoho „skoro-synonym“), ale na to si zvyknete :-)

Frameworky

Technologie JSP sama o sobě je pořád dost slabá a pro vývoj velkých aplikací nevhodná. Proto se postupem času objevily stovky frameworků, z nichž desítky se opravdu často používají. Slouží nejrůznějším účelům pro různé vrstvy aplikací. O několika z nich si ve stručnosti povíme.

Zpracování požadavku se ve většině frameworků rozděluje na zhruba dvě části: Na akci a renderování stránky.

Akce je jednoduše provedení činností, které případné vyplývají z požadavku (např. vytvoření účtu), a dále příprava dat, které se použijí ve stránce.

Renderování je prostě vygenerování popisného kódu obsahující výsledný dokument – XHTML, WAP, SOAP, ale i binární jako PDF dokument pro tisk či PNG obrázek. Při tomto generování se obvykle použijí data připravená v akci, a k samoznému generování se často používá některý z přehršle šablonovacích systémů.

Struts

Největší obliby (podle mého pozorování) došel framework Struts. Ten slouží právě zejména k rozdělení a řízení toku aplikace – kdy provést jakou akci, jaké jí předat parametry, kam pokračovat, atd…

Má dvě hlavní verze:

Verze 1.x.x, která je ve své podstatě celkem jednoduchá a oproti verzi 2 toho moc neumí – čímž ale neříkám, že to málo, co umí, nezvládá dobře nebo že to není důležité. Zejména se totiž stará o aplikační logiku (jakou akci obsluhuje která třída, jaká stránka se má kdy zobrazit, atd.). Dále obsahuje celkem rozsáhlou knihovnu tagů (viz JSP), které plní různé účely.

Později spojením Struts 1 a frameworku WebWorks vznikla verze Struts 2, ve které původní funkčnost Struts 1 tvoří asi 20 %.

Seam Framework

Seam framework z dílny JBoss je známý především díky své části určené pro ulehčení spolupráce JSF a EJB (podle čehož ostatně nese své jméno). Obsahuje však mnohem více součástí, a dalo by se říci, že záběrem konkuruje frameworku Spring.

JSF – Java Server Faces

Sun ze všech nejvíce propaguje framework JSF. Ten do značné míry vychází ze Struts 1, má i podobný záběr funkcionality, ale v lecčems se zásadně liší, a pochopitelně s sebou přináší spoustu standardů a více XML.

Spring Framework

Když jsem se kamaráda – J2EE juniora – poprvé zeptal, k čemu je Spring, řekl: „Spring je naprosto bomba.“ A pokračoval tím, jak mu to ušetří spoustu psaní kódu.

Dnes, kdy jsem mnoho částí Springu již adoptoval a používám, mu musím dát zapravdu, i když on tehdy mluvil z pohledu vývojáře, který projekt nekonfiguruje, pouze využívá jeho efektů. Spring je však bomba i z pohledu správce projektu (seniora, chcete-li) – konfigurace je velmi snadná a jde jak po másle.

A nyní tedy, k čemuže ten spring je. Ve stručnosti se to moc popsat nedá, leda výčtem názvů jeho částí:

  • Inversion of Control – konfiguraci aplikace velmi snadno „vytáhnete“ z kódu do konfiguráků.
  • Spring AOP – opakující se „začátky a konce“ (např. otevření/zavření transakce) v metodách přesunete do jednoho místa a do oněch metod jej vloží Spring.
  • Resources – mnoho nástrojů pro načítání souborů z filesystému nebo z archivu aplikace.
  • Validace, provazování dat
  • Testování
  • Správa transakcí (může být provázáno s AOP)
  • Ulehčení práce s ORM nástroji a iBatisem
  • MVC framework pro webové aplikace a pro „portlety“
  • Integrace s mnoha zobrazovacími nástroji – FreeMarker, Tiles, XSLT, PDF, Excel
  • Podpora vývoje webových služeb
  • Práce s mailem (odesílání mailů z Javy)
  • Podpora skriptovacích jazyků pro programování servisních objektů
  • a další.

Lidem, kteří s J2EE začínají, takový výpis asi moc k ničemu nebude, proto vás rovnou odkáži na články

Další

Pokud hledáte něco pro konkrétní účel, je obvykle dobré podívat se na projekty, které zastřešují jiné projekty – jako jsou Jakarta, zejména v levé části v sekci „Ex-Jakarta“ jsou projekty, které se osvědčily a přesunuly pod projekt Apache – seznam konkrétních projektů pro Javu je opravdu dlouhý. Z těch nejznámějších sem patří:

  • Jakarta Commons (obecné pomůcky pro kdeco)
  • Jakarta Logging (obecný nástroj pro logování, vzniklo podle něj java.util.logging)
  • Struts (webový framework, viz výše)

A mimojiné také server Tomcat, buildovací nástroj Ant, nástroj pro správu projektů Maven, práce se soubory MS Office POI, a další.

Dalším takovým hnizdem projektů je JBoss, nyní spravovaný firmou RedHat, kde je projektů opravdu hodně – asi 35. Mezi ně patří:

  • Hibernate – asi nejpopulárnější pecka – objektově-relační mapování, viz „perzistence“ výše
  • JBoss Application Server (Aplikační server, viz výše)
  • JBoss AOP (implementace AOP, něco jako Spring AOP – viz výše)
  • Seam – framework, který začal jako zjednodušení vývoje v JSF a EJB, ale má namířeno na posty Spring Frameworku
  • a další obecné nástroje – cache, vzdálené volání, správa transakcí, webové služby, messaging, a další.

Nenechte se ale zahltit – pokud se zanoříte do všech projektů a budete chtít zjistit, co vše umí, bude to čtení na několik dnů. Já doporučuji tento postup: Koukněte se na nějaké Java fórum a hledejte témata s nadpisem typu „Jaký framework používáte pro XYZ a proč?“ V takových se obvykle nespustí flamewar, ale naopak věcná diskuze, kde se velmi stučně dozvíte shrnutí, k čemu který slouží, respektive k čemu jej kdo používá, a často i krátké a výstižné ukázky kódu.

EJB

EJB, Enterprise Java Beans : v podstatě jde opět o snahu standardizovat. Rozděluje „Beany“ (java třídy s určitým účelem) na několik kategorií, podle účelu, ke kterému mají sloužit – jestli mají provádět nějaké operace, nebo poskytovat nějakou službu, nebo jestli mají představovat nějakou entitu, a podobně. S tím souvisí pojmy „Stateful“, „stateless“ a další. ***Doplnit

Technologie EJB se týká především aplikačních serverů a enterprise aplikací. Má více verzí, které se docela zásadně liší. V současnosti je aktuální verze 3.0, která je snad první jednoduše použitelná. Ovšem na webu (v době psaní) narazíte povětšinou na materiály o EJB verze 2.0, z nichž leckteré to s klidným svědomím ani neuvedou, takže vy se pak zcela marně snažíte v aplikačním serveru pracujícím na EJB 3.0 aplikovat postupy pro EJB 2.0.

Tuto sekci o EJB uvádím hlavně proto, že na zkratku EJB se dá narazit hodně často. Studium EJB doporučuji odložit na dobu, kdy budete mít v ruce JSP, Struts a Hibernate. ***Dopsat

Závěr

Zatím vše. Jelikož se s obrovským světem J2EE stále seznamuji, vyhrazuji si právo plácat tu nesmysly, ale snažím se, aby uvedená fakta odpovídala pravdě – konec konců, účelem tohoto dokumentu je velmi rychle seznámit nováčky s J2EE. Do podrobností zde zacházet nechci, těch je na webu velká spousta.

Pokud jste zkušení J2EE harcovníci, uvítám jakékoliv opravy na e-mailu ondra@dynawest.cz.


Napsáno 2007–08, aktualizováno tu a tam, naposledy 2008–10.

... read more →
2018-07-31

JBoss Microcontainer with JBoss AOP – Howto with sample application

JBoss Microcontainer with JBoss AOP – Howto with sample application

A very brief intro to JBoss AOP.

Prerequisites

This tutorial is a follow-up to the JBoss Microcontainer intro – read that first if you haven't yet.

What is AOP good for?

AOP (Aspect Oriented Programming) is a concept of moving a „programatic envelopes“ away from the methods. What I call a programatic envelope is that kind of annoying code you have to repeat at the end or/and the beginning of many methods.

Usual textbook examples of AOP usage are:

  • Opening and closing of a transaction
  • Locking and unlocking of synchronization locks
  • Logging of debug messages
  • Measuring the time of method execution

However, AOP is particulary useful for frameworks for their need of generalization. It can help it to put the envelope code around method which it still does not know.

How does AOP work?

First, you mark some Java constructs (methods, fields, constructors, …) to be AOP'ed (encapsulated with your envelope code).
Then you need so-called „aspect“ – that is the official name for envelope code.
Then you need some tool which will bind the aspect to those methods. This is done by advanced techniques like byte-code instrumentation and class reflection.

Why JBoss AOP (and not the others)?

JBoss AOP offers much more then the other AOP frameworks (like Spring AOP).

  • It can bind not only to methods, but also to constructors and fields.
  • As it's not proxy based, you don't need to treat objects only through interfaces.
  • You can weave any existing class without any code changes.
  • Annotation-based weaving – intercept Java constructs which are annotated by some anotation.
  • Weaving at compile time gives much better performance.
  • Configuration by annotations – if you don't like XML, you can set the aspects and bindings using annotations like @Aspect, @Interceptor, @Bind etc. See Chapter 6. Annotation Bindings.
  • Runtime weaving, called „HotSwap“ – allows bytecode of your classes to be weaved in runtime.

Terms

Copied from JBoss AOP reference docs.

Joinpoint
A joinpoint is any point in your java program. The call of a method. The execution of a constructor the access of a field. All these are joinpoints. You could also think of a joinpoint as a particular Java event. Where an event is a method call, constructor call, field access etc…
Invocation
An Invocation is a JBoss AOP class that encapsulates what a joinpiont is at runtime. It could contain information like which method is being called, the arguments of the method, etc…
Advice
An advice is a method that is called when a particular joinpoint is executed, i.e., the behavior that is triggered when a method is called. It could also be thought of as the code that does the interception. Another analogy is that an advice is an „event handler“.
Pointcut
Pointcuts are AOP's expression language. Just as a regular expression matches strings, a pointcut expression matches a particular joinpoint.
Introductions
An introduction modifies the type and structure of a Java class. It can be used to force an existing class to implement an interface or to add an annotation to anything.
Aspect
An Aspect is a plain Java class that encapsulates any number of advices, pointcut definitions, mixins, or any other JBoss AOP construct.
Interceptor
An interceptor is an Aspect with only one advice named „invoke“. It is a specific interface that you can implement if you want your code to be checked by forcing your class to implement an interface. It also will be portable and can be reused in other JBoss environments like EJBs and JMX MBeans.

What we're willing to achieve?

We want to catch all calls to methods that affect the fuel in the Car. To make this easily achievable with AOP, let's follow a convention that all changing methods are setters and all fuel-related properties names end with „Fuel“.

For the purposes of this example, we've changed the Car class to have two fuel-related properties:

public class Car {
  public int litresOfFuel;
  public int getLitresOfFuel() {    return litresOfFuel;  }
  public void setLitresOfFuel( int litresOfFuel ) {    this.litresOfFuel = litresOfFuel;  }

  public int reserveFuel;
  public int getReserveFuel() {    return reserveFuel;  }
  public void setReserveFuel( int reserveFuel ) {    this.reserveFuel = reserveFuel;  }

  public String toString(){
    return "Car \""+this.name+"\" with "+(this.litresOfFuel + this.reserveFuel)+" litres of fuel.";
  }
  ...
}

Creating an Interceptor („envelope“)

This is a simple interceptor that will just notify us when triggered.

package cz.zizka.ondra.jbmctest;

import java.util.logging.Logger;
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.instrument.Untransformable;
import org.jboss.aop.joinpoint.Invocation;

public class FuelInterceptor implements Interceptor, Untransformable {

  private static final Logger log = Logger.getLogger( FuelInterceptor.class.getName() );

  public Object invoke(Invocation invocation) throws Throwable
  {
    Object target = invocation.getTargetObject();
    if( target instanceof Car ){
      log.info("The fuel is being changed for the car '"+((Car)target).getName()+"'.");
    }
    return invocation.invokeNext();
  }

  public String getName() {
    return FuelInterceptor.class.getName();
  }
}// class FuelInterceptor

Binding the interceptor to the method calls

For the syntax of AOP pointcuts, see JBoss AOP documentation.

The syntax for our purpose stated above would be:

execution(* cz.zizka.ondra.jbmctest.Car->set*Fuel(..)

The AOP settings go to a special XML file having <aop> as it's root element, and conforming to the JBoss AOP XSD.
From what I've found, this file must be either in META-INF/jboss-aop.xml of your .jar, or anywhere on the filesystem, but you'll have to point to it by the -Djboss.aop.path JVM argument – see 10.2.1. Precom­piled instrumentation and 5.2. Resolving XML.

To let maven put this file to your .jar, store it in src/main/resources (the default path for resources), giving the resulting path src/main/resources/META-INF/jboss-aop.xml.

So let's bind this interceptor to some method calls. In this case, we're binding it to all methods of the Car class whose name has the pattern set*Fuel.

<?xml version="1.0" encoding="UTF-8"?>
<aop>
   <bind pointcut="execution(* cz.zizka.ondra.*->set*Fuel(..))">
       <interceptor class="cz.zizka.ondra.jbmctest.FuelInterceptor"/>
   </bind>
</aop>

Alternatively, it should be possible to put the AOP settings to the JBoss Microcontainer XML (but I wasn't able to get it working):

<deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd"
            xmlns="urn:jboss:bean-deployer:2.0"
            xmlns:aop="urn:jboss:aop-beans:1.0">

  <bean ... /> <!-- Car and garage beans -->

  <aop:interceptor name="FuelInterceptor" class="cz.zizka.ondra.jbmctest.FuelInterceptor"/>

  <aop:bind pointcut="execution(* cz.zizka.ondra.jbmctest.Car->set*Fuel(..)">
    <aop:interceptor-ref name="FuelInterceptor"/>
  </aop:bind>

</deployment>

Maven configuration

After setting Maven to use JBoss repositories (see the JBoss Microcontainer how-to), add these dependencies to your project:

<dependencies>
  <dependency>
    <groupId>org.jboss.microcontainer</groupId>
    <artifactId>jboss-kernel</artifactId>
    <version>2.0.9.GA</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.aop</groupId>
    <artifactId>jboss-aop</artifactId>
    <version>2.1.6.GA</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.microcontainer</groupId>
    <artifactId>jboss-aop-mc-int</artifactId>
    <version>2.0.9.GA</version>
    <scope>runtime</scope>
  </dependency>
</dependencies>

Also, add the JBoss AOP Maven plugin. It binds automatically to the compile phase. This will change the classes code to call your interceptors when a method is being called.

<plugins>
  <plugin>
    <groupId>org.jboss.maven.plugins</groupId>
    <artifactId>maven-jbossaop-plugin</artifactId>
    <version>2.1.3.GA</version>
    <executions>
      <execution>
        <id>compile</id>  <goals> <goal>compile</goal> </goals>
        <configuration>
          <includeProjectDependency>true</includeProjectDependency>
          <aoppaths>
            <aoppath>src/main/resources/META-INF/jboss-aop.xml</aoppath>
          </aoppaths>
        </configuration>
      </execution>
    </executions>
  </plugin>
</plugins>

Test code

public class JBossAopSampleApp {

  public static void main( String[] args ) throws Throwable
  {
    Car myCar = new Car("Red Devil");
    System.out.println( "I have a garage: "+car);

    // Put some fuel in.
    myCar.setLitresOfFuel( myCar.getLitresOfFuel() + 1 );
    myCar.setReserveFuel( myCar.getReserveFuel() + 1 );

    System.out.println( "I have a garage: "+car);
  }

}

The result

Now run the application, and you'll see that the interceptor is really being invoked.

I have a garage: Garage with a car: Car "Red Devil" with 0 litres of fuel.
16.11.2009 11:42:47 FuelInterceptor invoke INFO: The fuel is being changed for the car 'Red Devil'.
16.11.2009 11:42:47 FuelInterceptor invoke INFO: The fuel is being changed for the car 'Red Devil'.
I have a garage: Garage with a car: Car "Red Devil" with 2 litres of fuel.

Sample application

The application created in the examples above can be downloaded here: JBossAOPsample­.zip

... read more →
2018-07-31

How to add existing project's jar to SVN-based Maven repository

How to add existing project's jar to SVN-based Maven repository

See also: Quick and dirty mavenization of an existing project

Bash script for the impatient

#
#  Creates two files:
#
#    1) A bash script with mvn install:install-file commands to push the .jar's to a repository.
#    2) A POM file with dependencies pointing to .jar's in Maven repo, uploaded by the script.
#

if [ -z "$1" ] ; then
  echo "Usage:  mavenize.sh <path-to-dir-with-jars> [<groupId:'fake'>]"
  exit
fi


LIB_PATH=$1
GROUP=${2:-fake}


echo '' > stuffTheRepo.sh
echo '<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
' > pomWithDeps.xml
echo "
  <modelVersion>4.0.0</modelVersion>
  <groupId>$GROUP</groupId>
  <artifactId>deps</artifactId>
  <packaging>pom</packaging>
  <version>0.0-SNAPSHOT</version>
  <name>Fake Maven deps from JARs</name>

  <dependencies>
" >> pomWithDeps.xml


for JAR_PATH in $LIB_PATH/*.jar ; do
  JAR=`basename $JAR_PATH`
  ARTIFACT=${JAR%.jar}
  echo "mvn install:install-file -Dpackaging=jar -DgeneratePom=true -DgroupId=$GROUP -Dfile=$JAR_PATH -DartifactId=$ARTIFACT -Dversion=0.0" >> stuffTheRepo.sh
  echo "    <dependency><groupId>$GROUP</groupId><artifactId>$ARTIFACT</artifactId><version>0.0</version></dependency>" >> pomWithDeps.xml
done

echo "
  </dependencies>

</project>" >> pomWithDeps.xml

chmod u+x stuffTheRepo.sh

How-to for the rest

Copied from Sardine project's READ­ME.txt.

This is a maven repository of the Sardine project.

To add a new version, do the following:
Note: This is not a copy-paste code – edit it according to your situation.
Note: The preferred way is to use the Wagon-SCM Maven plugin, as described on JBoss wiki.

# First, create the sources and javadoc jar's.
zip -9 -b sardine-XX/javadoc/* > sardine-XX/javadoc.jar
zip -9 -b sardine-XX/src/* > sardine-XX/sources.jar

# Let Maven create the directory structure and all the metadata files in the local repository.
mvn install:install-file -DpomFile=sardine-pom.xml -Dpackaging=jar -DgeneratePom=true -DcreateChecksum=true -DgroupId=com.googlecode.sardine -Dfile=sardine-XX/sardine.jar -Djavadoc=sardine-XX/javadoc.jar -Dsources=sardine-XX/sources.jar -DartifactId=sardine -Dversion=XX

# Check out remote SVN-based Maven repository. -N means non-recursive.
svn co -N https://sardine.googlecode.com/svn/maven sardine-mvn --username you@gmail.com

# Download the dir you're going to modify (if it exists).
svn update com/googlecode/sardine/sardine

# Copy the new artifacts to the working copy of the repository.
cp -r ~/.m2/repository/com/googlecode/sardine/sardine sardine-mvn/com/googlecode/sardine/sardine
# Rename the metadata file holding versions info.
mv ~/.m2/repository/com/googlecode/sardine/sardine/maven-metadata-local.xml ~/.m2/repository/com/googlecode/sardine/sardine/maven-metadata.xml

# Add everything new and commit.
svn add --force *
svn commit -m "Maven repo: Added version XX"
  • ~/.m2/repository/ is your local Maven repository.

    On windows it is usually c:\Documents and Settings\user\.m2\repository\.

  • The pom.xml is there because it contains dependency definitions.
... read more →
2018-07-31

SQL koutek

SQL koutek

Jednou z mých oblíbených technologií jsou relační databáze a jazyk SQL. Líbí se mi, jak elegantně se dají některé typy problémů pomocí SQL řešít – zejména grafové úlohy. Například výpočet neuronové sítě v tradičních programovacích jazycích sestává obvykle ze tří vnořených cyklů, v SQL je to cyklus pouze jeden, zbytek vyjádříte v SELECTech. Ale o tom až dále.

Mojí oblíbenou databází je MySQL 5.0. Schválně uvádím verzi, protože jsem si ji oblíl až na základě možnosti psát tzv. Stored procedures.

V průběhu doby jsem při řešení různých projektů vytvořil užitečné procedury a funkce, které usnadňují vývoj procedur pro MySQL a mohly by se kdekomu hodit.

Omlouvám se těm, co nehovoří anglicky, ale zbytek SQL sekce bude většinou právě v angličtině.

Krom toho střádám i své touhy, co by se mohlo (a mělo) v MySQL objevit:

... read more →
2018-07-31

Web, JavaScript, AJAX, and Canvas

Web, JavaScript, AJAX, and Canvas

JavaScript isometric game rendering libraries

I've made up a list of JavaScript libs for isometric rendering.

WebTTD – browser-based Transport Tycoon clone idea.

canvas element selection buffer

English, česky

... read more →
2018-07-31

Webová služba Insolvenční rejstřík – ISIR WS

Webová služba Insolvenční rejstřík – ISIR WS

1.1.2008 spustilo Ministerstvo spravedlnosti na svém serveru justice.cz webovou službu insolvenčního rejsříku , doplněk k informačnímu systému ISIR. S touto službou jsem měl tu čest pracovat a zde bych se rád podělil o zkušenosti v naději, že na tuto stránku narazí i tvůrce služby, firma CCA.

//Update 18.7.2008:// Sepsal jsem Popis dalších nedomyšleností webové služby Insolvenční rejstřík.

//Update 25.7.2008:// Mám první funkční prototypy aplikace pro automatickou kontrolu subjektů v insolvenčním rejstříku.

//Update 8.8.2008:// Přesun projektu: insolvenční rejstřík.

//Update 2.9.2008:// Betaverze aplikace pro automatickou kontrolu insolvenčního rejstříku.

//Update 12.9.2008:// Alfaverze webového rozhraní.

//Update 1.11.2008:// Alfaverze okamžitého upozorňování na události.

WSDL

Asi jako každý jsem začal prohlédnutím definice webové služby WSDL:https://isir.justice.cz:8443/…s/IsirPub001?wsdl. Už ta vás trošku zatahá za oči, protože hledáte nějaké názvy funkcí, které budete volat, a typů, se kterými budete pracovat, ale zde najdete názvy podobného ražení jako getIsirPub001, ns2:IsirPub001Data, IsirPub001SOAP12port_http a tns:IsirPub001SEI_getIsirPub001Response:

<wsdl:service name="IsirPub001">
  <wsdl:port name="IsirPub001Httpport1" binding="tns:IsirPub001HttpBinding">
    <http:address location="https://isir.justice.cz:8443/isir_ws/rest/IsirPub001"/>
  </wsdl:port>
  <wsdl:port name="IsirPub001SOAP12port_http" binding="tns:IsirPub001SOAP12Binding">
    <soap12:address location="https://isir.justice.cz:8443/isir_ws/services/IsirPub001"/>
  </wsdl:port>
  <wsdl:port name="IsirPub001SOAP11port_http" binding="tns:IsirPub001SOAP11Binding">

    <soap:address location="https://isir.justice.cz:8443/isir_ws/services/IsirPub001"/>
  </wsdl:port>
</wsdl:service>

Nádhera, že? Na první pohled autoři služby ponechali jména prostě taková, jaká jim generátor služby (nástroje z Axis) nabídl. Ale budiž, řeknete si, generátor vytvořil, generátor zpracuje. Ne tak v tomto případě.

Generování klienta služby podle WSDL

Moje oblíbené IDE je NetBeans, vytvořil jsem tedy v NetBeans 6.0.1 projekt a v něm se pokusil vygenerovat klienta podle výše zmíněné WSDL definice. Bohužel WSDL pravděpodobně neodpovídá plně standardům, protože už validace WSDL selhává a hlásí, že někde nejsou uvedené atributy address a že vygenerované knihovny klienta služby budou asi nepoužitelné. Což je krásná hláška na začátek, ale pustil jsem se do toho i přesto.

Knihovny pochopitelně nefungovaly. Vygenerovaný kód je celkem nanic. Nevím, jestli za to může WSDL nebo generátor klienta (dost možná že generátor), koneckonců – nejsem odborník na webové služby. Nicméně poté, co jsem kód přepsal, jak má být, opět klient nefungoval – vyhazoval výjimku java.lang.ClassCastException. Chyba byla ovšem v knihovně SAAJ. NetBeans 6.0.1 sice obsahují číselně (nominálně) nejnovější verzi 1.3, ta je ale přes dva roky stará. Je tedy nutné stáhnout nový build SAAJ z adresy https://saaj.dev.java.net/…DocumentList?… , v adresáři NetBeans najít JAR saaj-impl.jar a nahradit jej novým ze staženého JARka.

Pak už tedy volání webové služby funguje. Jenom podotknu, že v zoufalosti během dvoudenního řešení nejen výše uvedených problémů jsem zkoušel volat webovou službu ISIR také z PHP. Výsledkem bylo toto:

500 Internal Server Error
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
        at java.lang.String.substring(String.java:1444)
        at org.apache.axis2.builder.XFormURLEncodedBuilder.extractParametersFromRequest(XFormURLEncodedBuilder.java:155)
        at org.apache.axis2.builder.XFormURLEncodedBuilder.processDocument(XFormURLEncodedBuilder.java:112)
        at org.apache.axis2.transport.TransportUtils.createDocumentElement(TransportUtils.java:160)
        at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:111)
        at org.apache.axis2.transport.http.util.RESTUtil.processXMLRequest(RESTUtil.java:60)
        at org.apache.axis2.transport.http.AxisServlet$RestRequestProcessor.processXMLRequest(AxisServlet.java:788)
        at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:193)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)].server.http.ServletRequestDispatcher.invoke(ServletRequestDispatcher.java:824)
        at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)].server.http.ServletRequestDispatcher.forwardInternal(ServletRequestDispatcher.java:330)
        at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)].server.http.HttpRequestHandler.processRequest(HttpRequestHandler.java:830)
        at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)].server.http.AJPRequestHandler.run(AJPRequestHandler.java:224)
        at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)].server.http.AJPRequestHandler.run(AJPRequestHandler.java:133)
        at com.evermind[Oracle Application Server Containers for J2EE 10g (10.1.2.0.2)].util.ReleasableResourcePooledExecutor$MyWorker.run(ReleasableResourcePooledExecutor.java:192)
        at java.lang.Thread.run(Thread.java:534)

Takže s PHP jsem to raději vzdal úplně.

Princip využití webové služby

Vezměme si moji situaci. Klient chce zjistit, zda v daném okamžiku je nějaká fyzická osoba vedena jako dlužník či ne. Zdálo by se to velmi jednoduché, kdyby služba ISIR měla nějakou funkci (třeba s výstižným názvem „getIsirPub0012_2“), která by přebírala rodné číslo ve formátu RRMMDD/AAAA, a vracela true/false. Chápu že to je značně zůžená funkčnost, ale jak už jsem psal, je to asi to, k čemu službu využije polovina uživatelů. Další polovina ji využije stejně, ovšem pro IČ.

Bohužel, to je komfort, o kterém si můžeme nechat zdát. Služba ISIR WS funguje úplně jinak.

Představte si, že vám Ministerstvo životního prostředí zadá úkol vytvořit webovou službu, která umožní široké veřejnosti zjistit teplotu naměřenou v jakékoliv meteorologiké stanici v ČR. Firma CCA (tvůrce ISIR WS) by to nejspíš udělala tak, že by zpřístupnila záznamy změn teplot oproti předchozímu stavu za celou historii existence služby od jejího spuštění. Takže kdo by chtěl aktuální teplotu v Brně, stáhnul by si v dávkách po tisíci řekněme miliardu záznamů v logu včetně záznamů pro tisíce stanic, které ho vůbec nezajímají, aplikoval by změny od začátku zaznamenávání, a nakonec by odečetl aktuální stav stanice Brno ve vlastní databázi.

Tak přesně totiž funguje webová služba insolvenčního rejstříku! Nejedná se o nic jiného než o replikaci databáze pomocí zpracování logu změn. Pod záštitou „maximální dostupnosti služby“ služba jenom zpřístupňuje statické záznamy z logu bez jakékoliv další bussines logiky!

Což by ještě nebylo tak špatné, kdybyste jako programátor klienta věděli, co který úkon znamená. Já se přiznám – nemám právní vzdělání, a proto to nevím. Proto mi polovina záznamů ve výstupu webové služby nedává smysl a nechápu, proč tam jsou. Předveďme si ukázku.

Když se podíváte na výstup webové služby, evidentně se jedná o zaznamenané operace uživatelů informačního systému insolvenčního rejstříku (ISIR). Pokud tedy nějaký soudce v Praze zakládá spis týkající se nějakého dlužníka, nejprve v systému klikne na tlačítko „Nový spis“. Vyplní jeho značku a stiskne „Vytvořit“. Tím se v logu ISIR vytvoří záznam a do výstupu webové služby přibyde:

ID: 2760
Cas: 23.1.2008 9:11:46
Spis: INS 132/2008 Odd: A  Poradi: 2, Typ: 185 (Vyhláška o zahájení insolvenčního řízení)

Data:
<?xml version = '1.0' encoding = 'UTF-8'?>
<tns:udalost ... >
  <idOsobyPuvodce>MSPHAAB</idOsobyPuvodce>
  <vec>
    <druhStavRizeni>NEVYRIZENA</druhStavRizeni>
  </vec>
</tns:udalost>

Tím zatím věc končí a soudce se na nějakou dobu odmlčí. Mezitím soudci a úředníci na ostatních soudech pilně pracují a klikají v informačním systému jako o život, takže vznikne dalších 100 záznamů. Zhruba po třech hodinách se pražský soudce opět probere a v informačním systému přejde do sekce „Návrh – přílohy“, čímž nám vznikne tento velice duchaplný a užitečný záznam:

ID: 2853
Cas: 23.1.2008 11:57:20
Spis: INS 132/2008  Odd: A  Poradi: 3, Typ: 23 (Návrh - přílohy)

Data:
<?xml version = '1.0' encoding = 'UTF-8'?>
<tns:udalost ...>
  <idOsobyPuvodce>MSPHAAB</idOsobyPuvodce>
  <vec>
    <druhStavRizeni>NEVYRIZENA</druhStavRizeni>
  </vec>
</tns:udalost>

Po dalších pěti hodinách a další stovce záznamů z jiných soudů se soudce vrátí z oběda a v IS klikne na tlačítko „Nový pokyn insolvenčního soudu“, a tím vzniká další velmi užitečný záznam:

ID: 2954
Cas: 23.1.2008 16:48:44
Spis: INS 132/2008  Odd: A  Poradi: 4, Typ: 204 (Pokyn insolvenčního soudu)

Data:
<?xml version = '1.0' encoding = 'UTF-8'?>
<tns:udalost ...>
  <idOsobyPuvodce>MSPHAAB</idOsobyPuvodce>
  <vec>
    <druhStavRizeni>NEVYRIZENA</druhStavRizeni>
  </vec>
</tns:udalost>

Tím v této dávce tisíce záznamů informace o tomto spise končí a vy musíte stáhnout další tisícovku.

Služba insolvenčního rejstříku byla spuštěna 1.1.2008. Od té doby do dneška (18.3.2008) log obsahuje CCA. 18 000 položek. Pokud si tedy v roce 2030 založíte firmu a budete chtít o svých klientech zjistit, zda nejsou vedeni jako dlužníci, budete si muset stáhnout odhadem (lineární interpolací) 1 500 000 záznamů a podle nich zreplikovat databázi informačního systému insolvenčního rejstříku!

Ruku na srdce – nezdá se vám nepřiměřené, aby si _každý_, kdo chce službu jakkoliv využívat, dělal lokální kopii celého logu za celou historii existence systému, poté nastudoval pracovní postupy pracovníků soudů z nepřehledné „dokumentace“ Popis_WS.pdf a na základě těchto znalostí aktualizoval svoji kopii databáze pro každou entitu, která v DB existuje, ačkoliv ho 99,999% z nich nezajímá a nikdy zajímat nebude, ale musí to dělat pro případ, že by náhodou někdy v budoucnu potřeboval s danou entitou pracovat?

Formát přijímaných dat

Další krásou, kterou jsem objevil až s tímto projektem, je vkládání XML do XML. Cituji:

Aby byla webová služba co nejobecnější a přitom odolná proti častým změnám rozhraní, obsahuje samotné volání pouze základní údaje pro identifikaci události, které se akce týká. Samotná přenášená data obsahuje poznámka. Data jsou v poznámce strukturována formou XML dokumentu.

Budiž – uznávám, že generovat nové knihovny klienta webové služby při každé změně struktury dat by nebylo příjemné. Jak často a proč se ale má jejich struktura měnit? Je to proto, že webová služba obsahuje data, která vás nezajímají o subjektech, které vás nezajímají. Pokud by Ministerstvo spravedlnosti bylo natolik soudné, aby požadovalo normálně fungující službu, byl by vstupem pro službu nějaký identifikátor a typ subjektu, a vracela by AKTUÁLNÍ data, která se ho týkají. Myslím, že u takové WS by se nutnost změny WSDL omezila na minimum.

Odezva služby

„Služba je koncipovaná jako veřejná a je zdarma.“ Z toho také plyne, že tvůrci předem neví, kdy a kolik požadavků přijde. Ovšem že vrácení rovného tisíce položek ze STATICKÉ databáze, tedy logu, trvala až půl až 4 minuty !!, a to v době, kdy službu ještě zdaleka nevyužívá tolik klientů, to je opravdu velmi zarážející. Už jsem se setkal se systémy s desítkami milionů záznamů, které ovšem reagují řádově v sekundách zhruba na dva požadavky za sekundu, a to se jedná o fulltextové vyhledávání. Na čem potom provozují webovou službu ISIR? Na vyřazených noteboocích?

//Update:// Podle odpovědi tvůrců byly prodlevy způsobeny něčím jiným než nedostatečným hardware. Nyní se zdá, že služba již pravidelně odpoví do několika sekund.

Souhrn

Takže, když shrnu svoje výtky vůči IRIS WS:

  • WSDL (pravděpodobně) neodpovídá normě, ale to mi momentálně vadí asi nejméně.
  • Názvy portů ve WSDL vůbec nevypovídají o účelu
  • Služba je nepochopitelně pomalá
  • A co mi vadí nejvíc – celý princip získávání dat z DB. Databáze obvykle slouží k získávání aktuálního stavu entity podle nějakého identifikátoru, ne ke zpřístupnění historie operací se všemi existujícími entitami.

Odpověď tvůrců webové služby

Na mé námitky vůči kvalitě zpracování služby odpověděla firma CCA Group takto:

Vámi připomínkovaný způsob fungování WS ISIR byl navržen, odsouhlasen a zpracován na základě požadavků MSp. Víme, že některé subjekty by radši používaly sofistikovanější WS s vlastnostmi, které popisujete. Dle sdělení zadavatele – MSp není takto koncipovaná WS ve shodě s jejich záměry dalšího rozvoje aplikace ISIR.

Jinými slovy, ministerstvo (rozumějte – nejspíše laici, kteří ani netuší, co je webová služba) je spokojeno se stavem, kdy se data vůbec nějak mohou k někomu dostat, čímž splnilo požadavek zákona, myje si ruce a víc jej nezajímá.

Překladiště údajů z webové služby insolvenčního rejstříku

Jak jsem uváděl výše, většina lidí si pod pojmem „Webová služba Insolvenční rejstřík“, která má zveřejňovat údaje o insolvenčních řízeních, představí něco trochu inteligentnějšího než stahování kopie databáze ISIR. Proto jsem se rozhodl takovouto funkčnost zpřístupnit.

Na adrese http://isir.dynawest.cz/ tedy bude klient Webové služby Insolvenční rejtřík ISIR. Spuštění plánuji na konci července 2008.

... read more →
2018-07-31

Začátky se Spring AOP – návod

Začátky se Spring AOP – návod

Právě jsem úspěšně rozběhal Spring AOP ve stand-alone (newebové) aplikaci, takže si opět postup a poznatky zapíšu na web. Jako vždy si vyhrazuju právo mýlit se, ale snad jsem vše pochopil správně.

Co je AOP

AOP je zkratka za Aspect Oriented Programming neboli „aspektově orientované programování“.

AOP zajišťuje ulehčení práce programátora v případech, kdy se při volání metod různých tříd volá vždy stejný nebo podobný kód – typickým příkladem je otevírání a uzavírání transakce, kontrola práv k provedení operace (autorizace), trasování běhu aplikace atd.

Co je aspekt

Aspekt je (společná) vlastnost či spíše potřeba některých metod – například právě potřeba otevřít a uzavřít transakci nebo ověřit práva.

Co je Spring AOP

Spring AOP je jedna z implementací AOP. Dále existují ještě AOP frameworky JBoss AOP (s tím se dostanu brzy do potyčky :-), AspectJ (ten to všechno začal a Spring AOP jej využívá) a AspectWerkz (nic moc).

Spring jde svojí obvyklou cestou co nejjednodušší konfigurace a co nejstručnějšího zápisu. Můžete využít buď @Anotace ve stylu AspectJ (@Aspect, @Before, @Pointcut atd.), nebo konfiguraci v XML souboru. Ukázka XML následuje.

Konfigurace Spring AOP v XML

Dříve (před verzí Spring 2.0) se konfigurace AOP prováděla poněkud neohrabaně nastavováním Beans (což popisuji v návodu Úplné začátky se Spring framework).

V současnosti se AOP nastavuje pomocí elementů z namespace <aop:*>. Tento jmenný prostor je třeba v XML souboru zmínit, proto se místo DTD použije definice přes xmlns:aop.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:aop="http://www.springframework.org/schema/aop"
     xsi:schemaLocation="
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
>

  <!-- Před spuštěním metod tříd z balíku "aoptest" zavoláme metodu test() z beany s ID aopTestAdviceBean. -->
  <aop:config>
    <aop:pointcut id="aopTestPointcut" expression="execution(* aoptest.*.*(..))"/>
    <aop:aspect ref="aopTestAdviceBean">
      <aop:before pointcut-ref="aopTestPointcut" method="test"/>
    </aop:aspect>
  </aop:config>

  <!-- Metoda této beany (objektu) se bude volat podle výše uvedeného pravidla. -->
  <bean id="aopTestAdviceBean" class="aoptest.AopTestAdviceBean">
    <property name="foo" value="foo value"/>
  </bean>

  <!-- Automatické volání metod funguje jen pro objekty vytvořené Springem. -->
  <bean id="nejakaTrida" class="aoptest.NejakaTrida">
    <property name="bar" value="bar value"/>
  </bean>


</beans>

K tomu ještě pár poznámek:

  • Automatické volání metod funguje jen pro objekty vytvořené Springem. Následující tedy nebude fungovat:
aoptest.NejakaTrida objekt = new aoptest.NejakaTrida();
objekt.metoda();  // <--- ZDE AOP NEZAFUNGUJE!
  • Aby Spring zpracovával jiné jmenné prostory nez výchozí, je třeba místo XMLBeanFactory použít „full verzi“, tedy třídu ApplicationContext.

Celý kód pro rozjetí AOP tedy vypadá takto:

ApplicationContext ac = new ClassPathXmlApplicationContext("properties/SpringBeans.xml");
aoptest.NejakaTrida objekt = (aoptest.NejakaTrida) new aoptest.NejakaTrida();
objekt.metoda();  // <--- zde AOP zavolá napřed metodu aoptest.AopTestAdviceBean::test().

A k tomu samozřejmě definice příslušných tříd, myslím, že nemá cenu je zde vypisovat, jsou zcela obyčejné.

Potřebné knihovny

Použil jsem:

  • Spring 2.5.5
  • AspectJ 1.6.1

Konkrétně tyto .JAR soubory:

  • Z distribuce Spring:
    • dist/spring.jar
    • dist/modules/spring-aop.jar
    • dist/weaving/spring-aspects.jar
    • dist/weaving/spring-agent.jar
    • lib/jakarta-commons/commons-logging.jar
    • lib/cglib/cglib-nodep-2.1–3.jar
  • Z distribuce AspectJ (stažené .jar je instalátor – spusťte a rozbalí se):
    • lib/aspectjto­ols.jar

Tučně zvýrazněné jsou nutné (rozuměj „bez nich mi to nešlo“). U ostatních nevím – je možné, že některé jsou navíc, ale takto mi to funguje a tak neřeším.

Závěr, literatura, zdroje

Tolik tedy ke Spring AOP. Snad jsem na nic nezapomněl, ale v podstatě je to dost jednoduché.

Cokoliv dalšího nastudujete z velmi obsáhlého referenčního manuálu Springu, zejména oblasti:

Další použité či použitelné zdroje:

... read more →
2018-07-31

JTexy! – Texy! Java Implementation project

JTexy! – Texy! Java Implementation project

I am about to port Texy! to Java.

But that's a long-term plan, therefore this page is here as a placeholder.

Texy! author, David Grudl, created a test suite of several Texy! formatted files, which can be used to validate the implementation.

Available at http://download.texy.info/refs.zip .

Notes…

Oh no – JDK6's regular expressions do not support recursion :(

I am looking for a Java regexp lib with support for recursion, like: <a+(?0)>. See http://www.php.net/…ecursive.php. I need it for this expression:

(?:mUi)^/--++ *+(.*)(?: *(?<= |^)\\.((?:\\([^)\\n]+\\)|\\[[^\\]\\n]+\\]|\\{[^}\\n]+\\}|<>|>|=|<){1,4}?))?$((?:\\n.*+)*)(?:\\n(?0)|\\n\\\\--.*$|\\z)

JDK does not support it, ORO does neither, nor Stevesoft Pat does.

dev.java.net is sooooo slooow…

Gone to Google Code: http://code.google.com/p/jtexy/

What's the relation between ORO and Jakarta Regexp?

ORO developement stalled in 2004? Is Jakarta Regexp a successor? Is Jakarta Regexp PERL compatible? ORO claims so, Regexp does not.

Parsing core: TexyParser.php @ 152

PHP's preg_mat­ch_all

// parse loop
$matches = array();
$priority = 0;
foreach ($this->patterns as $name => $pattern)
{
        preg_match_all(
                $pattern['pattern'],
                $text,
                $ms,
                PREG_OFFSET_CAPTURE | PREG_SET_ORDER
        );

        foreach ($ms as $m) {
                $offset = $m[0][1];
                foreach ($m as $k => $v) $m[$k] = $v[0];
                $matches[] = array($offset, $name, $m, $priority);
        }
        $priority++;
}

PREG_OFFSET_CAPTURE – makes the returned multidimensional array even more multidimensional – stores the string at [0] and the offset at [1] (well, PHP is really that shitty).

PREG_SET_ORDER – the matches are ordered so that sub-group is next to it's parent group or it's sibling (depth-first instead of breadth-first).

|...|U makes all quantifiers ungreedy:

You could also make ALL the quantifiers in a regular expression „ungreedy“ by using the U modifier. http://www.skdevelopment.com/…ressions.php

AAAAaaaaaa!

No Java library supports global ungreediness! :-((
* StackOverflow post:
* Java forums post:
* Java forums archive:
* Ales Novak – ales A netbeans.com
* java.util.regex JavaDoc: http://java.sun.com/…Pattern.html
* java.util.regex tester: http://www.regexplanet.com/…e/index.html

Promising clues:

* OpenJDK should support LAZY
* There's a PHP port to Java: http://www.java2s.com/…java-doc.htm
* I could hack the JDK code: http://hg.openjdk.java.net/…Pattern.java
* http://hg.openjdk.java.net/…Pattern.java
* 2721 private void addFlag(), 2760 private void subFlag()

preg_match_all():

Is this the same as multiple calls to preg_match()?
preg_match() returns the number of times pattern matches. That will be either 0 times (no match) or 1 time because preg_match() will stop searching after the first match. preg_match_all() on the contrary will continue until it reaches the end of subject.

Is there similar in Java, or do I have to iterate?

Need to re-design…

Original design is, despite of author's credits,… not perfect.
* The way modules are registered
* and whole callback system

Questions

RegExp.Patterns.php – slash hell – do the slashes belong to RE or to PHP?

protect() – will I preserve it? Yes.

Is dom4j or jDOM enough for #JTexy? Yet seems so.

modifier.decorate( elmRet ) dosn't need texy reference – it should keep it from it's creation.

Why Texy doesn't keep $handler, $pattern, $name together in a classfunction registerLinePattern($handler, $pattern, $name)

WTF, list(, $mParam, $mMod, $mContent) = $matches; everywhere? Again, why not put it in a class?

$pattern . 'Am', // anchored & multiline → #JTexy: Is it the same as prepended ^ ?

TexyParser.php @ 169: $priority++; – later patterns have higher priority? No, the other way.

What is TexyLineParser.again good for? Never set to true?

Texy Refactoring

Zdravím,

mám pár návrhů na mírný refactoring parseru:

1) Zavést třídu pro patterny; handlery uložit k patternům rovnou jako referenci funkce.

public class RegexpInfo {

        public String name;
        public String perlRegexp;
        public String regexp;
        public String flags;
        public String mode;
        public String htmlElement;

        // Handler of this pattern - a "callback".
        public PatternHandler handler;

        public enum Type { LINE, BLOCK };
        public Type type = Type.LINE;
}

2) V parseru: Výsledky preg_match_all() převést na pole objektů, místo pole polí (… polí polí, jak je zvykem v PHP).

class ParserMatchInfo implements Comparable<ParserMatchInfo>
{
        public final RegexpInfo pattern;
        public final List<MatchWithOffset> groups;
        public final int offset;
        public final int priority;
}

Taková třída je taky přirozeným místem pro funkci cmp().

3) Při vytváření objektu s informacemi o matchnutí rovnou uložit referenci na použitý patten, místo jeho jména.
Zaprvé se tak ušetří jeden lookup, zadruhé to zpřehlední kód.

4) V názvech proměnných zavést pojem group pro skupiny matchnutí reg. výrazu. „Match“ ponechat pro celý match.
Aneb:

preg_match_all( $pattern['pattern'],  $text,  $ms,  PREG_SET_ORDER );
$matches[0];    // --> First match
$matches[0][0]; // --> Group - matched text of the whole first match.
$matches[0][1]; // --> First sub-group of the first match.

Tak nebude nutné pojmenovávat proměnné $ms, $matches, $m, $mMatches, …

**5) Přesunout TexyParagraphMo­dule.process() do TexyBlockParser

**6) Zavést třídu ParserEvent, dědit od ní a tyto používat pro model událostí.


Jsou to všechno interní věci, takže to nikoho moc netrápí, ale když už je to ten opensource a někdo by to mohl chtít časem hackovat… ;-)

Ondra

PS: Kódy jsou v Javě; nápady na refaktorizaci totiž pocházejí ze vznikajícího JTexy.

Sun feature request

Synopsis

Regex: Support for UNGREEDY or (?U) flag

Description

Perl regular expressions have „/…/U“ and „(?U)“. Many of text processing tools based on regexp use this extensively (e.g. Texy).

These tools are done in a way that makes quite hard to add the ungreedy (reluctant) mode, using .*?, to all closures – they have many regular expressions (few dozens to hundreds), and many of them change with each release.

Justification

  1. This would make porting such text tools easier to port to Java, and thus would contribute to spread
  2. None of other Java regexp libs (including ORO and Jakarta Regexp) has support for this feature.
  3. I believe it wouldn't be hard to implement since there already is support for in-place reluctant closures. Checking for a flag when processing a closure shouldn't be complicated.

Expected Behavior:

Regex: „.*foo“ with UNGREEDY flag or „(?U).*foo“ String: „AAAfooBBBfoo“

Desired result:
group(1): AAAfoo
group(2): BBBfoo

Actual Behavior:

Current result:
group(1): AAAfooBBBfoo

Source code for an executable test case:

String inputStr = „AAAfooBBBfoo“; String patternStr = „.*foo“;

Pattern pattern = Pattern.compi­le(patternStr); Matcher matcher = pattern.matcher(in­putStr);

… etc.

Workaround

Well, changing all closures to be reluctant. sigh

User Info

ozizka@redhat.com

Java implementace překladače Texy!

Texy je bezesporu jeden z pokladů českého opensource. Je škoda, že je zatím jen pro PHP.

Zdravím,

nechtěl by někdo čirou náhodou implementovat překladač Texy v Javě?

www.texy.info

Mohlo by to být dobré téma projektu / bakalářky… Formální specifikace není, jen podle popisu syntaxe a ukázek použití…

Java komunita by vás jistě oslavovala :-)

Ondra

Autor Texy David Grudl sestavil sadu testovacích souborů, na kterých lze ověřit implementaci překladače. K dispozici na http://download.texy.info/refs.zip

Algou a omegou původní PHP imiplementace jsou PCRE. Knihovna pro Javu, která zvládá PCRE podle Perl 5, je na http://jakarta.apache.org/oro/ .

Ondra Žižka

... read more →
Older posts are available in the archive.
0