JavaOne 2013 loppuraportti – executive summary (RasPI, IoT, Lambdas)

Jälleen oli työntäyteinen viikko San Franciscossa – yllättävänä bonuksena aurinkokin pilkisteli hieman. Konferenssi oli Javaa työkseen käyttäville suunnattu – paikalla oli Java kehittäjiä/koodaajia runsain mitoin, mutta samoin myös testaajia, projektinvetäjiä, konsultteja, ylläpitäjiä, ja jonkun verran myös business-puolen ihmisiä. Aurinkoa tuli nähtyä vaikka erityisen lämmintä ei ollutkaan, pääosin kuitenkin aika kului pimeissä konferenssihuoneissa. Yli 20 000 osallistijaa – yli  400 esitystä viikon ajalle jaettuna – valintoja oli tehtävä. Sykettä ja suoranaista innostusta oli taas ilmassa. Wired raportoi Javan renessanssista – tai uudesta tulemisesta. Twitter toteaa miten Java on heille ainoa mahdollinen alusta (Hylättyään Rubyn aikoja sitten Javan hyväksi).

2013-09-22 22.14.05

Ja tähän se yhteenvedon yhteenveto: Uudet versiot Java SE 8 ja Java EE 7 ovat tärkeitä ja merkittäviä päivityksiä. Java alustana elää ja voi vahvasti. Se on siirtynyt entistäkin enemmän avoimen lähdekoodin maailmaan. Jo pitkään hypetetty pilvi on saapunut, se on jo täällä. Se tarjoaa uusia mahdollisuuksia ja Java on nihiin valmis. Nykypäivän ja tulevaisuuden älykkäät päätelaitteet mukaanlukien mobiililaitteet, mutta myös autot ja älykodit kytketään serveripäähän, tyypillisesti HTML5+JavaScript tekniikoin – mutta tilanteen mukaan millä vain. Vuoden 2014 trendejä ovat em ohella Lambdat ja Websocketit, sekä HTML5 ja Javascript. Niitä voivat käyttää jo nyt Glassfish palvelimien käyttäjät (Kuten Tieturi), mutta ensi vuonna myös muilla palvelimilla homma hoituu. Ja aina voi vuokrata pilven päältä viipaleen tilaa itselleen. Lambdat ovat Java-kielen tasolla huomattavasti suurempi muutos kuin esim. Generics aikoinaan.

Yksi piiloteema on myös alustan yhdenmukaistuminen: Java ME 8 + Java SE 8 yhdistyminen lähemmäs toisiaan, jatkuu versiossa 9 toivon mukaan Project Jigsawn kera.  Jatkossa on tarkoitus synkronoida myös SE ja EE julkaisuja enemmän samaan tahtiin. Erittäin mielenkiintoinen huomio taas siitä mitä ei ole: Yhden yhtä Java ME demoa puhelimessa en nähnyt, eli alusta on karkaamassa jo kansoitetusta puhelin ja tablet alustasta (niitä hoidetaan HTML5+Javascript mallilla tai sitten vain natiivikoodauksella ja RESTful web serviceilä) – kohden todellisia sulautettuja järjestelmiä: Kulunhallintaa, kapasiteetin hallintaa, käytön hallintaa, kunnon hallintaa.

Mitä uutta Javasta?

Varsinaiset uutuudet olivat tietysti Javan uudet ja tulevat versiot. Tärkein niistä oli Java EE 7 palvelinstandardi, joka julkaistiin jo viime kesänä ja alkaa nyt valumaan pikkuhiljaa Java-serveriympäristöihin. Toinen tärkeä uutuus on ensi vuonna alkupuolella julkaistava Java SE 8, joka pistää käytännössä kaiken Javan uusiksi – hyvällä tavalla. Vanha Java-koodi tulee toimimaan, kuten aina ennenkin, edelleen ilman muutoksia. Mutta kaikki tulevat rajapinnat tulevat rakentumaan niin vahvasti Java 8 Lambda expression malleihin – ja olemassaoleviakin on jo Java 8 osalta päivitety rajusti – että koodaajilla on edessään suuri osaamisen päivitys. Väittäisin että suurempi kuin Java versiossa 5 aikanaan.

2013-09-25 11.59.55

Rivien välissä oli myös muuta tarinaa trendeistä luettavissa. Näytteilleasettajien puolella oli hurjasti pilvipalveluita tarjolla niille jotka haluavat ja uskaltavat ulkoistaa infransa vuokrattavaksi. Pilvipohjaista kehitysympäristöä, testausympäristöä, entistä helpompaa pilvipohjaista ajoympäristöä sovelluksille, jne. Pilvi on tullut ja on jo osa elämää ja rutiinia. Yhtenä haasteena paikan päällä koodasin CloudFoundry pilveen Spring Tool Suitella tehdyn Spring web-sovelluksen jossa integroin JavaOne tweettejä twitteristä – helppoa kuin heinänteko. Codenvy tarjosi kehitysympäristöä pilveen – jossa voi vuokrata kapasiteetin. Sauce Labs tarjosi testausta pilvessä, web ja mobiilisovelluksille, mahdollisuus testata automatisoidusti yli 150 selain/käyttöjärjestelmäkombinaatiolla.  New Relic tarjoaa edelleenkin ulkoistettua serverin monitorointia pilvessä.

Internet of Things – robottien maihinnousu

