2014. április 3., csütörtök

MongoDB

Régóta keresem a kapcsolatot a NoSQL adatbázisokkal. Ezek közül az egyik legelterjedtebb a MongoDB, a hírekben is erről hallani a legtöbbet. Rengeteg energiát fordítanak a népszerűsítésére, remek dokumentációja van, sok videót lehet találni, konferenciákat szerveznek, neves előadókat beszéltetnek különböző felhasználási területekről, sikersztorikról. Ennek a stratégiának a része a MongoDB University is, ahol különböző online tanfolyamokon lehet részt venni. A dolog szépsége, hogy a tanfolyamok teljesen ingyenesek, de ennek ellenére rendkívül igényesen ki vannak dolgozva. Van kurzus Java, Python és Node.JS fejlesztőknek, de van egy külön DBA-knak tartott tanfolyam is. Mivel már régóta második nyelvként a Python-t használom, a M101P: MongoDB for Developers tanfolyamot végeztem el, melynek során a programozási példák Pythonban voltak, és ezen a nyelven kellett megírni a gyakorlati feladatokat is. Külön meglepetés volt, hogy kaptunk egy Pycharm 90 napos licencet is, mely a JetBrains IDE-je, nem kevésbé kitűnő szoftver, mint az IDEA, melyről csak szuperlatívuszokban tudok beszélni.

Maga a tanfolyam egy 7 hetes képzés volt, hetente új tananyaggal. Az első hét az alapfogalmakat tisztázta, és segített a környezet beüzemelésében. A fejlesztés a Bottle pehelysúlyú webes keretrendszerrel és a Pymongo klienssel történt, sokak bánatára még csak Python 2.7-ben. Külön érdekes volt a Bottle megismerése, mellyel hatékonyan tudunk egyszerű webes alkalmazásokat összedobni. Az első héten elmagyarázták a JSON rejtelmeit is, hiszen a MongoDB natívan JSON dokumentumokat kezel, de valójában minden JSON-ben van, pl. egy explain plan, vagy egy belső statisztika is JSON-ben jön vissza. A konzolja maga egy JavaScript interpreter, nagyon tetszett, hogy pl. a következő utasítással lehet gyorsan teszt adatokat generálni.

for (var i = 1; i <= 25; i++) db.testData.insert( { x : i } )

Majd egy utasítással lekérdezzük a generált adatokat.

db.testData.find()

A második hét szólt a CRUD műveletekről, a harmadik a séma tervezésről. A következő három hét volt az izgalmasabb, amikor is először a teljesítményről volt szó, azaz az indexek használatáról, majd az aggregation frameworkről, mellyel, mint a neve is mutatja komplex lekérdezéseket tudunk futtatni. Eztán következett a replikáció és a sharding. Az utolsó hét laza volt, ekkor két esettanulmány hangzott el.

Egy hét úgy telt, hogy hét elején elérhetővé váltak a videók, kb. hetente 1-2,5 órányi terjedelemben, de fel voltak vágva apró darabokra, jellemzően 3-6 perces részekre. Mindegyik videó után volt egy egyszerű kis teszt, mely ellenőrizte, hogy megértetted-e az elhangzottakat. Majd mindegyik hét végén volt házi feladat, 3 - 5 feladattal, melyek általában gyakorlati példák voltak. Vagy programot kellett írni, vagy egy bonyolultabb lekérdezést. Van, hogy adták az adatbázis tartalmat, melyet be kellett tölteni. Volt egy példa alkalmazás, egy blog motor, melynek a perzisztens rétegét kellett megírni, bár jellemzően eléggé ki volt preparálva, csak egy-két sort kellett bele írni. A feladat ellenőrzése úgy történt, hogy vagy az eredményt kellett beírni, vagy tesztkérdések közül kiválasztani, vagy lefuttatni egy programot, melynek eredményét kellett elküldeni. (Pl. webes klienst szimulálva teszt eseteket futtatott, és ha sikeres volt, akkor adott egy számot, amit el kellett küldeni.) A megoldásokat a következő hét elejéig kellett beküldeni.

A hetedik héten kellett megoldani a vizsgafeladatokat, szám szerint tízet. Ebben volt teszt és gyakorlati példa is. Volt egyszerűbb, de volt olyan is, melyen sokat kellett gondolkozni, és a videókat is visszanézni, hogy biztos legyél a dolgodban. Az volt az érdekessége, hogy itt nem kaptál visszajelzést, hogy jó-e a válasz.

A végén az értékelés úgy történt, hogy a legrosszabb hetet kivéve fogták a heti házi feladatok, és a vizsga átlagát, és ha 60% felett voltál, még egy bizonyítványt is kaptál (PDF-ben, egyedi azonosítóval, mely ellenőrizhető).

A tanfolyam alatt végig működött egy fórum és egy wiki, a videók még mindig elérhetőek.

