Pilven reunalle istumaan JEE serverin kera

Tänään koulutellessa Java EE ohjelmointia tuli vastaan kysymys siitä, mitkä suomalaiset web-hotellit tukevat Java EE softan asennusta ja ajamista. Itselle on tutuksi tulleet lähinnä Google App Engine sekä Amazon pilvipalvelut entuudestaan, mutta suomalaista tarjontaa en juuri tuntenut joten ei kun tutustumaan.

Tarjokkaita löytyi lopulta – pun intended – pilvin pimein. Mutta jostakin syystä käteen jäi itselle Jelastic, pystytin sinne trial hengessä pienen glassfish serverin, mysql kannan, ja noin 10 minuutin uurastuksella perinteiseen tapaan vältellen ohjeiden lukemista pystyssä oli hetken päästä toimiva ympäristö kurssin harjoituksille. Itse harjoitustehtävälle en tehnyt mitään muutoksia, tuuppasin paketoidun JPA:ta ja servlettejä sisältävän .war paketin suoraan Jelastic pilveen, mutta etukäteisvalmisteluna loin toki mysql kantaan uuden scheman, sille sopivat käyttäjätunnarit, kirjauduin glassfish hallintakonsoliin, loin mysql connection poolin, ja sen päälle datasourcen nimeltä jdbc/sample – jota harjoitustehtävä käytti.

Forum war paketti tuupattuna serverille

Yllättävän kivuton ja hauska prosessi. Toki trial serverillä serverien resurssit on kuristettu niin alas että sain sähköpostiin motkotuksia vähistä resursseista ja serverin kriittisestä tilasta. Mutta nehän korjautuvat rahalla, pilven idean mukaan sellaisen viipaleen saa mistä maksaa – ja mitä käytetään.

mysql_admin

 

glassfish_admin

Hauskaa oli havaita, että jopa serverin tiedostoihin pääsi vapaasti käsiksi. Serverin lib kansioon piti tietysti ladata mysql connector/j ajuri.

Näyttää että pilvet alkavat suomessakin olemaan elinvoimaisia. Odotellessa kummoisempia pilvistandardeja Java-maailmaan Java EE tekniikat toimivat jo hyvin ja sovellukset siirtyvät paikalliselta testipalvelimelta pilveen – toki oma oppimiskäyränsä on resursoinnissa ja hallinnassa, sekä vasteaikojen hiomisessa, mutta lupaavaa kumminkin. Taitaa olla takana ajat kun itsekin linux purnuja webin nurkalle pystyttelin oman huoneen nurkkaan :p

accesstoserverfilesandfolders

 

Tervetuloa vain mukaan pilven reunalle istuksimaan! 😉

 

Mainokset

ÄLÄ sieppaa sitä poikkeusta! ÄLÄ!

Heh, luin taas artikkelin joka muistutti yhdestä asiasta jota olen alkanut koulutuksissa painottamaan itsekin nähtyäni paljon huonoa koodia jossa on ongelmia. Se liittyy virheiden käsittelyyn.

Java- kielihän jakaa virhetilanteiden aiheuttamat poikkeukset kahteen kategoriaan: checked ja unchecked. Checked poikkeukset ovat niitä joita on pakko käsitellä, ja niitä käytetään osiin kuten tiedostonkäsittely, verkko- ja tietokanta-ohjelmointi, jne. Ja kun ohjelmoija törmää Eclipsessä käännövirheeseen joka muistuttaa lisäämään try-catch lohkon näiden osien ympärille, mitä tapahtuu? Useat klikkaavat pikanappeja jotka luovat geneerisen try-catch lohkon joka tulostaa virheen konsoliin/logiin. Jota ei kukaan ehkä koskaan lue. Ja ei tee mitään muuta. Kuten esim. kerro käyttäjälle virheestä, hälyytä ylläpitoa korjaamaan se, tms. Käsitelty poikkeus ei myöskään keskeytä suoritusta vaan jatkaa virheellisessä tilassa eteenpäin ellei sitten itse kirjoita lisää koodia joka estää sen. Tämä poikii lisää mehukkaita virhetiloja ja vaikeuttaa alkuperäisen ongelman löytämistä.

Tuossa mm. esimerkki pätkästä joka löytyy googlesta haulla jdbc sample code:

try{
  // Tässä riveittäin virheellistä ja surkeasti kirjoitettua
  //  JDBC moskaa joka voi heittää poikkeuksia.
}catch(SQLException se){
      //Handle errors for JDBC
      se.printStackTrace();
   }catch(Exception e){
      //Handle errors for Class.forName
      e.printStackTrace();
   }finally{
      //finally block used to close resources
      try{
         if(stmt!=null)
            stmt.close();
      }catch(SQLException se2){
      }// nothing we can do
      try{
         if(conn!=null)
            conn.close();
      }catch(SQLException se){
         se.printStackTrace();
      }//end finally try
   }//end try