Itselleni yllättävä painotus oli Internet of Things – IOT ihan kaikkialla. Konferenssissa esiteltiin Raspberry Pi- tuttavallisemmin RasPi – pohjaisia robotteja, tabletteja, kotiautomaatiota, klustereita, autojen toiminnan etälukua langattomasti, Raspberry Pi esiintyi niin monesti esityksissä että oli pakko ostaa tuliaisiksi itsellekin sellainen – maksaahan yksikkö vain 30 dollaria ja sillä voi sentään ajaa Linuxia ja Javaa! 😉 Tosin omana mielipiteenä on, että mielenkiintoinen sulautettujen yksiköiden suunta on käytetyt matkapuhelimet – pari kolme generaatiota vanha Android on äärimmäisen hyvin ohjelmoitavissa ja niitä saa tyyliin ilmaiseksi kun jaksaa vain kärrätä pois, etenkin käytettynä. Tässäpä olisi business idea: Rakenna klusteroitu supertietokone käytetyistä Android laitteista ja myy sieltä pilvikapasiteettia käyttäjille. Tai tee niistä kodintekniikan keskuksia.

Java embedded-haasteessa joku rakensi sydänmonitorin jossa oli mukana Java, RasPI, sekä Google Glass 😉

Shakinpeluurobotti

Tuotteistettunakin löytyy jo E-Health alusta, joka rakentuu RasPI tai Arduino alustojen päälle, ja mittaa mm. pulssia, hapen määrää veressä, hengitystä, ruumiinlämpöä, EKG:tä, verensokeria, hikoilua, verenpainetta, potilaan asentoa, ja lihaksiston kuntoa – ja lähettää tiedot reaaliajassa analysoitavaksi.

Piiloviesti tämän alla valkeni vasta muutaman esityksen katsottuani: yhteistä IoT esityksille oli vahva Java EE 7 serveri pinnan alla, jossa on tila ja logiikka. Java EE 7 tarjoaa entistäkin helpomman tavan rakennella sovelluksen sydänlogiikka – ja niitä voi viskata pilveen ellei halua omaa serveriä ostaa. Toinen mielenkiintoinen teema oli EE 7 uusi websocket mallin käyttö: Se muuttaa ohjelmoinnin siitä että asiakkaat hakevat aktiivisesti sisältöä sellaiseksi että lukuisat erilaiset asiakasohjelmat vastaanottavat tapahtumia ja sanomia kun serverillä tapahtuu jotain. Näin pystyvät esim. ipad, laptop, ja robotti keskustelemaan sulavasti keskenään. Ideana on että IoT on (mikro- ja muiden) laitteiden pilvi jotka tuottavat sekä Big Dataa että Fast Dataa. Keskellä olevan Java EE 7 serverin rooli on yhdistää, prosessoida ja suodattaa datamääriä. Kyseessä on eräänlainen väylä-ajattelu, vähän eri näkökulmasta.

Hazelcast Lego-Pi cluster

IoT on myös nykyisellään puhdasta villiä länttä. Innovointi on vahvaa, ja se tarkoittaa että tietoturvaa ei yleensä ole juuri ollenkaan. Jo nyt on kertomuksia miten hakkerit ovat murtautuneet auton viihdejärjestelmän kautta sisään ja onnistuneet ohjaamaan pyöriä – tai miten hotellin valonohjaus on otettu haltuun tökkäämällä pistorasiaan oma kontrollimoduuli – tai miten Android puhelimella on hakkeroitu lentokoneen järjestelmiä. Tietoturva on osa-alue joka nousee aina vain tärkeämmäksi jatkossa, koska IoT laitteiden tietoturvahaavoittuvuuksissa voi olla seurauksena loukkaantumisia tai jopa hengen menetyksiä – toisin kuin ennen vanhaan jos joku virus päätti pistää koneen levyasemat tasaiseksi.

Ihmisiä valuu luentosaliin

Eurotech demonstroi myös IoT ajattelua toteuttamalla JavaOne kävijämäärien laskureita luentosaleihin ja auloihin. Uutta oli se että ne ovat langattomia laskureita, kytkettynä Oraclen pilveen ja antavat reaaliaikatietoa siitä miten paljon missäkin on ihmisiä. Näitä on toteutettu mm. wc-tilojen puhdistusaikataulutukseen, bussien kapasiteetinohjaukseen, taksijonojen optimointiin, jne.

Entä akronyymit? Mikä on kuumaa ja mikä kylmää?

Tässä vielä teknisempää trendilistaa. Mielestäni nousussa ovat:

Java EE 7, etenkin EJB 3.2 ja Websocket sekä CDI ihan kaikkialla.

– Netbeans – jopa Gosling kyykytti Eclipseä ja kehui netbeansiä. Se on mainettaan paljon parempi kapistus ja 7.4 versiosta alkaen myös HTML5 + JavaScript ovat saaneet ainutlaatuisen hyvän tuen. Tukee tottakai kaikkea mitä Java EE 7 voi antaa.

Glassfish. No, nopea, kevyt, maksuton serveri. On se kova. Ei niin ettei myös JBOSS olisi. Ei pidä unohtaa myöskään TomEE palvelinta tai Jettyä. Yhä enemmän tehdään joka tapauksessa open sourcella.

HTML5, JavaScript – mahdollistavat sen että varsinaista serveripään web sovelluskehystä ei aina tarvita. Tässä saa olla hieman tarkkana tietoturvan kanssa mutta valmiita kirjastoratkaisuja löytyy kuten Vaadin, Project Avatar, ja mikä hyvänsä javascript kirjasto.

– GPU kiihdytys, eli grafiikkapiirien käyttäminen laskemiseen. Se on jo ennestään kova juttu tietoturvamaailmasta, mutta nyt myös tietokanta ja sovelluspalvelinmaailmassa hyödynnetään – case IBM ja Oracle.

– Tietoturva. No joo, sen pitäisi aina olla nousussa. Lisätään monimuotoisemmat ympäristöt ja EU:sta päin tulevat lainsäädännölliset paineet niin ehkä tähänkin aletaan budjetoimaan enemmän.

Laskussa ovat:

– JavaServer Faces JSF – murheellista sanoa, mutta vaikka JSF on standardi se ei ole ainoa vaihtoehto käyttöliittymiin. Se on edelleen aivan mainio kohtuukokoisille yrityssovelluksille missä projektin kustannustehokkuus on kaiken a ja o ja pitää saada nopeasti hyvää jälkeä aikaan. Mutta IoT maailmassa vaihtoehdot ovat tärkeitä. Niitä voi olla vaikkapa juuri open sourcattu Project Avatar, joka sisältää mm. Node.js tekniikasta päivitetyn JVM version.

Todettakoon kuitenkin että JSF 2.2 on myös aika hieno, sieltä löytyy mm. HTML5 leiskapohjamalli – ei ole siis pakko käyttää jsf tagejä. Sieltä löytyy JSF Flow malli jolla voi määritellä miten sivuilla liikutaan. Sieltä löytyy entistä enemmän mahdollisuuksia tilattomuuteen jos niin haluaa.

Kaupalliset serverit ja kehitysvälineet. Tästä voi olla montaa mieltä – mutta jos katsoo meidänkin asiakaskuntaamme niin yhä harvemmalla on satojentuhansien lisenssillä varustettua serverisoftaa tai tuhansien eurojen lisenssillä varustettua kehitysympäristöä Javan tekemiseen. Toki rahalla saa – sekä Oracle että IBM julkistivat mahtavia parannuksia serverituotteisiinsa joissa teemana on että kytkintä kääntämällä saa lisää vääntöä, tai operaatio voidaan tehostaa 48 kertaa nopeammaksi.