Be kell vallanom, nagyon tetszett ez a fajta tanulási mód. Hetente kb. 5-6 órát kellett vele foglalkoznom. Bár hiszek abban, hogyha valamit alaposan meg kell tanulni, akkor könyvből és netes forrásokból hatékonyabb, itt viszont az volt a cél, hogy egy benyomást, és áttekintő képet kapjak. Erre tökéletes volt, hiszen folyamatosan de nem túl nagy adagban jött az új anyag, és érdekes feladatok is voltak. Én még annyival megtoldottam, hogy egy nagyon egyszerű kis hobbi projektet (Badges) implementáltam vele, így még jobban rögzültek az ismeretek.

A MongoDB-ről is alapban jó tapasztalataim voltak, bár a 32-bites rendszeren megszenvedtem vele. Az a tooling, ami mögötte van, nagyon korszerű, és nagyon kézre áll, rendkívül gyorsan lehet eredményeket elérni, egy agilis projektben, egy startup mögé ideális választás. Persze hallani rossz tapasztalatokat is, hogy baj van a performanciával, és a séma nélküliség, a redundancia is okozhat gondot, így nagyon oda kell figyelni, hogy mikor használjuk. Viszont nagyon szeretnék egy olyan SQL adatbázist, ami ennyire kézre áll, gyors, skálázható, és az, hogy a konzolja egy imperatív programozási nyelv interpreterje, és nem csak egy SQL értelmező, rettentő sokat hozzáad az élményhez.

Érdekességként annyit, hogy 6 312-an kezdték, és 1 141 hallgató végezte el sikeresen. Javaslom mindenkinek, hogy akit érdekel, próbálja meg. Azonban ha azonnal indul a projekt, melyben Mongo-t kell használni, akkor inkább valami intenzívebb módját javasolom a tanulásnak.

2014. március 16., vasárnap

HOUG 2014

Frissítve: 2014. április 3. - felkerültek a képek

A HOUG ismét megrendezi a Magyarországi Oracle Felhasználók Konferenciáját 2014 március 24 és 26 között Siófokon. Érdekessége, hogy a konferencia nulladik napja egy ingyenes Java konferencia is, melyet a HOUG.j, a HOUG Java Szakosztálya szervez. Akik remek meetupot is hosztolnak DPC-HOUG.j JavaBar néven. Idén én is adok elő 16:00 - 16:30 között "Continuous Delivery: Problémák és megoldások" címmel. Alább az előadásom bevezetőjét olvashatjátok.

A Continuous Delivery bevezetése nagyvállalati Java környezetben fejlesztett, több modulból álló alkalmazás esetén nagy kihívást jelenthet. Gondoljunk csak a branchek használatára, az Ant korlátolt képességeire, a Maven SNAPSHOT és repository kezelésére, a release pluginra, az adatbázis séma verziózására, vagy akár az integrációs teszt esetek sebességére. Előadásomban ezen problémás részeket igyekszem azonosítani, és alternatív megoldási javaslatokat adni. Nincsenek általános igazságok, a Continuous Delivery egy szemléletmód, folyamatos tanulás és fejlődés.

A következő előadásokat hallgathatjátok meg 14:00-tól:

  • JavaEE Application Security - Minden, amit az alkalmazásbiztonságról a fejlesztőknek érdemes tudni. – Schaffer Krisztián, security analyst, Cloudbreaker Company
  • JavaSE 8 újdonságok – Elek Márton, DPC Consulting Kft
  • JavaEE 7 újdonságok – Varga Péter, tanácsadó, DPC Consulting Kft.
  • Az Apache Maven élete és halála – Cservenák Tamás, Sonatype // Nexus fejlesztő
  • Continuous Delivery: Problémák és megoldások – Viczián István, vezető fejlesztő, IP Systems
  • Android és JavaEE: légy REST! – Auth Gábor, senior architect

Jelentkezni itt lehet.

Közben véget ért a konferencia, készültek képek, ide is teszek egyet, amin nagyon magyarázok.

2014. január 22., szerda

A Maven feltámadása

Frissítés: A videó is megtekinthető a YouTube-on, és egy blog poszt is megjelent azóta.

A mai napon Jason van Zyl, a Maven alkotója egy prezentációt tartott arról, hogy milyen tervei vannak a jövővel kapcsolatban, ezt szeretném összefoglalni ebben a posztban.

Jason eddig a Sonatype-nál volt, aminek a nevéhez fűződik a Nexus repository manager alkalmazás, valamint a remek Mavennel foglalkozó, ingyenesen letölthető könyvek. Azonban mostanában főleg a biztonsággal kapcsolatban lehetett róluk hallani, pontosabban a nyílt forráskódú library-k használatának biztonsági kockázatának minimalizálását tűzték ki célul.

Jason fő területe azonban a Maven, és továbbra is ezzel szeretne foglalkozni, így megalapította a Takari céget, mely Maven oktatással, tanácsadással foglalkozik, erősen támaszkodva a nyílt forráskódú közösségre.