Ennenaikainen poikkeusten käsittely on perisynti. Ja tätä syntiä on harrastettu koodipohjissa siellä sun täällä. Pahin mitä olen nähnyt on poikkeuskäsittely jossa käsittelylohko on jätetty tyhjäksi. Toisin sanoen: Piilota kaikki ongelmat mitä ilmenee. Piilota ne niin syvälle että kukaan ei mitenkään pysty ymmärtämään mikä virheen alunperin aiheutti. Klassinen esimerkki asuntolainavetoisesta kehityksestä (MDD).

try {
  // ota yhteys kantaan, hae tietoja, muodosta tiedoista json-sanoma,
  // ja palauta se kutsujalle
} catch (Exception ex) { }

Jep jep. Tuollaisen näin tuotantojärjestelmässä ja valitettavasti en vain yhtä kertaa. Konsulttina saan usein kutsun katsomaan kun koodit eivät toimi tai projekti ei etene. Valitettavasti se tarkoittaa että näen pääosin surkeaa koodia ja harvoin kaunista, hienoa ja hyvin toimivaa. Se alkaa masentamaan aikaa myöden. 😉

Miten sitten poikkeukset tulee käsitellä? Yksinkertaista, älä käsittele. Älä käsittele. Ja sitten käsittele kun on sen aika. Sen aika on kun voit:

– toipua virheestä automaattisesti

– viestiä käyttäjän aiheuttaman virheen käyttäjälle ja opastaa käyttäjää korjaamaan sen ja pääsemään takaisin tuottavalle polulle

– viestiä odottamattoman virheen käyttäjälle ja tallettaa sen yksityiskohdat logiin, ja hälyttää jonkun korjaamaan virheen

Käsittelyn voi tehdä heti jos pystyt toipumaan virheestä. Jos et pysty toipumaan, virhe kannattaa yleensä kuplittaa käyttöliittymään/palvelurajapintaan asti ja tuoda selkeästi käyttäjän tietoon ja tarvittaessa myös ylläpidon (jos käyttäjä syötti emailiosoitteensa väärin siitä ei ehkä kannata spammata logia – tai ehkä kannattaisi, virhevetoinen ui suunnittelu voisi myös olla kova juttu).

Jos rajapinnoissa näkyvät poikkeukset aiheuttavat sinulle mielipahaa, voit tietysti ottaa poikkeukset kiinni ja kietaista ne uusien poikkeusten sisään ja heittää ne uudelleen, siten että poikkeus kuplii edelleen kunnes se voidaan käsitellä, Tästä ollaan kuitenkin montaa mieltä – se mm. aiheuttaa suorituskykymielessä jonkun verran enemmän rasitusta. Toisaalta, suorituskykyyn kannattaa koskea vasta kun tarpeen, ensisijainen prioriteetti tulee aina olla koodin selkeys ja käytettävyys. Avainkysymys: Haluatko nähdä SQLException tyypin rajapinnoissa? Onko suorituskyky vai arkkitehtuurin puhtaus tärkeämpää?

Mutta nyrkkisääntö siis pelkistetysti tässä: Poikkeus kertoo virheestä. Voit käsitellä poikkeuksen kun pystyt korjaamaan virheen.

Muitakin poikkeussyntejä löytyy. Catch-all lohko eli lohko jossa sieppaat kiinni Throwable tai Exception kantatyypin (eli väität kykeneväsi käsittelemään kaikki poikkeukset) on useimmiten huono idea, koska se piilottaa yksityiskohtia, ja saattaa kätkeä ongelmia. Mutta kaikille säännöille on poikkeuksensa, tätäkin voi käyttää rajoitetusti, esim. kun kaikki spesifiset poikkeukset on jo käsitelty ja ollaan UI kerroksessa tekemässä viimeistä huolittelua. Lopputuotteessa et toki halua asiakkaan näkevän Java nullpointerexception tai sockettimeoutexception viestejä vaan: Järjestelmässä on tilapäinen käyttöhäiriö. Yritä uudelleen hetken päästä tai ota yhteys ylläpitoon osoitteessa blahblah@blahblah.com.

Yllätys, yllätys… Modernit ratkaisut käyttävät yhä vähemmän checked exception tyyliä ja yhä enemmän runtime-exception tyyliä. Esim. EJB 3, Spring, Scala, Groovy, ovat siirtyneet pois mallista jossa poikkeukset on pakko käsitellä. Saa-käsitellä tyyppiset poikkeukset ovat mukavampia koska koodaajat eivät kirjoittele boilerplate koodia vaan poikkeukset käsitellään kun siitä on jotain hyötyä. Joka on juuri kuten sen olisi alunperin pitänytkin olla.

Tässä tämän viikon hajatelmat.

Update: Sivusin aihetta Mortgage-Driven Development ja Refuctoring, aiheeseen liittyvä Matt Wynnen maukas videoesitys löytyy täältä:

http://vimeo.com/39660655

 

Java EE 7 on valmis