Seuraavien asioiden status ei mielestäni ole nousussa tai laskussa, niitä käytetään kun ne sopivat: JavaFX, RESTful web services, Spring Framework (jos seminaarin luennoitsijoilta kysytään, se on kuitenkin kirjastoraskasta legacymoskaa josta pitäisi pääästä eroon ja siirtyä uuteen kauniiseen Java EE 7 aikaan 😉

Miten päivitetään taidot vuoden 2014 tasoon?

Eli meidän asiakkaillemme koulutusterveisiä: Kannattaa tarkistaa että koodaajilla on modernit Java versiot hallussa – tällä hetkellä Javan uudet piirteet versiosta 5.0 versioon 7.0 – ja pian myös 8.0. Kannattaa myös tarkistaa että Java EE 7 taso ja paletti on hallussa – EJB, CDI ja JPA niistä tärkeimpinä. Ehdottoman tärkeää on tarkistaa että suunnittelijat tietävät missä mennään – Java EE 7 ja Spring Frameworkin uusimpiin versioihin tutustuminen ei ole huono idea.

Jos kaipaa parempia tuotteita sovelluksen seurantaan, niitä olisi tarjolla maailmalla, eikä edes maksa paljoa. Javan ei tarvitse olla musta laatikko. Samoin jos pilvi kiinnostaa, niin ei ole mitään syytä miksi sinne ei voisi mennä vaikka heti. Vaihtoehdot kuten Jelastic, Google App Engine, CloudFoundry, Oracle Public Cloud – ovat valmiina Java EE sovelluksille samantien. Voi myös miettiä onko sovelluskehitysympäristö tai testausympäristö pilvessä jotain mikä voisi kiinnostaa – itseäni kiinnostaa, koska skaalautuvuus ja käyttöönoton vaivattomuus on tällaisessa omaa luokkaansa. Ja voi koodata vaikka Nexus 7 tabletilla seminaariluentoja katsellessaan.. :p

Niin, vuosi 2014 tulee nopeammin kuin voi arvatakaan, osaamisen päivittämistä on jo korkea aika suunnitella. Edelleenkin koulutuksissa käy ilmi että kaikki koodaajaresurssit eivät ole täysin tuttuja Java 5 uusien piirteiden kanssa – ja nyt puhutaan kuitenkin Java versioista 7 ja 8, ja uudet piirteet ovat kaikkialla rajapinnoissa käytössä. Edelleen kuulee myyttejä jotka perustuvat vanhaan J2EE maailmaan: monimutkaisuus ja suorituskyky sekä ORM tekniikoiden uskottavuus. Ei kannata tehdä olettamuksia ellei ole toteuttanut projektia Java EE 7:llä  -se on hauskaa, helppoa ja varsin uskottavaa.

Vanhoilla teknologioilla projektien tekeminen on kuin lähtisi ajelemaan maanteille T-mallin fordilla: Voihan sitä huvikseen tehdä ellei ole erityistä kiirettä.

Täältä niitä koulutuksia löytyy jos tarvetta ilmenee:

http://www.tieturi.fi/java

Ja tuossa Wired artikkeli samasta seminaarista:

http://www.wired.com/wiredenterprise/2013/09/the-second-coming-of-java/all/

Mainokset

JSF 2.2 Faces Flow ja HTML5 friendly layout

Odotellessa tulevaa Java EE 7 sekä Java SE 8 standardia olen seuraillut yksittäisten spesifikaatioiden kehitystä. Yksi mielenkiintoinen päivitys on Java EE 7:n tuleva JavaServer Faces 2.2 versio. Se on näennäisesti taas minor update, eli ei arkkitehtuurin uusintaa kuten aikanaan 2.0 päivitys – mutta pienet päivitykset kasaantuvat aika mielenkiintoisesti.

Mitäpä on odotettavissa JSF 2.2 versiossa? Yksi kiintoisa piirre on Wicket-frameworkin tapainen mahdollisuus käyttää HTML5 pohjaa ja id attribuutteja aiemman tag-mallin sijasta. Tässä esimerkki uudesta JSF 2.2 leiskasta tähän tapaan tehtynä:

< !DOCTYPE html>
< html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:jsf="http://java.sun.com/jsf" xmlns:f="http://java.sun.com/jsf/core">
    < head jsf:id="head">
        < title>Putting it all together < /title>
        < script jsf:target="body" jsf:name="js.js"/>
        < link jsf:name="css.css" rel="stylesheet" type="text/css" />
    < /head>
    < body jsf:id="body">
        < form jsf:id="form" jsf:prependId="false">
            < label jsf:for="name">Name < /label>
            < input jsf:id="name" type="text" jsf:value="#{complex.name}">
                < f:ajax execute="@this" render="progress"/>
            < /input>
            < label jsf:for="tel">Tel < /label>
            < input jsf:id="tel" type="tel" jsf:value="#{complex.tel}">
                < f:ajax execute="@this" render="progress"/>
            < /input>

            < label jsf:for="email">Email < /label>
            < input jsf:id="email" type="email" jsf:value="#{complex.email}">
                < f:ajax execute="@this" render="progress"/>
            < /input>

            < label for="progress">Progress < /label>
            < progress jsf:id="progress" max="3">#{complex.progress} of 3 < /progress>

        < /form>
    < /body>
< /html>

Kiintoisaa? Miksei, onhan se. Toinen itseä kiinnostava tutkaan osunut piirre on JSF Faces Flow. Idea on itselle tuttu Spring Web Flow moduulin puolelta – sensijaan että navigointisäännöt naputellaan sivuihin, määritellään sivuilla liikkuminen ja eri vaihtoehdot erilliseen tiedostoon. Tässä ei ole kuitenkaan kyseessä vain navigointi, vaan page flow voi myös sisältää logiikkaa, virhekäsittelyä, jne. Faces Flow on valittu ns ’Big Ticket Feature’:ksi, eli on merkittävä osa JSF alustaa ja sen ympärille rakentuu paljonkin pientä.

Yksi osa on uusi Scope annotaatio, @FlowScoped, joka määrittää luokan elinkaareksi senhetkisen Flown (kääntäisikö tuon virtaukseksi? Aika kömpelö käännös). Tarkoittaa että scope voi olla yli yhden requestin mutta vähemmän kuin session verran. Tätä voisi vertailla hieman @FlashScoped-laajuuteen, mutta viimekädessä elinkaaren määrittää siis määritelty flow, ei se montako kutsua serverille tehdään.

@FlowScoped ottaa flow id parametrin joka määrittää mihin flow-virtaukseen se kuuluu.

Esimerkki @FlowScoped beanistä:

@Named
@FlowScoped(id = "someFlowName")
public class SomBean {
    public String someReturn() {
        return "/somePage.xhtml";
    }
}

Käytössä on oletuksia mitkä helpottavat elämää: flow oletussivu voidaan luoda luomalla kansio jonka nimi on sama kuin flow id, sekä .xhtml tiedosto jonka nimi on edelleen sama kuin flow id, esim:

/someFlowName/someFlowName.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:j="http://java.sun.com/jsf/flow"
>
    <f:metadata>
        <j:faces-flow-definition>
            <j:faces-flow-return id="someReturnName">
                <j:navigation-case>
                    <j:from-outcome>#{someBean.someReturn}</j:from-outcome>
                </j:navigation-case>
            </j:faces-flow-return>
        </j:faces-flow-definition>
    </f:metadata>

    <!-- Rest of view -->
</html>

Flow-tiedostojen välillä voi navigoida flow-id:n avulla, eli navigaatiojärjestelmä tunnistaa nyt flow id:n. Flow id voi olla sama kuin tiedostonimi, tai se voidaan määrittää j:faces-flow-definition elementin id-attribuutilla jos tiedostonimeä ei haluta käyttää. Navigointi flow-sivulta toiselle tapahtuu tähän tapaan:

 <h:commandLink value="Enter flow" action="someFlowName" />

No niin, tässähän ei ole mitään uutta. Aiemminkin JSF:ssä on voitu navigoida sivulta toiselle sivunimen perusteella. Uutta onkin se, että flow node (virtaussolmu? :p) voi olla muutakin kuin näkymä, view. Se voi olla myös Switch (EL lause joka evaluoi mikä on seuraava node), Return (virtauksen paluuarvo),  Method Call (vapaavalintaisen metodin suoritus ja navigaatio), tai Faces Flow Call (uuden flow-sarjan käynnistys).

Ja tässä vähän mehukkaampi Faces Flow määritys:

 

<f:metadata>
        <j:faces-flow-definition>

            <j:initializer>#{someBean.init}</j:initializer>
            <j:start-node>startNode</j:start-node>

            <j:switch id="startNode">
                <j:navigation-case>
                    <j:if>#{someBean.someCondition}</j:if>
                    <j:from-outcome>fooView</j:from-outcome>
                </j:navigation-case>
            </j:switch>

            <j:view id="barFlow">
                <j:vdl-document>barFlow.xhtml</j:vdl-document>
            </j:view>
            <j:view id="fooView">
                <j:vdl-document>create-customer.xhtml</j:vdl-document>
            </j:view>

            <j:faces-flow-return id="exit">
                <j:navigation-case>
                    <j:from-outcome>/exit</j:from-outcome>
                </j:navigation-case>
            </j:faces-flow-return>
            <j:faces-flow-return id="error">
                <j:navigation-case>
                    <j:from-outcome>/error</j:from-outcome>
                </j:navigation-case>
            </j:faces-flow-return>

            <j:finalizer>#{someBean.finish}</j:finalizer>

        </j:faces-flow-definition>
    </f:metadata>

 

Joten tällaista tänä vuonna. Vuosi 2013 on Javan kannalta jännä vuosi tulevien standardien johdosta. Spring Framework 4 tulee luonnollisesti sisältämään tuen myös EE 7 ja SE 8 piirteille, se on jo työn alla.

 

JSF 2.2 ja kunnon HTML-yhteensopivat templatet

No niin, JavaServer Faces on elänyt aika elinkaaren. Ensimmäisessä versiossaan siinä käytettiin JSP tekniikkaa sivupohjana, ja se mahdollisti hirvitykset kuten:

<h2>Categories</h2>
<ul>
 <% 
 ArrayList<Category> categories = Category.selectAll();
 for (int i = 0; i < categories.size(); i++) {
 %>
 <li>
 <h:form>
 <h:inputHidden binding="#{BookCategories.bookBean.categoryId}" value="<%= categories.get(i).getId() %>" />
 <h:commandLink action="#{BookCategories.filterByCategory}">
 <h:outputText value="<%= categories.get(i).getName() %>" />
 </h:commandLink>
 </h:form>
 </li>
 <% } %>
</ul>

Joka ei lisäksi tietysti edes toimi! Mutta vaikka toimisikin, antaa myös sydänkohtauksen mille hyvänsä HTML editorille (ja Web Developer rassukalle joka yrittää saada sivua näyttämään hyvältä selaimessa)

JSF 2 paransi hieman asiaa ottamalla faceletit käyttöön, mutta edelleen sivuleiska on täynnään kaikenlaista ei-html standardimaista puppua:

    	<h1>JSF 2 dataTable sorting example</h1>
    		<h:dataTable value="#{order.orderList}" var="o"
    			styleClass="order-table"
    			headerClass="order-table-header"
    			rowClasses="order-table-odd-row,order-table-even-row"
    		>

    		<h:column>
    			<f:facet name="header">
    			   <h:commandLink action="#{order.sortByOrderNo}">
    				Order No
    			   </h:commandLink>
    			</f:facet>
    			#{o.orderNo}
    		</h:column>

    		<h:column>
    			<f:facet name="header">
    				Product Name
			</f:facet>
    			#{o.productName}
    		</h:column>

    		<h:column>
    			<f:facet name="header">Price</f:facet>
    			#{o.price}
    		</h:column>

    		<h:column>
    			<f:facet name="header">Quantity</f:facet>
    			#{o.qty}
    		</h:column>

    	    </h:dataTable>

Samaan aikaan muut frameworkit kuten Wicket tekevät puhtaita HTML sivuleiskoja. Nyt JSF 2.2:sen myötä näyttäisi sama piirre olevan tulossa myös Java EE alustan web-standardikehikkoon JSF:ään, tässä maistiainen tulevasta:

 

< !DOCTYPE html>
< html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:jsf="http://java.sun.com/jsf" xmlns:f="http://java.sun.com/jsf/core">
 < head jsf:id="head">
 < title>Putting it all together < /title>
 < script jsf:target="body" jsf:name="js.js"/>
 < link jsf:name="css.css" rel="stylesheet" type="text/css" />
 < /head>
 < body jsf:id="body">
 < form jsf:id="form" jsf:prependId="false">
 < label jsf:for="name">Name < /label>
 < input jsf:id="name" type="text" jsf:value="#{complex.name}">
 < f:ajax execute="@this" render="progress"/>
 < /input>
 < label jsf:for="tel">Tel < /label>
 < input jsf:id="tel" type="tel" jsf:value="#{complex.tel}">
 < f:ajax execute="@this" render="progress"/>
 < /input>
 
 < label jsf:for="email">Email < /label>
 < input jsf:id="email" type="email" jsf:value="#{complex.email}">
 < f:ajax execute="@this" render="progress"/>
 < /input>
 
 < label for="progress">Progress < /label>
 < progress jsf:id="progress" max="3">#{complex.progress} of 3 < /progress>
 
 < /form>
 < /body>
< /html>

 

 

 

Pieni yksityiskohta? Yep, mutta ne ratkaisevat. Itse pidän aina siitä kun asiat menevät yksinkertaisempaan suuntaan:

Java on ollut aina hyvä varuste raskaisiin isoihin yrityssovelluksiin (joskin tästä voidaan käydä uskonsotia, mutta uskottavia referenssejä on riittävästi Javan puolesta 😉 – mutta viime vuosina sillä on voinut näperrellä nopeammin, halvemmin, ketterämmin myös pienempiä start-up juttuja uskottavalla tavalla.

Jos ensimmäisen prototyypin saa käyntiin tunneissa tai minuuteissa viikkojen sijaan, saa aiemmin arvokasta palautetta, ja etenkin ketterissä hankkeissa tämä on elintärkeää.

Java EE 7 kypsymässä

Odotellessa Java SE 8 versiota mullistuksineen, seuraava mielenkiintoinen päivitys – jo tänä vuonna – on tuleva Java EE 7 ”cloud” standardi – eli JSR-342.

Kiintoisia osia tulee olemaan:

– JPA 2.1 ja multitenancy (JSR-338)

– JAX-RS 2.0 ja viimeinkin client API (JSR-339)

– Servlet 3.1 ja websockets, multitenancy, ja PaaS malli (JSR-340)

– EL 3.0 (JSR-341)

– JMS 2.0 ja viimein yksinkertaistettu API (JSR-343)

– JSF 2.2 ja pikkuparannusten ohella HTML 5 tukea lisää (JSR-344)

– EJB 3.2 pääjuttuina PaaS, Multitenancy tuet (JSR-345)

– CDI 1.1 (JSR-346)

– Bean Validation 1.1 (JSR-349)

– JCACHE – viimein standardi cacheille, YAY!! 😉 Tämä on kova juttu. (JSR-107)

– Java State Management – tilanhallinnan standardointia (JSR-350)

– Batch applications for Java -eräajostandardi osaksi EE:tä (JSR-352)

– Concurrency Utilities for Java – concurrency rajapinnat EE ympäristöön (JSR-236)

– Java API for JSON Processing – No REST:n mukana tulee tietystikin JSON (JSR-353)

Että on sitä jotain mitä odottaa. Pääalustoina tietysti JBOSS, Websphere, Weblogic, Glassfish, Tomee, mutta kiintoisaa tulee olemaan myös Oracle PaaS pilvipalvelu, ja se tuleeko esim. Google App Enginen tai Amazonin puolelta tukea uudelle standardille.

JSF 2 ja AJAX

Pitkästä aikaa pääsin taas pitämään JSF 2 koulutuksia. Kovasti olen tästä tekniikasta itse pitänyt, siinä on huomattavia parannuksia versioon 1 nähden mutta siltikään ei joudu aikaisempia oppejaan täysin hukkaan heittämään.

Yksi koukuttava uutuus on JSF AJAX moduuli. JSF 1 heikkoutena oli aiemmin että kun se oli täysin serveripuolen ratkaisu, ja vielä korkealla nostetulla abstraktiotasolla, niin AJAX ei oikein istunut kuvaan. Sitä voi scriptata komponenttien sisään mutta Googlen suosima yhden sivun ajax malli ilman navigointia ei oikein onnistu elleivät kontrollit keskustele keskenään niin client kuin server puolellakin.

JSF 2 to the rescue! Nyt löytyy parannettu elinkaarimalli, JavaScript kirjasto AJAX:ia varten, ja myös helppo tag jolla käskyttää JSF kontrolleja JavaScriptin kautta. Näin ollen sivu jolta ei navigoida ollenkaan pois on nyt mahdollinen.

Perusidea on että vaiheet execute (sisältäen muodosta oliomalli sivusta, päivitä sitä lähetetyillä parametreilla, validoi, konvertoi, kopioi tiedot model:eihin, ja suorita koodi) ja render (käy puumalli läpi ja käske kontrolleja generoimaan lopputulokseen tarvittava HTML) on nyt erotettu toisistaan, ja lisäksi tukevat osittaista suoritusta ja renderöintiä. Näin voidaan pähkinänkuoressa sanoa: Suorita kontrolliin a liittyvät vaiheet, ja piirrä kontrolli b. Eli reagoi johonkin eventtiin, ja päivitä joku osa sivua.

Tässä siis klassinen hello world versio tästä:

<h:form>
   <h:inputText id="name" value="#{helloBean.name}"/>
     <h:commandButton value="Greet me">
	 <f:ajax execute="name" render="output" />
     </h:commandButton>
   <h2><h:outputText id="output" value="#{helloBean.greeting}" /></h2>
</h:form>

Eli tuossa käytännössä todetaan: kun painat nappia, suorita kontrolli jonka id on ’name’, ja päivitä kontrolli jonka id on ’output’. Jos haluaa reagoida muihin javascript eventteihin, ylläolevassa voidaan lisätä parametri ’event’. Ja suorittaessa kontrollia ’name’ mekanismi käy siis pistämässä kaikki muuttujat paikalleen, ja ajaa tarvittaessa myös action bindingit. Todellinen voima ei piile napin painalluksen käsittelyssä, vaan muissa javascript eventeissä, mutta sekin voi olla hyödyllinen – esim. taulurakenne jossa on sorttaukseen ja sivutukseen napit jotka eivät navigoi pois sivulta, vaan päivittävät managed bean tilaa ja renderöivät vain taulun uusiksi.

Tässä esimakua aiheesta, jos päädyn leikittelemään asialla lisää kirjoittelen pikkasen hello worldiä kiintoisampia kikkailuja. Näitä on toki jo maailmalla ruodittu, esim. html 5 canvas elementistä saa paketoitua aika kivan komponentin JSF 2 komposiittimallilla.

 

Vuosi lähestyy loppuaan – Scalaa ja App Engineä ;)

Jep, joululomailut ovat vähentäneet blogikirjailua mutta vielä ehtii yhden artikkelin luikkaamaan sisään ennen kuin vuosi ja kujeet vaihtuvat. Olkoonkin sisällöltään vähän kevyempää tällä kertaa – ei esim. koodi tai konfiguraatiopätkiä tarjolla 😉 Vuoden vaihtumisen kunniaksi uusi ulkoasu kehiin.

Jouduin valitettavasti luopumaan suunnitelmastani toteuttaa google app engine sovellukseen käyttöliittymä Vaadin frameworkillä. Tähän päätökseen vaikutti useampikin asia, mutta se mitä en pystynyt kiertämään oli se että joka vaiheessa oli vastaan tapeltavaa ja säädettävää, ja työaika meni virittelyyn sensijaan että se olisi mennyt ratkaisun tekemiseen. Tämä on aina omassa mielessäni se killswitch jolloin on aika vaihtaa tekniikkaa. Vaadin on itsessään loistava framework, mutta se abstraktoi liiankin korkealle tasolle, jolloin gae:n asettamien vasteaika ja kirjastorajoitusten kanssa tulee vastaan paljon haasteita. Lisäksi tietysti mehukkaimmat komponentit ovat AGPL lisenssin takana josta en järin itse pidä – se kun pakottaa julkaisemaan KOKO oma sovellus lähdekoodina, ei pelkästään muutoksia komponentin koodiin. Tästä pääsee tietysti eroon lisensoimalla komponentin mutta se vaatii tiettyä sitoutumista ratkaisuun. Lopulta ongelmana on myös debuggaus; Testaus pilvessä ei anna aina kovin hyviä virhetietoja ja statistiikkaa – testaus omassa koneessa ei taas toimi samoin kuin pilvessä. Tämä on tietysti vastassa joka frameworkillä mutta kun puolet asioista tapahtuu javascriptin puolella on asiassa vielä lisähaasteita.

Sinnikkäämmät sielut ovat saaneet homman toimimaan, eli tässä pari viitettä gae + vaadin asioihin:

http://vaadin.com/wiki/-/wiki/Main/Google%20AppEngine%20HOWTO

http://www.streamhead.com/maven-spring-vaadin-appengine/

http://devrimyasar.com/blog/2009/11/22/finally-there-vaadin-godsend-on-gwt-google-app-engine/

Eli vielä kerran, Vaadin on hieno ellei peräti loistava framework, ja paljon käytetty, mutta pilvi + vaadin on toistaiseksi early adopter aikaa, jossa joutuu maksamaan aika kovan hinnan etenemisestään. Se on huimasti parempi vaihtoehto kuin paljas Google Web Toolkit, koska suurin osa prosessoinnista ja tilanhallinnasta tapahtuu palvelinpäässä (tästä on myös tietoturvahyötyä GWT:hen verrattuna). Kokonaisuus tulee varmasti tulevaisuudessa paranemaan vielä ennestään, mutta itselleni valikoitui käyttöliittymään RichFaces toistaiseksi, se kun on pilvivalmis uusimmassa 4.0 releasessaan. Näin pääsen hyödyntämään rikkaita JSF kontrolleja ja voin hallita miten paljon AJAX:ia haluan upotella mukaan. So far so good..

Ja sitten, sain valmiiksi koulutusmateriaalin Scala ohjelmoinnista, ja tutustuessa tähän kieleen täytyy sanoa että se on kuin kevättuulen virkistävä hengähdys. Javan vanhuus ja muuttumattomuus näkyy ja useat parannukset ovat kuin laastarilappuja alustan päällä. Se on edelleen kova alusta jolla voi tehdä melkein mitä vain, mutta aika ajoin koodaajalle tekee hyvää tuulettaa vähän ajatuksiaan ja oppia jotain uutta, ja Scala on kyllä miellyttävää. Monet asiat jotka vaativat paljon työtä Javassa ovat salamannopeita Scalassa, ja jokainen koodaaja voi itse päättää haluaako kirjoittaa Scalaa oliomaisesti, vai funktionaalisesti, ja missä suhteissa.

On toki vielä useita alueita joissa Scalassa on keskeneräisiä ratkaisuja ja turhankin monta vaihtoehtoa, mutta suuri rikkaus on myös hypätä saumattomasti Java kirjastoihin aina kun sille on tarve – ja enemmän ja enemmän asioita voi jo nykyisin tehdä scalamaisesti, kuten esim. tiedostojen ja url resurssien käsittelyn, tietokannankäsittelyn, ja web kerrokset. Ja mikä mukavinta, scalaa voi ajaa missä vain java alustalla – esim. pilvessä 😉

Joka tapauksessa, kurssi on näkyvillä http://www.tieturi.fi/avoimet-kurssit/kurssi.html?cat_id=117445444&course_id=83926464 – ja palautetta kuulen mieluusti. Jos homma kiinnostaa niin jatko-osia tulee perässä!

Joka tapauksessa, tämä on viimeinen blogi tälle vuodelle. Parhaimmat uudenvuoden toivotukset kaikille tälle sivuille osuville!

Google App Engine pilvipalvelu ja Java EE 6, osa 3

No niin, huomasin etten ole mennyt paljonkaan yksityiskohtiin näissä pilvipalveluissa, eli ihan omaksi muistintueksikin, tässä yksityiskohtia. Varoitus, tästä tulee rumaa, kuten aina kun yksityiskohtiin mennään.

Toimiva Maven pom jossa on mukana JPA 1 ja JSF 2, on tässä:

<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>fi.tieturi</groupId>
  <artifactId>PilvenVeikko</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>PilvenVeikko Java EE 6 Webapp</name>
  <url>http://maven.apache.org</url>
  <repositories>
    <repository>
      <id>java.net2</id>
      <name>Repository hosting the jee6 artifacts</name>
      <url>http://download.java.net/maven/2</url>
    </repository>
  </repositories>
  <pluginRepositories>
    <pluginRepository>
      <id>maven-gae-plugin-repo</id>
      <name>maven-gae-plugin repository</name>
      <url>http://maven-gae-plugin.googlecode.com/svn/repository</url>
    </pluginRepository>
  </pluginRepositories>
  <dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>servlet-api</artifactId>
      <version>2.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-api</artifactId>
      <version>2.0.2</version>
    </dependency>
    <dependency>
      <groupId>com.sun.faces</groupId>
      <artifactId>jsf-impl</artifactId>
      <version>2.0.2</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>el-impl</artifactId>
      <version>2.2</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-jpa</artifactId>
      <version>1.1.5</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>javax.persistence</groupId>
      <artifactId>persistence-api</artifactId>
      <version>1.0</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-core</artifactId>
      <version>1.1.5</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>javax.jdo</groupId>
      <artifactId>jdo2-api</artifactId>
      <version>2.3-eb</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-enhancer</artifactId>
      <version>1.1.4</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-rdbms</artifactId>
      <version>1.1.5</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>com.google</groupId>
      <artifactId>appengine-local-runtime-shared</artifactId>
      <version>1.2.0</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>org.datanucleus</groupId>
      <artifactId>datanucleus-appengine</artifactId>
      <version>1.0.7.final</version>
      <type>jar</type>
    </dependency>
    <dependency>
      <groupId>com.google</groupId>
      <artifactId>appengine-sdk-api</artifactId>
      <version>1.3.8</version>
      <type>jar</type>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.0.2</version>
        <configuration>
           <source>1.6</source>
          <target>1.6</target>
       </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.1-beta-1</version>
        <configuration>
          <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
    </plugin>
    <plugin>
        <groupId>net.kindleit</groupId>
        <artifactId>maven-gae-plugin</artifactId>
        <version>0.6.0</version>
       <configuration>
          <sdkDir>D:/java/appengine-java-sdk-1.3.8</sdkDir>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.datanucleus</groupId>
        <artifactId>maven-datanucleus-plugin</artifactId>
        <version>1.1.4</version>
        <configuration>
          <mappingincludes>**/domain/*.class</mappingincludes>
          <verbose>true</verbose>
          <enhancername>ASM</enhancername>
          <api>JPA</api>
        </configuration>
        <executions>
          <execution>
            <phase>compile</phase>
            <goals>
              <goal>enhance</goal>
            </goals>
          </execution>
      </executions>
      <dependencies>
        <dependency>
          <groupId>org.datanucleus</groupId>
          <artifactId>datanucleus-core</artifactId>
          <version>1.1.5</version>
          <exclusions>
           <exclusion>
              <groupId>javax.transaction</groupId>
              <artifactId>transaction-api</artifactId>
            </exclusion>
          </exclusions>
        </dependency>
        <dependency>
          <groupId>org.datanucleus</groupId>
          <artifactId>datanucleus-rdbms</artifactId>
          <version>1.1.5</version>
        </dependency>
        <dependency>
          <groupId>org.datanucleus</groupId>
          <artifactId>datanucleus-enhancer</artifactId>
          <version>1.1.4</version>
        </dependency>
      </dependencies>
      </plugin>
    </plugins>
    <finalName>PilvenVeikko</finalName>
  </build>
  <profiles>
    <profile>
      <id>netbeans-private</id>
      <activation>
        <property>
          <name>netbeans.execution</name>
          <value>true</value>
        </property>
      </activation>
      <properties>
        <netbeans.deployment.server.id>[C:\Program Files (x86)\glassfish-3.0.1\glassfish]deployer:gfv3ee6:localhost:4848</netbeans.deployment.server.id>
      </properties>
    </profile>
  </profiles>
  <properties>
    <netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server>
  </properties>
</project>

Julkaisin tuon kokonaisena copy-pastea ajatellen. Pieni mutta tärkeä kohta on lopussa oleva DataNucleus enhancer plugin, koska DataNucleus käyttää vielä vanhanaikaista bytecode vahvistusta, tuo vaihe tehdään käännöksen jälkeen, tärkeää tarkistaa että pakettirakenne-parametri on oikein. Vierastan lisä ant scriptien käyttöä joten yritin tehdä kaiken Mavenillä ja näyttäisi toimivan.

Toinen jippo oli imaista gae kirjastot paikalliseen maven repositoryyn etukäteen, koska tietääkseni niitä ei globaaleista repositoryistä löydy. Kirjastot mitä näemmä tarvittiin olivat datanucleus-jpa, datanucleus-core, jdo2-api, datanucleus-enhancer, datanucleus-rdbms, appengine-local-runtime-shared, datanucleus-appengine, sekä appengine-sdk-api. Lisäksi javan core kirjastoista tarvitsin persistence-api ja servlet-api ja jsp-api pakettien lisäksi jsf-api ja jsf-impl kirjastot, versio 2, sekä el-impl. Huom! JSF-impl on google app enginelle tuunattu versio, johtuen parista rajoituksesta sen suhteen. Tässä pari linkkiä siihen:

Take a look at this site
http://javadocs.wordpress.com/2009/10/17/mojarra-jsf-2-0-rc2-and-google-app-engine-sdk-1-2-6/

and download this file
http://code.google.com/p/joshjcarrier/source/browse/trunk/Sun%20JSF%20GAE/jsf-impl-gae.jar

Rakensin tällaisen scriptin joka vie ne repositoryyn:

call mvn install:install-file -Dfile=lib/appengine-tools-api.jar -DgroupId=com.google -DartifactId=appengine-tools -Dversion=1.2.0 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/shared/appengine-local-runtime-shared.jar -DgroupId=com.google -DartifactId=appengine-local-runtime-shared -Dversion=1.2.0 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/appengine-api-1.0-sdk-1.3.8.jar -DgroupId=com.google -DartifactId=appengine-sdk-api -Dversion=1.3.8 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/orm/datanucleus-appengine-1.0.7.final.jar -DgroupId=org.datanucleus -DartifactId=datanucleus-appengine -Dversion=1.0.7.final -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/orm/datanucleus-core-1.1.5.jar -DgroupId=org.datanucleus -DartifactId=datanucleus-core -Dversion=1.1.5 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/orm/datanucleus-jpa-1.1.5.jar -DgroupId=org.datanucleus -DartifactId=datanucleus-jpa -Dversion=1.1.5 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/orm/jdo2-api-2.3-eb.jar -DgroupId=org.datanucleus -DartifactId=jdo2-api -Dversion=2.3 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/orm/geronimo-jpa_3.0_spec-1.1.1.jar -DgroupId=org.geronimo -DartifactId=geronimo.jpa -Dversion=1.1.1 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=lib/user/orm/geronimo-jta_1.1_spec-1.1.1.jar -DgroupId=org.geronimo -DartifactId=geronimo.jpa -Dversion=1.1.5 -Dpackaging=jar -DgeneratePom=true
call mvn install:install-file -Dfile=jsf-impl-gae.jar -DgroupId=com.sun.faces -DartifactId=jsf-impl -Dversion=2.0.2 -Dpackaging=jar -DgeneratePom=true

No niin , ehkäpä siinä oli taas tarpeettoman paljon tietoa tällä kertaa 😉 Joka tapauksessa, itselleni muistiin mitä askelia tarvittiin pilveen pääsemiseen.