Az utóbbi hónapokban több cégnél dolgozott azon, hogy a JVM alapú alkalmazások életciklusa gyorsabb legyen, gyorsabban lehessen szállítani az ügyfélnek. Persze ez több tényezőn múlik, nyilván a Maven közeli dolgokra koncentráltak, a fejlesztés és a build gyorsítására. Több eredményt is sikerült elérni, melyből már van, amit publikáltak, és van amit a közeljövőben szeretnének nyílt forráskódúvá tenni.

Sebességgel kapcsolatos fejlesztések:

  • Inkrementális fordítás
  • További párhuzamos működés bevezetése (aggressive parallelization)
  • Generációk (generations)

Ezek mellett egyéb érdekes dolgokat is csináltak:

  • Projekt leírása más nyelveken (polyglot support)
  • Konzolban futó shell eszköz

Az összes témakör nagyon érdekes, és előremutató, érdemes ezeket bővebben kifejteni. Az biztosan látszik, hogy nem öncélú fejlesztés történik, hanem a fejlesztők leggyakoribb problémáit igyekszik megoldani. Az is látható, hogy még szorosabb lesz a kapcsolat az IDE, a Maven és a repository között. Azonban az újdonságok parancssorból is kihasználhatóak majd.

Az inkrementális fordítás alapvetően az Eclipse beépített inkrementális fordítójára, a JDT-re épül. Már az m2eclipse Maven-t támogató Eclipse plugin is képes egy önálló erőforrást egy önálló MOJO (Maven plugin)-n keresztül hívni. Ez lett API-ként bevezetve, ez elég durva módosítást eredményezett, hiszen, hozzá kellett nyúlni az életciklusokhoz, a fordítóhoz, és a megfelelő pluginekhez. A függőségek feltérképezésével igen bonyolult impact analyzis végezhető, mit kell újragenerálni, újrafordítani. Konfiguráció változásnál pl. érdemes újra elvégezni. De akár el lehet menni addig, hogy milyen teszt eseteket érdemes újrafuttatni.

Párhuzamos fordítás a Maven 3-ban jelent meg, mely feltérképezi a függőségi struktúrát, szinteket alkot, és ezeket a szinteken lévő projekteket buildeli párhuzamosan. Az aggressive parallelization használatával további gyorsulást sikerült elérni. Ennek az az alapja, hogy egy sorba dobálja be azokat a projekteket, melyeknek már elkészült a függősége, és ezeket sorba veszi attól függően, hogy hány szál van, stb. Kiderült, hogy létezik egy critical path mely az a függőségi ág, mely fordítása a legtöbb időt veszi igénybe. Igazából úgy kell ütemezni a többi fordítást, hogy e mellett párhuzamosan egyenletesen elosztva menjen. Így érdemes pl. ezt a critical path hosszát is csökkenteni.

Annak azonban, aki már küzdött azzal, hogy a Mavent Continuous Delivery (CD) környezetben használja, a legérdekesebb újdonság a generációk bevezetése lesz. Ennek használatával ugyanis az artifactok egy számot kapnak. Hatalmas előnye, hogy multi module project artifaktjai is ugyanazt a számot kapják. Ez a szám a verziókezelő revision és branch vonatkozásában egyedi. Ez rengeteg problémát megold. Egyrészt nem kell innentől SNAPSHOT, azzal amúgy is volt olyan baj, hogy a multimodule projektek más számot kaptak, és nem lehetett egymáshoz rendelni őket. Nem kell ezek után használni sokunk ellenségét, a release plugint. Nem kell release-elni, nem kell újra buildelni, nem kell a verziókezelővel játszani, ugyanaz az artifact kerülhet ki.

Ezzel egy időben még azt is kitalálták, hogyan legyen az új artifactok repository-ba juttatása, és onnan terítése még gyorsabb és hatékonyabb. Erre egy delta protocol került kialakításra (JSON alapú). Nevéből adódóan az az alapja, hogy csak a különbség utazik, és tárolva sem lesznek az azonos artifactok, hanem egy operációs rendszerbeli hardlink készül.

A polygot támogatás lehetővé teszi a pom (Project Object Model) más nyelvekben való meghatározását, pl. Ruby, Groovy, Scala, stb. Az említett három nyelv érdekessége, hogy inline lehet plugineket megvalósítani az adott nyelven.

A parancssoros konzol Tesla shell néven szintén nagyon érdekes dolog, rengeteg jó ötlet van benne. Ebből láttunk egy élő demót is. El kell indítani, és folyamatosan fut, így a memóriában marad, ami megtakarítja a JVM állandó indítgatását. Gyakorlatilag az m2eclipse-el közös alapokkal fog rendelkezni, az inkrementális forráskód generálást és fordítást támogatni fogja. Alapból támogatja a GitHub-ot, ha olyan könyvtárba lépünk, ahol git repository van, azonnal jelzi. Egy pufferben tárolja az előző parancs kimenetét, amit a következő parancsban fel tudunk használni. A demóban azt láttuk, hogy lefordított egy projektet, a kimenetét Gist-ként feltette GitHubra, majd megnyitotta böngészőben. Egy parancsból létrehozott egy GitHub issue-t. Parancsokat tartalmaz a pom kezelésére, pl. Java verzió állítás, új függőség felvétele, erőforrások filterelése (ezen parancsok hatására átírta a pom.xml-t). És nem utolsó sorban szép színes!