Jep, speksi Java Enterprise Edition versiolle 7, toisella nimellä JSR-342 tuli uunista ulos ja vielä hyvissä ajoin ennen tämän vuoden JavaOne seminaaria. Sovelluspalvelimista esim. JBOSS (Wildfly 😉 ja Glassfish tukevat jo suurinta osaa piirteistä, ja arvatenkin aika rivakasti kaikkia. IBM Websphere pakkaa tulemaan mukaan parin vuoden päästä eli isoilla firmoilla on hetki aikaa hengähtää ja tarkastella tulevaa. Mitä alusta sitten merkitsee kehittäjälle tai arkkitehdille?

IMG_3013

No tästähän piti tulla se suuri pilvipalveluiden standardi, mutta toisin kävi. Maku tässä editiossa on vähän kuin aikanaan EE 6. Kun katselin sitä ensi kertoja tuntui että kyseessä on vain pikkupäivityksiä ja bugifiksauksia. Mutta pienet nerokkaat parannukset ynnäävät aika nopeasti. Myönnettäköön että EE 6 sai aikaan kauhean sotkun CDI:n kanssa mutta monta muuta asiaa meni siellä hyvin ja tuo CDI kuviokin tulee korjautumaan, tässä versiossa jo vähän matkaa. Eli Java EE 7 on enimmäkseen pieniä päivityksiä. Muutama päivitys meni major versioon:

JMS 2.0 on erittäin maukasta tavaraa sanomapalveluiden kanssa paljon pyöriville. Parannuksia, yksinkertaistusta jota todella on kaivattu.

JAX-RS 2.0 tarjoaa RESTful palveluita tekevälle ennen muuta viimeinkin standardoidun ja toimivan asiakaspään rajapinnan, tätä on myöskin kaivattu kovasti. Kylkiäisenä standardirajapinnat Web Socket ja JSON teknologioille, jotka ovat niinikään nykyaikaa.

Aivan uutuutena on myös Batch API, ja Concurrency Utilities API. Eräajoja ja rinnakkaisuutta järeissä servereissä standardien mukaisesti. Need I say more.. 😉

Mutta todelliset makupalat löytyvät vakaiden paljon käytössä olevien teknologioiden päivityksistä. Itse odotan innolla etenkin JSF 2.2 versiota, jonka tulevista ominaisuuksista olenkin jo bloggaillut. Parempaa HTML 5 tukea, page flow malli Springistä lainattuna, helpompia custom komponentteja, ja tietysti EL 3.0 jossa mm. tuki Lambdoille. Hyvä huomata että EE 6 määritteli JSF 2.0 version osaksi, eli EE 7 hyppää 2.1 yli suoraan 2.2 versioon, kaikenlaista maukasta siis tulossa.

Pienempiä päivityksiä ovat EJB 3.2, Servlet 3.1, JPA 2.1, CDI 1.1, Bean Validation 1.1, sekä JASPIC 1.1. Hyvin toimivia osia on vaikeaa enää parantaa ja sen huomaa versionumeroiden lähes huomaamattomista nytkähdyksistä. Asynkronisia kutsuja ja seuraavan version pilvistandardin alkuvalmistelua luvassa. CDI:n korjauksena on lähinnä valmistautua 1) poistamaan päällekkäisyydet 2) laajentamaan mahdollisuuksia ja 3) avaamaan sen käyttö kaikkialle Javaan. CDI on nykyisellään vielä sotku mutta siinä on kasvupotentiaalia, ja väittäisin että 3 vuotta tästä eteenpäin se on Java EE standardin kaikkein tärkein osa. (Nauretaan sitten yhdessä tällekin ennustukselle vuonna 2016).

Ja tietysti, nyt pistettiin valinnaisiksi jo aiemmin pruning listalla olleet muinaisteknologiat kuten Entity Beanit ja JAX-RPC. Tarkoittaa että sovelluspalvelimet todennäköisesti lakaisevat näihin liittyvät tukiosat vähin äänin pois, IBM maailmaa lukuunottamatta. Harmin paikka että viime metreillä standardi cache-välimuistiratkaisuille sai kirvestä, saamme jäädä odottelemaan vielä sitä. Odotellessa kannattaa käyttää ei-standardeja cache ratkaisuja, niillä saa suorituskykyä.

Eli tässä pikapäivitys. Olen menossa JavaOne seminaariin kuuntelemaan miten näitä tosiasiassa hyödynnetään, joten lisää mehukkuutta luvassa. Ja nämä tietysti päivittyvät pikkuhiljaa kaikkiin asianmukaisiin koulutuksiimme. Kiirettä en silti uskoisi olevan, tämä päivitys on aikaa rauhassa valutella paikalleen ja tuo kaikenlaista mukavaa mutta harvalle mitään kriittisen välttämätöntä juuri nyt. Se kuitenkin ankkuroi taas vahvemmin standardipaletin paikkaa yritysarkkitehtuureissa. Näillä saa aikaan tulosta, taas entistä enemmän entistä vähemmällä vaivalla.

Saa nähdä miten käy Java SE 8 version Lambdoineen kaikkineen. Ehtiikö syksyksi? Toivon mukaan, mutta Lambdoista ei tällä kertaa tingitä, eli julkaistaan jahka valmis niiden osalta. Ja onhan JodaTime myös kiva kirjasto 😉

Linkkejä:

Tieturin Java-kurssit (erityisesti suosittelen 5pv Java EE ohjelmointikoulutusta)

Java EE 7 standardi