Az itt ismertetett összes funkciót nyílttá teszik a GitHub-on, és utána kerülhet a Maven-be. A legtöbb újdonsággal az elkövetkezendő két-három hónapban fognak kijönni. A polygot támogatás már letölthető a GitHubról tesla-polyglott néven. Egyelőre elég nagy a disztibúció, mert az összes nyelvhez tartozó library-t tartalmazza, ezen majd javítanak, hogy csak azt töltse le, amire szüksége van. A translate parancsot kiadva lehet a pom.xml-ünket átkonvertálni más nyelvre. Ki is próbáltam gyorsan, egy egyszerű Spring Security-s projekt pom.xml-jét konvertáltam Groovy-ba. A Tesla shellt már egy héten belül megkaphatjuk, még elég kísérleti változatot. (A Tesla névvel még lesznek licensz gondok.)

A fáma alapvetően az Eclipse és m2eclipse-ről szól, de később integrálható a többi IDE-hez is, hiszen az API elérhető lesz azokból is.

Az előadás alapján én nagyon bizakodó vagyok, ugyanis nem apró, szükségtelen funkciók kerültek bele, hanem felismerték a valós igényeket, a valós használati eseteket, elismerték a Maven hibáit (SNAPSHOT-kezelés), és nem féltek hozzányúlni az alapjaihoz, hogy kijavítsák.

2014. január 20., hétfő

Java és az XML

Felhasznált technológiák: Java 7, JUnit 4.11, XmlUnit 1.5, Hamcrest 1.3, xml-matchers 1.0-RC1, Maven 3.0.3

Van pár régebbi anyagom, melyet szeretnék publikálni, mielőtt új témákba kezdenék bele. Ebből egyik a Java XML kezeléséről szól, ami ugyan nem a legforróbb terület manapság, azonban mégsem árthat egy kis összefoglaló.

Ehhez poszthoz is található egy projekt a GitHub-on, melyben rengeteg példa van.

Maga a Java SE is meglehetősen komplex XML támogatást tartalmaz, méghozzá a The Java™ API For XML Processing (JAXP), The Java Architecture For XML Binding (JAXB) és The Java API for XML Web Services (JAX-WS) specifikációk formájában. Az JAXP egyszerű alap XML feldolgozást támogat, ide tartozik pl. a SAX, DOM, validáció, XPath, transzformáció, stb. A JAXB egy binding megoldás, mellyel Java objektumokat tudunk XML dokumentumohoz rendelni. És végül a JAX-WS, mellyel webszolgáltatásokat tudunk hívni, és implementálni.

Természetesen a JAXP maga is egy specifikáció, JSR-206. Itt az is látható, hogy melyik Java verzióban ennek melyik verziója szerepel:

  • JAXP 1.6: Java Platform, Standard Edition 8
  • JAXP 1.5: Java Platform, Standard Edition 7u40
  • JAXP 1.4.5: Java Platform, Standard Edition 7
  • JAXP 1.4: Java Platform, Standard Edition 6
  • JAXP 1.3: Java Platform, Standard Edition 5

Az 1.4-es újdonsága a Streaming API for XML (StAX), míg az 1.5 bizonyos biztonsági funkciókkal egészítette ki az előző verziót. A JAXP 1.5 2013 augusztus 30-án jött ki, és a következő szabványokat támogatja:

  • SAX 2.0.2
  • StAX 1.2, JSR 173
  • XML 1.0, XML 1.1
  • XInclude 1.0
  • DOM Level 3 Core, DOM Level 3 Load and Save
  • W3C XML Schema 1.0
  • XSLT 1.0
  • XPath 1.0

A JAXP-hez is tartozik referencia implementáció, mely frappánsan a JAXP reference implementation nevet kapta. Alapvetően két Apache-s projekttől forkolt el, az egyikt az XML parse-olást végző Xerces2, a másik az XML transzformációt végző Xalan-Java.

Gyakorlatilag annyi történt, hogy a csomag neve elé még betették a com.sun.org előtagot. Bármikor megtudhatjuk, hogy az aktuális JDK-ban hanyas Xerces és Xalan található:

System.out.println(com.sun.org.apache.xerces.internal.impl.Version
        .getVersion());
System.out.println(com.sun.org.apache.xalan.internal.Version
        .getVersion());

Ez nekem a JDK 1.7.0_51 esetén a következőt írja ki:

Xerces-J 2.7.1
Xalan Java 2.7.0

A cikk írásának pillanatában mindkettőből van frissebb verzió, a Xerces-ből 2.11.0, a Xalan-ból a 2.7.1.

Mivel a JAXP csak egy API, könnyen lehet az implementációt is cserélni alatta. Ennek mikéntje a Java API DocumentBuilderFactory osztályánál van leírva.

Ha nem tudjuk, hogy éppen melyik verziót használjuk (mert pl. a classpath-on szerepel egy más implementáció, ami alkalmazásszerverek használata esetén is gyakori), akkor a következőképpen állapíthatjuk meg azt:

System.out.println(getJaxpImplementationInfo("DocumentBuilderFactory", 
        DocumentBuilderFactory.newInstance().getClass()));
System.out.println(getJaxpImplementationInfo("XPathFactory", 
        XPathFactory.newInstance().getClass()));
System.out.println(getJaxpImplementationInfo("TransformerFactory", 
        TransformerFactory.newInstance().getClass()));
System.out.println(getJaxpImplementationInfo("SAXParserFactory",   
        SAXParserFactory.newInstance().getClass()));

Ez amúgy a példaprojektben is kijött, ugyanis az xml-matchers berántotta a Xerces újabb, 2.8.0 verzióját, ami az egyik XML-t más formátumban írta ki (az mvn dependency:tree paranccsal ellenőrizhető).

A JAXP-hez remek tutorial is található az Oracle oldalán.

A JAXP-ben három parser található. A Simple API for XML (SAX), Document Object Model (DOM) és a Streaming API for XML (StAX). A SAX (mely egy de facto szabvány) egy push parser, a DOM (mely egy W3C szabvány) memóriában felépíti a teljes fát és a StAX pedig egy pull parser, és önmagán belül is még két lehetőséget tartalmaz parse-olásra. Mindegyikre található példa a példa alkalmazásban, és a StAX-ról régebben egy posztot is írtam.

A TransformerFactory és Transformer osztályok használatával lehet XML transzformációkat végezni.

XML séma alapján validálni a Validator osztállyal lehetséges, a Schema betöltése SchemaFactory-val történik. DTD alapján nem tud validálni, ha mégis ilyent szeretnénk, akkor a parsernél kell a validációt beállítani.

A JAXP XPath kiértékelési lehetőségeit a XPathFactory osztályon és XPath interfészen keresztül lehet kihasználni.

A JAXP minden része fel van szerelve névterek kezelésére is.

Az XML funkciók unit tesztelésére több könyvtár is rendelkezésünkre áll (mindegyikre található példa a példa projektben). Az XMLUnit alkalmas XML összehasonlításra (nem szöveg összehasonlítás), XPath kifejezések futtatására, validációra és transzformációk ellenőrzésére. A Hamcrest is tartalmaz egy HasXPath osztályt, azonban ha komolyabb dolgokra van szükségünk, javasolt az xml-matchers használata, ami szintén Hamcrest matchereket tartalmaz.

Az XML kezeléshez tartozó következő API a JAXB, melyről már írtam a JAXB és JAXB trükkök cikkben.

A JAX-WS-ről írtam a JAX-WS mélyvíz posztban, tesztelésükről a Webszolgáltatások integrációs tesztelése soapUI és JUnit használatával posztban. Könyvről a SOA Using Java Web Services posztban, és vizsgáról a Oracle Certified Expert, Java EE 6 Web Services Developer posztban.

Az XML-lel kapcsolatban még érdemes megjegyezni, hogy a properties állományokat is lehet XML formában tárolni, ekkor a Properties osztály loadFromXML metódusát kell meghívni.

Nagyon egyszerű esetben, amennyiben JavaBean-eket akarunk kiírni, majd visszaolvasni, és nem számít az XML felépítése, használhatjuk a Java XMLEncoder és XMLDecoder osztályát.

A javax.xml.soap csomag felelős a SOAP üzenetek alacsony szintű feldolgozásáért.

A két legelterjedtebb nyílt forráskódú XML feldolgozást végző XML library a JDOM és dom4j. Alternatív binding könyvtár a Castor. Alternatív JAXB implementáció az EclipseLink MOXy.

A témával kapcsolatban két könyvet ajánlok. Az egyik a Brett McLaughlin, Justin Edelson: Java and XML, a másik a
Ajay Vohra: Pro XML Development with Java Technology Paperback.

2014. január 6., hétfő

Források

A hírek jelenleg két forrásból esnek be hozzám. Az egyik a Twitter, a másik a Feedly, mely egy online RSS olvasó. A Feedlyből kigyűjtöttem, hogy milyen Javaval kapcsolatos portálokat, blogokat olvasok, kidobáltam azokat, melyek tavaly nem frissültek, és most megtaláljátok a Források oldalon. Két kategóriában, ábécé sorrendben szerepelnek a magyar és angol nyelvű tartalmak.

Kérlek titeket, hogy nézzétek meg, hogy miket követtek, és amennyiben nem szerepelnek a fenti listában, szúrjátok be ide a megjegyzések közé.

Az oldalt próbálom rendszeres időközönként frissíteni.

2013. december 27., péntek

PDF elektronikus aláírása és időbélyegzése nyílt forráskódú eszközökkel

Felhasznált technológiák: JDK 7, Maven 3, JUnit 4.11, iText 5.4.5, Apache PDFBox 1.8.3, Bouncy Castle 1.49, 1.50

A PDF formátum egy olyan dokumentumleíró formátum, mely képes az elektronikus aláírást is tárolni. Így nincs szükség külön fájlra mely az aláírást tartalmazza, ezáltal könnyebben kezelhető, és azonnal megnyitható akár olvasásra, akár az elektronikus aláírás ellenőrzésére. A PDF törzsrésze un. objektumokat tartalmaz, melyek különböző típusúak lehetnek, pl. logikai, szám, szöveges, stream, szótár, stb. Az elektronikus aláírást egy un. signature directory tartalmazza, mely része a tanúsítvány, a dokumentum aláírt hash-e, időbélyeg, vagy akár az aláírás valamilyen vizuális megjelenése.

Az aláírás folyamata nagy vonalakban a következőképpen zajlik. Először vesszük a dokumentum hasznos részét, az hash-elésre kerül, pl. SHA-256 algoritmussal, majd ez lesz az aláíró privát kulcsával titkosítva (pl. RSA algoritmussal), és egy hexadecimálisan kódolt PKCS#7 tárolóba rakva. Ezután mehet az időbélyeg. Minden aláíráshoz egy un. handler tartozik, az Adobe.PPKLite handler azt jelenti, hogy az aláírás a PKI infrastruktúrán (publikus/privát kulcs) alapul. Akit ennél részletesebben érdekel, olvassa el az Adobe Digital Signatures in a PDF dokumentumát.

Akit érdekel az elektronikus aláírás témaköre, olvassa el korábbi posztjaimat is, melyeket pár napja frissítettem, hogy naprakész információkat tartalmazzanak: Elektronikus aláírás és alkalmazása Java-ban, kulcskezelés, Minősített elektronikus aláírás.

Valamint érdekelt, hogy a különböző szolgáltatók, mint pl. Elmű, Főgáz, Tigáz, stb. az elektronikusan kiadott számláikat milyen módon írják alá, ennek összesítése megtalálható egy Google Drive Táblázatban. Örülnék, ha ki tudnátok egészíteni más szolgáltatókkal is.

Először az iText jutott eszembe, de annak a 4.x verziója lett kiadva MPL és LGPL licensz alatt, míg az 5.x sorozatért keményen fizetnünk kell, ha zárt forráskódú kereskedelmi alkalmazásban akarjuk használni (AGPL). A 4.x sorozattal azonban két baj is van. Egyrészt az iText megalkotója Bruno Lowagie maga figyelmeztette a felhasználókat, hogy a 4.x sorozat tartalmazhat olyan kódrészleteket, melyek nem szabályosan vannak LGPL licensz alatt. Technikaibb jellegű, hogy csak a 1.38-as Bouncy Castle Java crypto könyvtárra tartalmaz függőséget. Ez azonban az időbélyeg kérésére beépítetten SHA-1 algoritmust használ, ami elavult, minimum SHA-256 hash-t kéne használni. A BC 1.49 verziójában jelent meg, hogy a TSP API SHA-1 hash-en kívül mást is tudjon használni (lsd. release notes). A BC verzióját feljebb emelni nem sikerült, nem visszafele kompatibilis az API. Ezért alternatív megoldás után néztem.

Legelterjedtebb nyílt forráskódú PDF library Java nyelven az Apache PDFBox, melyre már több más projekt is átállt. Közel sem olyan jól dokumentált, mint az iText, melyhez már könyv is van (iText in Action), valamint egy ingyenes whitepaper is letölthető az elektronikus aláírásról. A PDFBox példaprogramjai között is csak elektronikus aláírásra van példa, az időbélyegzésre nincs.

Fontos megjegyezni, hogy minősített elektronikus aláírás esetén magát az aláíró szoftvert is minősíttetni kell, mint az a korábbi posztomban már megemlítettem.

A már említett poszt alapján e-mailben kértem egy NetLock teszt tanúsítványt, valamint a UnlimitedJCEPolicyJDK7.zip tartalmát is elhelyeztem az SDK-ban a megfelelő helyen, enélkül ugyanis a következő kivételt kaptam:

java.io.IOException: exception unwrapping private key 
  - java.security.InvalidKeyException: Illegal key size

A NetLock-tól megkaptam teszteléshez a fokozott (joghatással nem rendelkező) időbélyeg url-jét (http://www.netlock.hu/timestamp.cgi), mely autentikációt nem igényel. Ezúton köszönöm Varga Viktornak, a NetLock Kft. Üzemeltetési és Vevőszolgálati Vezetőjének a cikk megírásához nyújtott segítséget.

Eztán elkészítettem a példaprogramot, mely elérhető a GitHub-on. Itt megtalálható az iText-es megoldás is, mely láthatóan sokkal egyszerűbb, mint a PDFBox-os társa.

Alapvetően mindkét helyen a Bouncy Castle crypto API-t használom. Mindkét esetben ugyanolyan módon kell betölteni a tanúsítványokat, valamint a titkos kulcsot a PKCS#12 tanúsítványtárból, melyben az összes böngészőből ki lehet exportálni ezeket. Az iText teljesen elfedi, hogy mi történik a háttérben, a MakeSignature signDetached metódusát kell hívni, valamint időbélyegzéshez át kell adni egy TSAClient implementációt is.

A PDFBox esetén viszont teljesen kezünkben van a vezérlés. A SignatureInterface sign metódusát kell implementálnunk. Az aláírás Cryptographic Message Syntax (CMS - RFC 5652) tárolóban tárolt a PDF-en belül, mely a PKCS#7 szabványon alapul. A CMS az ASN.1 standard formátumot használja az adatok ábrázolásra. Ennek kezelésére a Bouncy Castle CMSSignedDataGenerator osztálya való. Hash SHA256, titkosítási algoritmus RSA.

Az időbélyegzés kicsit trükkösebb. Ugyanis időbélyegezni az aláírást kell. Tehát csak aláírás után lehetséges, ezért egy lépéssel később történik. (Mint arra a Bouncy Castle levelezési listán rámutatnak. Amúgy nagyon készségesek, kérdésemre is nagyon hamar válaszoltak.) Az aláírást kell hash-elni, majd elküldeni az időbélyegző szolgáltatónak az RFC 3161 szabvány szerint. Ezt a Bouncy Castle tsp csomagja implementálja. Kód a TimeStampClient osztályban. Arra kell nagyon vigyázni, hogy a TimeStampResponse.getTimeStampToken().getEncoded() byte tömb kerüljön a PDF-be. A timestamp formátumát az RFC 5544 írja le, szintén CMS-re építve.

Még egy problémám akadt. Míg így már az Adobe Acrobat Reader már tökéletesen megjeleníti az aláírást és időbélyeget is, a Foxit Reader nem. Ennek oka, hogy a Bouncy Castle BER kódolást használ, azonban a Foxit csak a DER kódolást tudja olvasni. Levél ment a supportra, nagyon segítőkészek. Azonban a Bouncy Castle képes BER-ből DER-be konvertálni, ez szintén megtalálható a példaprogramban. Az időbélyegzés megjelenítése sincs benne a Foxit Reader-ben, erre is kaptam ígéretet.

2013. november 17., vasárnap

Web Component Developer

Ebben a hónapban tettem le a Java EE 6 Web Component Developer Certified Expert Exam (1Z0-899) vizsgát, mely alapvetően a Java EE 6 szabványon belül a Servlet és JSP technológiára koncentrált. Ahhoz képest, hogy napi életben ezt használom a legtöbbet, ez volt az eddigiek közül (Java SE, EJB, JPA, Web Services) a legnehezebb, annak ellenére, hogy 40 órát biztos készültem rá.

A vizsga a szokásos, 140 perc, 57 kérdés, tesztek, ahol előre megmondják a jó válaszok számát. Sikeres vizsgához 64% kell, ami egyáltalán nem tűnik soknak. Az egész körítés nem változott a legutóbbi Web Services vizsgám óta, bővebb információk ott.

A témakörök a következők voltak:

  • Web alkalmazások tervezése, protokollok, technológiák, komponensek: 5 kérdés
  • Controller fejlesztése a navigáció implementálásához: 5 kérdés
  • Biztonság: 7 kérdés
  • Hibák kezelése: 4 kérdés
  • JSP és JSTL: 12 kérdés
  • Model, View és Controller tervezési minta használata: 5 kérdés
  • Alkalmazás és felhasználó állapotának kezelése: 6 kérdés
  • Kérés és válasz kezelése servletekkel: 6 kérdés
  • Tesztelés, csomagolás és telepítés: 7 kérdés

A technológiák közül érintett volt a Servlet, JSP, JSTL, EL. És a Servlet API 3.0-ás verziójára is vonatkoztak kérdések, mint később látni fogjuk.

Felkészüléshez a OCEJWCD Study Companion: Certified Expert Java EE 6 Web Component Developer (Oracle Exam 1Z0-899) könyvet választottam. Másik lehetőség a Head First Servlets and JSP lett volna, ami szintén azt hirdeti magáról, hogy a vizsgára készít fel. Én az előbbit választottam, hiszen hivatalosabbnak tűnt, gondoltam jobban ismeri, hogy a vizsga mire koncentrál, jobban érzi a hangsúlyokat. Valamint a Head First könyvek jók valamilyen technológiát megismerni, de ha az ember már évek óta használja, akkor inkább a referencia jellegű könyv a jobb. Harmadrészt a Head First könyv nem tartalmazza a Servlet 3.0 újdonságait, SWCD exam for J2EE 1.4-re készít fel. Sajnos a könyv választással alapvetően tévedtem, az első könyv ugyanis abszolút nem arra koncentrált, amit a vizsgán kérdeztek. Vizsgára felkészítő könyvhöz képest is túl száraz volt. Tele volt hibákkal, amiknek egy része van a honlapján feltüntetve. Sajnos ezek nagy része az ellenőrző kérdésekben és megoldásokban van. Van egy fejezet, ahova nem tettek be kódrészletet, hanem a netről letöltendő példa alkalmazásokban kellett turkálni. Azért a teszteket érdemes belőle megnézegetni, de semmiképp nem javaslom egyedüli felkészítő anyagnak. Szemben pl. az OCJP könyvvel. Érződik, hogy a Servlet 3.0 részeket is utólag belegányolták, nem integráns része, nem illeszkedik bele a könyv egészébe. A neten található bónusz kérdéssor sem tartalmaz ezzel kapcsolatban kérdéseket.

A kiinduló oldal, ahonnan még érdemes információkat beszerezni, az a JavaRanch OCEJWCD vizsgával kapcsolatos oldala, valamint egy csomó példa kérdéssor található mock examra keresve itt, itt, itt és itt. Sokan javasolják a Enthuware programját is, én erre nem költöttem, de ma már másképp tennék.

És akkor konkrétan a kérdésekről. Több kérdés volt a HTTP metódusokról, külön kérdés a DELETE-ről is. Egy kérdés, hogyha formon nem írsz ki metódust, akkor az defultban POST-e? Ha egy JSP egy JS fájlt szolgál ki, de JSP kiterjesztéssel, headerben be kell-e állítani a content-type-ot? Ismerni kell a Last-Modified headert.

Nagyon fontos a Dispatcher include és forward ismerete, az include direktíva és az import jsp tag, és az ezek közötti különbségek, valamint mikor mit lehet csinálni, mikor van commit, mikor van IllegalStateException. Ismerni kell mindegyik paraméterezését, mert hát nyilván eltérnek. Ismerni kell az url rewrite-ot is.

Volt kérdés a role-link deployment descriptor elemről. A security annotációk szintakszisát fejből kell ismerni.

Számomra a legérdekesebb, és legkevésbé ismert rész a hibakezelés volt. Pl. ha az adatbázis 5 perccel később indul el, mint az alkalmazás, akkor mit kell csinálni. Servlet init-ben várni rá, vagy hibát dobni? Mi van, ha megbízhatatlan az adatbázis, többször elvesztjük a kapcsolatot, ez hogyan kell kezelni? Erősen kell ismerni, hogy mi a különbség a ServletException és a UnavailableException között. Deployment descriptor-ban milyen exception-öket lehet megadni, Throwable, Error, IOException? Sorrend számít, lehet többet megadni?

Volt jsp documenttel kapcsolatos kérdés is. Mivel én kizárólag scriptless JSP-ket írok, megdöbbentett a nagyon sok useBean és getProperty és setProperty-s kérdés. A legapróbb részletekig tisztában kell lenni velük. Ismerni kell a JSTL tag-ek nevét és paraméterezését. Amin meglepődtem, hogy saját tag-ek írása alap szinten volt. Én legtöbb energiát ebbe öltem, mert ritkán kell ilyen, és nagyon bonyolult a szintakszisa, és nem egyszerű megtanulni, az összes interfésszel, telepítési leíróval. Egy nagyon alap dolgot kérdeztek, ami kitalálható. A kedvencem az volt, hogy a taglib-nek prefixként meg lehet-e adni a java szót, és érzékeny-e a kis és nagybetűre.

Ismerni kell a session metódusokat: getCreationTime, getLastAccessedTime, és hogy ezek miket adnak vissza (long).

EL szinten nagyon ráment a típuskonverzióra, van-e String konkatenáció, és fejből kell tudni a precedenciát. Több kérdésben is rákérdezett, hogy a pont és szögletes zárójel operátort jól tudod-e használni, pl. map-ek, bean-ek esetén.

Kérdés, hogy Servlet 3.0 esetén az injection az init után van vagy előtt? Volt pár listeneres kérdés, pl. a getSession melyik listener eventjében van. Több kérdés is volt a web fragmentekről, különösen az orderingre szerettek rákérdezni. Érdekes kérdés, hogy vajon a web.xml vagy a fragment filtere fut-e előbb? Sok filteres és egy wrapperes kérdés volt. Filterből vajon hány példányt hoz létre a konténer? @Multipart annotáció paramétereit is ismerni kell. Egy asynccontext-es kérdés volt, kitalálható. Design patternnel foglalkozó kérdés nálam nem volt.

Ahhoz képest, hogy ennél a vizsgánál tanultam direkt vizsgára felkészítő könyvből, és a legtöbb anyag erről van fenn a neten, ez volt a legnehezebb vizsga, itt ért a legtöbb meglepetés a kérdésekkel kapcsolatban, hogy olyan dologra kérdezett rá, mely egyik felkészítő anyagban sem volt, és a mock vizsgákban sem.

Végül álljon itt egy letölthető szöveges állomány, mely a vizsgára készülés során összeszedett dolgokat tartalmazza. Aki erre a vizsgára készül, annak hasznos lehet, ha felkészülés gyanánt átfutja.