JavaOne 2014 käynnissä

Jep, JavaOne 2014 on taas käynnissä San Franciscossa. En ole tänä vuonna itse paikan päällä, mutta aika on merkattuna kalenteriin ja seuraan mielenkiinnolla etänä.

Missä mennään tällä hetkellä on Java 8 SE käyttöönotto Lambdoineen kaikkineen, ja ME 8 on myös julkaistu, ja EE 8 työn alla seuraavaksi. Olen blogaillut aiemmin jo Javan seuraavista askelista, Java SE 9 tulee ehkä viimein näyttämään mitä Project Jigsaw – Javan modulaarisuusjärjestelmä tarkoittaa. Se ei ole lopulta erityisen seksikäs aihe, mutta se on tärkeä. Javasta on vuosien saatossa tullut aikamoinen bloat, turvoke 😉 Ajatus modulaarisemmasta Javasta on hyvä skaalatessa pienempään päin, ja Mavenin suosio näyttää että moduulien avulla skaalaus ylöspäin on myös tärkeää. Jos viimein saadaan Javaan tukea myös moduulien versioiden huomioimiseen ihan ydintasolla, paketista tulee aika kova. Brian Goetz valitettavasti komennettiin alas lavalta kesken Java 10 mallailun 😉

Jigsaw projektissa on hyvä huomata kaksi vaihetta. Vaihe 1 on purkaa Javan hurja ristiinviittaus-spaghetti pakettien välillä ja saada Javan parikymmentämegaisesta ytimestä aidosti modulaarisempi. Tätähän aloitettiin jo joskus Java 6u10 aikoihin nimellä kernel. Toinen askel on sitten alkaa käyttämään tätä moduulijärjestelmää omien ohjelmistojen kehitykseen yhtälailla, Mavenin tapaan. Tarkoituksena ei näillä näkymin ole kuitenkaan korvata Maveniä repository-puolella, lähinnä moduulien riippuvuuksien julistuksessa. Riippuvuudethan sitten voivat olla paikallisia tai verkon yli noudettavia.

Vaikka on mukava tarkkailla mitä tulevaisuus tuo mukanaan, Java 9 on vielä aika kaukaista. Tämä vuosi 2014 on edelleen Java version 8 ramp-up aikaa: Lambdoissa, rajapintojen oletusmetodeissa, ja kokoelmakirjastojen uusissa stream-piirteissä on sulateltavaa runsaasti ja harva niitä vielä arjessa käyttää. Sertifiointi Java 8:lle on tätä kirjoittaessa vasta beta-tasossa, ja sekin mielenkiintoisella tavalla uusittu.

Tuolla tech keynote joka on klassisesti ollut kiinnostava avaus koko tapahtumalle:

http://medianetwork.oracle.com/video/player/3811045975001

Goetz saa kyytiä kohdassa 34:27 alkaen 😉

Mainokset

Klusteri-uniikit id-arvot Java EE/EJB/JPA

Uniikkien avainten kuten Primary Key-arvojen generointi on hauska juttu. Siihen on tarve lähes joka projektissa, ja siihen on lukemattomia eri tapoja. Yksi hurjimmista on laavalampun kuvioiden käyttö satunnaisluvun generointiin – mutta konservatiivisemmalta puolen löytyy mm. sequence, identity keinot jotka ovat kantakohtaisia. Korkeamman tason abstraktiot kuten JPA abstraktoivat halutessaan myös tämän: GeneratedValue-annotaatio antaa kannan päättää mikä kolmesta id-generointitavasta on fiksuin.

Tähän tulee kuitenkin vähän pykälää lisää jos ei voida syystä tai toisesta käyttää JPA generointia. Kenties halutaan ottaa itse avaimen generointi hallintaan koska siihen liittyy erityissääntöjä. Kenties on tarpeen generoida identity-kentän ohella toinen, uniikki avain joka ei kuitenkaan ole primary key. Pikkasen lisää haastetasoa saadaan jos homma pitää vielä tehdä klusterissa – silloin mikään muistinvarainen ratkaisu ei piisaa – ellei muistia synkronoida verkon yli sopivalla tapaa.

JPA:sta ja Hibernatesta löytyy kyllä valmiina generaattoreita, mutta ainakin JPA standardipuolella pääsy niiden mekanismeihin erillään primary key autogeneroinnista on heikko.Mitä? Minä olen ainakin uniikki!

Joten tähän vähän omia mietelmiäni ja koodia siirrettävästä geneerisestä klusteriystävällisestä primary key generoinnista. Tämä on iteraatio 1 joten päättelyssä ja toteutuksessa voi olla aukkoja, mutta päätin silti paljastaa itseni maailmalle – yksi mukava juttu blogeissa on että niitä voi kommentoida ja palaute on tässäkin tervetullutta jos jokin pistää silmään.

Ensiksi tarvitaan taulu kantaan, josta voi saada niitä arvoja. Sen voi hoitaa esim. JPA Entity Objectilla tähän tapaan:

 

@Entity
public class GenTableEntity implements Serializable {
  private static final long serialVersionUID = 1L;
  @Id
  private String tableName;
  private Long lastId;

  public String getTableName() {
    return tableName;
  }

  public void setTableName(String tableName) {
    this.tableName = tableName;
  }

  public Long getLastId() {
    return lastId;
  }

  public void setLastId(Long lastUsed) {
    this.lastId = lastId;
  }
}

Tästä esimerkistä jätetty pois Javan rakkaat equals, hashCode ja toString toteukset sekä muut hienosäädöt. Kyseessä on siis taulu jossa on String primary key, ja Long arvo jota voidaan (transaktiossa) paukutella.

Seuraava elementti: Singleton, joka pitää yllä id listaa, ja imaisee tarvittaessa serveriltä lisää.

@Singleton
public class UniqueIdGeneratorSingleton {

  private long ceiling; 
  private long current; 
  private static final long RANGE = 1000; 
  private static final String SEQUENCE_NAME = "myitem";

  @PersistenceContext
  private EntityManager entityManager;

  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
  public long getUniqueId() {
    if (ceiling == 0 || current > ceiling) {
     GenTableEntity entity = entityManager.find(GenTableEntity.class,
        SEQUENCE_NAME, LockModeType.PESSIMISTIC_WRITE);
      if (entity == null) {
        entity = new GenTableEntity();
        entity.setTableName(SEQUENCE_NAME);
        entity.setLastId(0L); // Reserve space
        entityManager.persist(entity);
      }
      current = entity.getLastId() + 1;
      ceiling = entity.getLastId() + RANGE; 
      entity.getLastId(ceiling); 
    }
    return current++;
 }
}

Mitä täällä tapahtuu? Kyseessä on generaattori-EJB joka hakee ja tallettaa kantaan mihin lukemaan asti on id:t käytössä. Tässä on optimointijippo: kannasta ei haeta yksi id kerrallaan, vaan tässä koodissa tuhannen erissä. Yhtälailla erä voi olla sata, tai kymmenentuhatta. Ceiling-arvo ja kannassa oleva lastId arvo pitävät kirjaa mihin asti id avaruutta on varattu. Singleton jakelee ensin omasta jäsenmuuttuja-avaruudestaan kaikki arvot, ja kun ne loppuvat, haetaan kannasta seuraava tuhannen viipale.

Koska kyseessä on Singleton bean, metodiin pääsee yksi säie kerrallaan – serverissä. Klusterissa voi kuitenkin olla useampi serveri, joissa voi käydä niin huonosti että jokaisessa ajetaan juuri samaa riviä samasta singleton-koodista. Siksi tässä on päällä vielä transaktiot, ja pessimistinen lukulukko. Kun yksi säie on lukenut rivin kannasta, se lukitaan ja seuraavan kerran siihen pääsee käsiksi vasta transaktion päätyttyä  -kun arvoa on onnistuneesti muutettu.

Huom. tässä mallissa SEQUENCE_NAME on kovakoodattu arvoon ’myitem’ – joten kaikki generoitavat id:t ovat osa samaa, suurta, globaalia arvoavaruutta. Tätä voi muokata helposti siten että parametrina annetaan taulunimi, silloin joutuu tosin id-cachen rakentamaan Map-muotoiseksi.

Testailin tätä hieman eri kanteilta. Suorituskyky riippuu hyvin paljon range-arvosta. Id-generointi ilman kantaosumaa on muutamia millisekunteja, kannan kanssa jutellessa niitä alkaa palamaan satakertaisesti. Range arvona tuhat on aika mukava, turhan suuret range arvot voivat syödä avaruutta turhankin nopeasti, etenkin jos servereitä tiheään buuttaillaan, päivitellään, tai ne kaatuilevat useita kertoja päivässä (No jos niin käy, tämä on pienimpiä ongelmista).

Tätä on tietysti kiva testata myös rinnakkaisesti. Testausta helpottaa kovasti jos tässä on esim. REST api edes hetkellisesti päällä. Testasin tätä restassured + java concurrency kirjastolla esim. näin:

 

@Test
public void getUniqueIdShouldReturnTwentyUniqueValuesWithParallelExecution() throws Exception {

 final int setSize = 2000;

 Callable<Set<Long>> c = new Callable() {
    @Override
    public Set<Long> call() throws Exception {
      Set<Long> idSet = new HashSet<>();
      for (int i = 0; i < setSize; i++) {
        idSet.add(fetchUniqueId());
      }
      return idSet;
    }
  };

  Set<Long> masterSet = new HashSet<>();

  Future<Set<Long>>[] futures = new Future[10];

  for (int i = 0; i < 10; i++) {
    futures[i] = Executors.newCachedThreadPool().submit(c);
  }

  for (int i = 0; i < futures.length; i++) {
    Set<Long> keys = futures[i].get();
    masterSet.addAll(keys);
  }

   // Set only accepts unique values, duplicates are not added
   // as long as equals() and hashcode() are implemented properly
   assertEquals(setSize * 10, masterSet.size());
}

private Long fetchUniqueId() {
  Response response = given()
    .when()
    .get("version/uniqueid")
    .then()
    .statusCode(200)
    .extract().response();
  
    Long id1 = response.jsonPath().getLong("id");
    return id1;
}

Eli ihan mukavasti tuo toimii, hyvä niksi hihassa. Aika armottomasti yritin tätä paukutella nurin mutta tarpeettomankin vakaasti pelittää. En löytänyt taas pikaisella googletuksella suoranaisesti tällaista mistään, joten kirjoittelin itselleni muistiin.

Mutta palautetta tulemaan jos tulee jotain omia ajatuksia mieleen! Tämä on taas semmoinen juttu attä aivan varmasti joku jossain on jo paremmin tehnyt. Toisaalta 90% JPA käyttäjistä ei asiaa koskaan mietikään koska @GeneratedValue. :=)

 

 

 

 

 

Linux + Glassfish 4.0 High availability Load Balancing Cluster – osa 1

Sain taannoin loistavan syyn perehtyä toimintavarman ja skaalautuvan järjestelmän rakentamiseen Glassfish serverin vinkkelistä – olen aiemmin rakentanut vastaavia mm. JBOSS alustalla. Tässä mitä teen ei ole mitään mullistavaa, nykyisellään löytyy paljon teknisesti jännempiäkin juttuja mm. Riak, MongoDB, Hadoop, ja pilvipalveluiden ajatusmaailmasta. Mutta tämä on yksi kätevä työkalu pakissa: miten saada Java sovelluspalvelin toimimaan katkotta yli käyttöhäiriöiden ja päivitysten, ja miten saada se skaalautumaan yli satojen yhtäaikaisten käyttäjien (satoja saa yhdelläkin serverillä vaikka mitenpäin aikaiseksi).

Perusidea on vähintäänkin tuplata kaikki: Jotta saadaan serveri vikasietoiseksi, niitä tulisi olla ainakin se kaksi (mieluiten enemmän), ja jos jotain tilaa on käytetty, se pitäisi jotenkin replikoitua. Mutta vikasietoisuus on yhtä vahva kuin heikoin lenkki: glassfish serverien replikointi ei vielä riitä. Siihen tarvitaan eteen mylly joka reitittää pyynnöt toimiville serverille, load balancer toisinsanoen. Mutta mitä jos load balancer kaatuu? No niitäkin tarvitaan kaksi, tai enemmän, siten että yhden ollessa maissa toinen ottaa sen paikan. Entäpä.. taustatietokannat? Verkko? On paljon kahdennettavia kohtia.

Tämän voi tehdä monella tapaa, mutta itseä viehätti tällainen malli: Joka serveri on virtuaalikone, jossa on Glassfish serveri, Apache Http serveri Load balancerina, ja MySQL tietokanta. Periaatteessa siis joka mylly on lähes identtinen, ja sisältää kaiken tarvittavan. Skaalautuvuutta ja vikasietoisuutta saadaan siis lisäämällä myllyjä – ainakin tiettyyn rajaan asti (Session replikointi, sen tarve ja ratkaisuperiaate vaikuttaa skaalautuvuuden skaalautuvuuteen – ja kaikki serveriresurssit eivät muutenkaan skaalaudu niin hyvin 😉

Tuossa on kuva siitä miltä tämmöinen voisi näyttää – ei ole oma mutta kuvaa niin hyvin mistä on kyse että menköön (lopussa on lähdeviittaus sivustoon josta kuva ja alkuperäiset ideat ovat peräisin):

diagram

No niin, olen jo aiemmin käsitellyt aihetta, miten asennetaan Debian alustalle yksi Glassfish instanssi – joten se tarvitaan tietysti pohjaksi. Samalla kaavalla tehdään vähintään kaksi lähes identtistä serveriä – jotka näkevät toisensa (ping toimii ristiin).

Ensimmäinen askel on poistaa paikallinen serveri ja http kuuntelijat – koska niiden tilalle tulee klusterin instanssikuuntelijat. Tämä tehdään molemmille myllyille, ja Glassfish täytyy olla käynnissä aluksi:

#run these on both debian1 and debian2 machines

$ asadmin delete-http-listener http-listener-1

$ asadmin delete-http-listener http-listener-2

$ asadmin delete-virtual-server server

Selvä pyy. Vaihdetaan seuraavaksi Glassfish tunnukseen, koska sillä serverit ajavat käskyjään, ja luodaan ssh avainparit joilla serverit voivat viestiä. Tämän voit ajaa vain node1 koneesta – ellet sitten halua Domain Admin nodea molempiin koneisiin. Huomaa että glassfish tunnuksella tulisi tässä kohtaa olla myös salasana – sama molemmissa nodeissa. Ellet ole sellaista luonut, aja passwd glassfish nyt.

Tässä esimerkissä koneiden verkkonimet ovat: debian1.mycompany.com ja debian2.mycompany.com:

#run this only on debian1 machine

sudo su --shell /bin/bash glassfish

asadmin setup-ssh --generatekey=true debian1.mycompany.com

# seuraava komento antaa virheen koska glassfish on jo asennettu kakkosnodeen, mutta 
# se myös mukavasti tarkistaa että kommunikaatio pelaa

asadmin install-node debian2.mycompany.com

Seuraava askel, luodaan kaksi hallinta-nodea Glassfishiin:

# run this on debian1 machine

asadmin create-node-ssh --nodehost localhost debian1-ssh 

asadmin create-node-ssh --nodehost debian2.mycompany.com debian2-ssh

Nämä ovat ssh nodeja, eli näiden avulla Glassfish voi yhdestä DA-serveristä käsin lähettää ssh-protokollalla komentoja kaikille klusterin nodeille.

Seuraavaksi luodaan klusteri ja kaksi serveri-instanssia siihen:

# run this on debian1 machine

asadmin create-cluster --systemproperties HTTP_SSL_LISTENER_PORT=8181:HTTP_LISTENER_PORT=8080 cluster1 

asadmin create-instance --cluster cluster1 --node debian1-ssh debian1-gf

asadmin create-instance --cluster cluster1 --node debian2-ssh debian2-gf

Jos tähän asti kaikki sujui, seuraavaksi tehdään Load Balanceriä varten AJP-palvelut. Tässä kikkaillaan vähän – ja asetetaan järjestelmämuuttujiin (system properties) instanssin nimi jota voi serverissä sitten käyttää esim. virtuaalikoneparametreissa kätevästi:

# run this on debian1 machine

asadmin create-http-listener --listenerport 8009 --listeneraddress 0.0.0.0 --defaultvs server --target cluster1 jk-connector

asadmin set configs.config.cluster1-config.network-config.network-listeners.network-listener.jk-connector.jk-enabled=true

asadmin create-jvm-options --target cluster1 "-DjvmRoute=\${AJP_INSTANCE_NAME}"

asadmin create-system-properties --target debian1-gf AJP_INSTANCE_NAME=debian1

asadmin create-system-properties --target debian2-gf AJP_INSTANCE_NAME=debian2

Seuraavaksi, piipahdetaan molemmilla koneilla vaihtamassa masterpassword – mutta siten että se tallettuu tiedostoon jolloin sitä ei koko aikaa kysellä:

# run this on debian1 machine

asadmin change-master-password --savemasterpassword true debian1-ssh

#run this on debian2 machine:

asadmin change-master-password --savemasterpassword true debian2-ssh

Ja lopulta, talletetaan myös tavallinen admin salasana tiedostoon, jotta asadmin työkalun ajo ei juutu dialogeihin:

# on debian1:

asadmin --host debian2 --port 4848 login 

#on debian2:

asadmin --host debian1 --port 4848 login

Nyt ollaan jo aika loppusuoralla. Meillä on jo ennestään init scripti joka ajaa glassfish domain serverin (ja tässä tapauksessa DAS) käyntiin, mutta kannattaa ehkä lisätä scripti joka käynnistää myös molemmissa koneissa instanssin – tai clusterin. Editoi tiedostoa etc/init.d/glassfish-inst ja pistä sinne jotain tämäntapaista:

#!/bin/sh
#
# glassfish init script for Linux 
# It only starts one instance by name. The instance needs to have
# .asadminpass and .asadmintruststore password files created
# for the user.
#
# .asadminpass is created via "asadmin login" command
# .asadmintruststore is created via 
# "asadmin change-master-password --savemasterpassword true"
### BEGIN INIT INFO
# Provides: glassfish-inst
# Required-Start: $local_fs $remote_fs $network $syslog $named
# Required-Stop: $local_fs $remote_fs $network $syslog $named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# X-Interactive: true
# Short-Description: Start/stop a glassfish instance
### END INIT INFO

GLASSFISH_HOME=/opt/glassfish4
GLASSFISH_USER=glassfish
GLASSFISH_INSTANCE=debian1-gf

case $1 in

start)
 echo "Starting Glassfish local instance ${GLASSFISH_INSTANCE}..."
 su - "${GLASSFISH_USER}" -c \
 "${GLASSFISH_HOME}/bin/asadmin start-local-instance "${GLASSFISH_INSTANCE}""
 ;;

stop)
 echo "Stopping Glassfish local instance ${GLASSFISH_INSTANCE}..."
 su - "${GLASSFISH_USER}" -c \
 "$GLASSFISH_HOME/bin/asadmin stop-local-instance "${GLASSFISH_INSTANCE}""
 ;;

restart)
 echo "Restarting Glassfish local instance ${GLASSFISH_INSTANCE}..."
 su - "${GLASSFISH_USER}" -c \
 "$GLASSFISH_HOME/bin/asadmin restart-local-instance "${GLASSFISH_INSTANCE}""
 ;;

*)
 echo "usage: $0 (start|stop|restart|help)"

esac

Huom! Vaihda ylläolevassa tuo GLASSFISH_INSTANCE arvoon 1, 2, tai mitä serveriä käsitteletkään. Joka serverillä se tulee tietysti olla omansa. Jos käynnistät clusterin, se tietysti potkaisee joka instanssin käyntiin kerralla. Tätä tapaa en kuitenkaan vielä ehtinyt kokeilemaan.

Seuraavaksi pistetään tämäkin automaattikäynnistymään:

sudo chmod 755 /etc/init.d/glassfish-inst

sudo update-rc.d glassfish-inst defaults

No niin, sitten vain boottia kehiin. Serverin 1 pitäisi toimia DAS-serverinä, joten sen kautta voit käydä ihan hallintakonsolista katsomassa miltä kaikki näyttää. Kannattaa myös kokeilla asentaa joku pieni ja varmasti toimiva klusterisovellus ja testata vähän miten se asentuu kaikille instansseille, ja miten se käyttäytyy kun instanssit sammuvat ja taas käynnistyvät.

Sellainen löytyy esim. täältä: http://blogs.nologin.es/rickyepoderi/uploads/SimplebutFullGlassfishHAUsingDebian/clusterjsp.war

Pari huomiota sessioreplikoinnin vaatimuksista ja nykytilasta:

Glassfish 4.0 ei virallisesti tue HA piirteitä, mutta siellä on olemassa early access joka toimii ihan hyvin. 4.1 versiossa olisi paremmin testattuna tulossa samat piirteet. Glassfish versioissahan on aina joissain klusterituki, joissain ei, eli kannattaa olla tarkkana version kanssa.

Glassfish 4.0 tukee eri replikointitavoista vain in-memory tapaa, joka tarkoittaa että nodet heittelevät verkon yli toisilleen notifikaatioita, ja replikoivat sessiodataa. Tämä ei ole parhaiten skaalautuva malli, mutta pienille ja keskikokoisille klustereille joissa sessiotilaa ei ole valtavasti ihan ok malli. Tämä edellyttää että klusterissa on GMS palvelu päällä, ja nodet näkevät toisensa verkossa. Hyvä myös tarkistaa että konfiguraation availability service alla on rastit oikeissa laatikoissa, mutta oletuksena pitäisi olla.

gms_service_enabled

availability_service_enabled

Mutta vielä on tärkeä huomioitava asia: Asennettava sovellus tulee olla availability-yhteensopiva ja availability-moodissa. Ensimmäinen edellyttää web.xml tiedostossa distributable=true arvoa (tai ei ollenkaan web.xml tiedostoa). Toinen vaatii että availability laitetaan päälle joko asennettaessa sovellus tai sen jälkeen. Esim. kun asensin em. clusterjsp sovelluksen oletusasetuksilla, siitä jäi rasti pois ruudusta, jolloin sessiot eivät replikoituneet.

availability_enabled

Voit myös kokeilla näkevätkö serverit toisensa ajamalla molemmissa nodeissa about yhtäaikaa tämän:

asadmin validate-multicast

 

Tässä tämä tällä kertaa. Tästä lähteestä ammensin paljon ideoita ja käytännön säätöjä:

http://blogs.nologin.es/rickyepoderi/index.php?/archives/53-Simple-but-Full-Glassfish-HA-Using-Debian.html

Jos tykkäät mielummin tehdä näitä UI:n puolella, tässä hyvä tutoriaali siihen (Glassfish 3 oppaat pätevät suurimmalta osin Glassfish 4:seen):

http://javadude.wordpress.com/2011/04/25/glassfish-3-1-clustering-tutorial/

 

Visualisoi EE riippuvuudet (CDI ja EJB)

Visuaalisena ihmisenä tykkään nähdä asioita eri vinkkeleistä ja saada sitä metriikkaa. Hiljattain heräsi projektissa mielenkiinto nähdä miten riippuvuuden olioiden ja komponenttien välillä menevät, missä kohden niitä voi yksinkertaistaa ja siistiä.

Mukavasti juuri törmäsin kirjoitukseen aiheesta ja löysin palikan joka vielä kaiken lisäksi toimii mahtavasti. Asialla taas kerran vanha kunnon Adam Bien 😉

Temppu on hyvin simppeli: Lisää tämä Maven pom.xml tiedostoon:

            <plugin>
                <groupId>de.struller-baumann</groupId>
                <artifactId>visualee</artifactId>
                <version>0.25</version>
                <configuration>
                    <outputdirectory>visualee</outputdirectory>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-resources</phase>
                        <goals>
                            <goal>visualize</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Ja tadaa! Sieltä ne riippuvuudet piirtyvät buildin ohessa, projektin alle alikansioon /visualee. Sinne tulee HTML+JavaScript+JSON paketti joka on niin paljon vaikuttavampi aidolle projektille ja livenä kuin kuvana – että kannattaa ihan kokeilla itse.

Tuossa kuitenkin maistiaisia:

http://www.struller-baumann.de/visualee/

Kuva

Pikkasen paremmin saa selkoa kun ottaa kiinni palikasta joka kiinnostaa, ja vaikka järjestelee niitä vähän ruudulla – tai käyttää hakutoimintoa.

visualee2

Vinkki: Paikallisesti käytettynä valitettavasti eivät toimi ilman virityksiä Chromessa, mutta esim. Firefox näyttää hienosti myös lokaalina omalta levyltä nämä. Työkalun sivuilla on lisätietoa näistä pikku virityksistä.

 

Lähde:

http://www.adam-bien.com/roller/abien/entry/visualize_your_javaee_dependencies_in

https://github.com/Thomas-S-B/visualee

Goodbye Glassfish

Juuri kun sinänsä erinomainen Glassfish Java EE palvelin alkoi saamaan suosiota ja jopa kiihtyvyyttä tuli uusia uutisia. Sen kaupallinen tuki lakkautetaan, ja Oracle keskittyy jatkossa myymään ja tukemaan Weblogic Application Server tuotteitaan. Muodollisesti lasikalaa toki edelleen kehitetään Java EE referenssitoteutuksena, mutta voipi arvata mm. hallintatyökalujen, monitoroinnin ja klusterituen, tietoturvapiirteiden sekä yleensä Java EE ulkopuolisen innovaation hiipuvan.

Dead_fish_on_the_beach

Tämä ei ole mitenkään suuri yllätys ja kysymysmerkiksihän jää miten puhdas tukematon open source puoli toimii Glassfishille – mutta useimpien kommentaattorien mukaan – kuten esim. Markus Eisele – ei kovinkaan hyvin:

http://java.dzone.com/articles/oh-lord-wont-you-buy-me

Harmin paikka. Glassfish on ollut yksi suosikkiservereitäni koska siinä on aina uusimmat EE piirteet ensimmäisenä, hyvät graafiset hallintanäytöt, helposti pystytettävissä ja hallittavissa, ja aivan riittävän stabiili ja skaalautuva omiin tarpeisiin. Jos tästä jotain hyvää saa irti niin veikkaisin että JBOSS/WildFly saa tästä aivan uutta buustia ja sekin on erinomainen palvelintuote, johon saa tukea tarvittaessa. (Ja Tieturillta RedHat sertifioitua koulutusta, wink wink 😉

Mitäpä muuta uutta? Kiireitä ollut koulutusten ja tulevien Java versioiden kanssa, mutta Android 4.4 KitKat on ulkona, samoin ensimmäinen sitä tukeva puhelin, Nexus 5, johon aion perehtyä juurta jaksain. Virallisten faktojen ohella uumoilen että laite petaa ensi vuonna julkaistavaa Google Glass älylasijärjestelmää. Kenties toiveajattelua, mutta itse odottelen noita laseja enemmän kuin mitään muuta gadgettiä, koska keksin niille oitis runsaasti käyttöä ja softamahdollisuuksia. Tuon ohella mukana mm. parempaa tukea auton bluetooth verkoille, infrapunakaukosäädinsoftille, parempaa vääntöä ja samalla parempaa akunkestoa monellakin saralla, parempaa soveltuvuutta myös nöyremmän pään puhelimiin, OpenGL 2:sta, tukea pilvivarastointi ja pilvitulostuspalveluille, jne.

Nexus 5

Hullun tiedemiehen labrassa on tosiaan liike- ja ajatuksen voimalla ohjausta, ja niitä on tarkoitus kehittää eteenpäin kun aikataulu antaa periksi. Mielenkiintoisinta noissa oli että ne todella toimivat jo nykyisellään. Valitettavasti LeapMotion + Android ei toimi nykyisellään, samoin kuin LeapMotion + RasPi – kiukkuista postia vain kehittäjille jotka eivät ARM prosessoritukea viitsi toimittaa. Sensijaan MindWave tukee täydellisesti Android alustan kehitystä ja laitteille onkin jo paljon sovelluksia jotka toimivat ajatuksen voimalla. Vielä kun saisi aivot toimimaan koherentimmin.

MindWave

LeapMotion

Joka tapauksessa, vaikka vuosi lähestyy loppuaan, tekemistä ja väännettävää riittää. Eli takaisin sorvaamaan.

Ja tässä ne linkit Java ja JBOSS koulutuksiin, jos on aikaa ja resursseja kehittää itseään:

http://www.tieturi.fi/java

http://www.tieturi.fi/haku.html?qc=jboss

JavaOne – Maanantai

No niin, ensimmäinen luentoja täysi päivä alkaa olla valmis ja kirjailen vähän ajatuksia tähän. Yksi ajatus on että on kyllä hyvä olla täällä paikan päällä. Ensinnäkin aikaerosta johtuen on helpompaa seurata rytmissä mukana tapahtumia ja julistuksia. Aikamoista keskittymistä tarvitaankin jos haluaa pysyä jyvällä mitä kaikkea täällä tapahtuu – etenkin kun itseä kiinnostaa vähän kaikki. Toinen huomio on, että tällaiselle visuaaliselle ihmiselle kuin minä on helpompaa muistaa asiat kun ne on nähnyt kerran livenä, versus että niistä lukee vain kalvoilla. Ehkä reissu on karmean matkustuksen arvoinen…

Hiukan yli 400 sessiota – vähän kuin puolet Tieturin kurssitarjonnasta olisi niputettu yhdelle viikolle. Paljon ravaamista, onneksi valtaosa on tässä hotellissa jossa olen majoittuneena. Tänä vuonna on kulkukortissa vähän vähemmän raitoja kuin viimeksi 😉

2013-09-23 13.03.56

Brian Goetz puhui Lambdoista ja tässä aukesi itsellekin hieman uusia ajatuksia vaikka olen niiden parissa jo aikani puuhaillut. Tässä taas itselle mieleen jääneitä pointteja:

– Koodin tulisi olla luettavaa. Tämä tarkoittaa että aie selviää lukemalla koodia. Tämä vähentää virheitä.

– Tottakai on helppo retostella nyt surkealla aiemmalla Java-koodilla, kun parempi vaihtoehto löytyy. Aiempi koodi on läpäissyt tarkistuksen aikanaan, nyt Java on ollut viimeisiä saarekkeita joissa ei vielä Lambdoja ole. Java 8:sta alkaen tulee olemaan. Lambdoilla monet kivuliaat, etenkin kokoelmien ja tapahtumankäsittelijöiden käyttöön liittyvät asiat näyttävät hurjasti paljon yksinkertaisemmilta ja luettavilta.

– Yllättäen suorituskyvyssä ei ole tullut takkiin: stream() operaatioita ei ajeta peräkkäin vaan yhdistettynä, ja parStream() operaatiot vieläpä fork&join tapaan rinnakkain. Nykypäivän raudalla jo tästä on suunnattomia hyötyjä – tulevaisuuden 64-ytimisellä raudalla astronomisia hyötyjä.Java 7 Fork&Joinia tarvitsee koodata itse käsin yhä harvemmin.

– Haluttiin edelleen pitää yhteensopivuudesta kiinni: siksi ei uusia funktiotyyppejä tai syntaksimuutoksia (sanottavammin) – vanhat rajapinnat ovat maagisesti yhteensopivia Lambdojen kanssa: funktiorajapinta on rajapinta jossa on yksi funktio, siinä kaikki

Tuossapa esimerkkiä lisää, Java 7 versio (tai Java 1.2 versio yhtä hyvin 😉  – huomaa miten koodi tuplautuu, rikkoen DRY periaatetta:

Collections.sort(people, new Comparator<Person>() {
    public int compare(Person x, Person y) {
        return x.getLastName().compareTo(y.getLastName());
    }
});

// Ja tässä Java 8 versio Lambdoilla:

people.sort(comparing(Person::getLastName));

Adam Bien piti mielenkiintoisen esityksen aiheella Java EE Demystified. Huone oli tupasen täyteen pakattu ja seisomapaikatkin käytössä. Eturivistä pari Spring-fanaatikkoa yritti kovasti keskeyttää alkupäästä esitystä mutta lopulta se pääsi rullaamaan. Täytyy sanoa että Adamin ajatukset tehokkuudesta ja Enterprise sovelluksista ovat niin pitkälti samoja kuin omasta suustani tulevat että tästedes voin todeta jos joku haluaa kuulla meikäläisen mielipiteitä: Ostakaa Adam Bienin kirja. Siinä on jo ajatukset valmiiksi purettuna helppoon muotoon. 😉 Pari huomiota jota jäi mieleen itselle:

– Transaktioita tarvitaan. Ilman niitä käy huonosti.

– Transaktioiden tekeminen on erittäin helppoa Java EE alustalla, ja niiden ’overhead’ eli ylimääräinen kuormitus mitätön. Samoin EJB:n.

– Jos ei käytä EJB:tä päätyy rakentamaan vain EJB:n uudestaan – yleensä huonommin lopputuloksin – koska EJB:n mukanaan tuomia hyötyjä useimmiten tarvitsee. Jos kehittäjä sovelluslogiikan sijaan päätyy kodaamaan uudestaan sovelluspalvelinta, se on yleensä hukkaanheitettyä energiaa.

– Jos tekee normaalia yrityssovellusta sadoille käyttäjille, JSF on paras framework nopeaan sulavaan kehitykseen. Jos haluaa täyden kontrollin käyttöliittymästä, kannattaa miettiä HTML5 Single Page App tyyliä – ja käyttää Java EE:tä serverillä. Jos haluaa tehdä uuden Twitterin/Facebookin/Youtuben, kannattaa heittää kaikki arkkitehtuurit ja olettamukset roskiin.

– Jos tekee kohtuulliselle määrälle käyttäjiä tilallisuudesta voi olla jopa hyötyä. Jos tehdään sadoille miljoonille, taas kerran valmisratkaisut saa heittää roskakoriin. TIlattomuus ei ole koskaan väärin, mutta se johtaa käytännössä raskaaseen tietokannan käyttöön.

– Olisi naurettavaa olla käyttämättä Java EE alustaa, ja käyttää jotain muuta/koodata omaa. Noin niinkuin useimmissa tapauksissa 😉 Tämä tarkoittaa ja sisältää ilman muuta pyhän kolminaisuuden EJB, JPA, ja CDI, ja kaiken tietysti sen ympärillä.

Tuosta löytyy pari Adam Bienin kirjaa joita voin suositella kirjahyllyä koristamaan – pirteän värisiäkin vielä ovat! 😉

http://press.adam-bien.com/

Lopuksi, jäin vielä miettimään eilistä Keynote päivää. Yhtä tärkeää kuin mitä sanottiin oli mitä ei sanottu. Mielenkiintoista oli, että tilaisuudessa ei pahemmin messuttu Oraclen kaupallisesta tarjonnasta, ei tuputettu tuotteita. Siellä ei edes paljoakaan puhuttu servereistä koska ne ovat tuoreita ja valmiina EE 7:n muodossa. Hyvin mielenkiintoinen fokus IoT aiheeseen, joka vastaa omia ajatuksiani jo pitkältä ajalta. Raspberry PI laitteita on kaikkialla – Hazelcast nimisen lafkan väki oli rakentanut hulluuttaan PI laitteista ja legopalikoista klusterin, jolla esitteli hajautustekniikoitaan pienemmässä skaalassa.

Hazelcast Lego-Pi cluster

Messuilla näin myös IoT teemaan liittyen kotiautomaatiota, robottihain, ja legoista kootun R2D2-robotin. IoT ja sulautettujen maihinnousu siis lienee tämän vuoden teema. Sikäli mielenkiintoista että Suomen päässä tuntuu näkyvän kaikki tämä ohuesti.

2013-09-23 09.40.24

2013-09-23 14.20.59

Kuten joku bloggasikin jo: Who needs chess-playing robots? Vaikuttaisi kuitenkin siltä että Java-pohjaisia ratkaisuja on häkellyttävässä määrin liikkeellä jo nyt kaikkialla muualla kuin vain serverissä. Hyvä myös huomata hinta. Arduino Pi-mikrotietokoneen hinta on n. 30 dollaria, ja sellainen ohjasi esim. tätä robottia, samoin siitä oli rakennettu DukeTab tablettitietokone. Aikanaan olin jo innostunut SunSpot laitteista ja ne olivat aika alkeellista ja suhteessa kallista teknologiaa tähän verrattuna. Hyllystä löytyy kuitenkin SunSpot 😉

Robotti pelailee shakkia

Ja jeei Vaadin-kavereille! Piipahdin heidänkin standillaan ja edelleen tuo iloa ja ylpeyttä nähdä suomalaisilla firmoilla standeja tämän kaliiberin kehittäjätapahtumassa toisella puolen maapalloa.

Tuossa linkki artikkeliin jossa pohdittiin Java-robotin hintaa ja hyötyjä:

https://weblogs.java.net/blog/editor/archive/2013/09/23/javaone-2013-impressions-1-so-who-needs-chess-playing-robot-anyway

Tässä pari mehukasta tuotelinkkiä muutenkin näyttelyjen puolelta:

https://vaadin.com/

http://www.jfrog.com/ (Artifactory ja Bintray, Mavenin käyttäjille)

https://saucelabs.com/ (Testaus pilvipalveluna, tästä bloggasin aiemmin)

http://www.cloudfoundry.com/ (Pilvipalvelualusta)

http://newrelic.com (Oma suosikkini ja käytössäkin, sovelluksen reaaliaikaista suorituskyky ja terveystilamonitorointia, monitorointi ulkoistettuna pilvipalveluna, mahtavan visuaalinen! Nyt näemmä myös mobiilisoftalle…)

http://www.jinfonet.com/ (Joku kysyi joskus raportointisoftista. Tää on nätti 😉

JavaOne lähestyy – TJ 9

Java One 2013 seminaariin San Franciscossa on enää reipas viikko aikaa. Siellä on taas luvassa täyteen pakattu viikko täynnä tietoa nykypäivän jännittävimmistä sovelluskehitysalustoista – ja tehdyistä projekteista. Tämä on kuin muotinäytös nörteille: Catwalkilla astelee sorjasääristen kaunottarien sijasta intomielisiä insinöörejä puhumassa asioista jotka ovat lähellä sydäntä. Kun Java-koodaajia löytyy maailmanlaajuisesti jo yli 10 miljoonaa – ja tänne suurimpaan tapahtumaan kokoontuvat kaikki kynnelle kykenevät – ilmassa on niinsanotusti urheilujuhlan tuntua 😉

The Duke

Odotettavissa on tiivis annos kesällä julkaistusta Java EE 7 alustasta ja sen käytöstä, edelleen paukutetaan jo laajassa käytössä olevan Java EE 6 alustan parhaita puolia, ja odotellaan ensi vuodeksi kypsyvää Java SE 8 versiota. Näiden ohella tehokkaat vaihtoehtokielet kukoistavat. Vastakkain pistetään Groovy, Clojure ja Scala – ja Grails vs Play. NoSQL kannat, Riak, MongoDB, big data, business intelligence, dashboardit ja eräajot kukoistavat. Käyttöliittymiä koristellaan nykyisen vaativan maun mukaan niin webissä kuin mobiilissa. Skaalautuvuutta pitää piisata miljardeille käyttäjille 😉

Fork&Join

Puuhailen tässä itsekin esittelyvideota EE 7 alustasta – jonka parissa on tullut vietettyä aikaa. Tieturin Java EE ohjelmointi-kurssi on ollut viime kevään hittejä, ja syyskaudellekin mahtuu vielä lisää osallistujia. Kurssi painottuu pääosin EE 6  -tasoon, mutta EE 7 -päivityksiäkin on jo luvassa. Kyseessä on sikäli mahtava paketti että pistimme sinne kaikki tärkeimmät Java EE teknologiat yhteen nippuun joita aiemmin joutui metsästämään kolmen päivän paketeissa. Ja mikä tärkeintä, nyt pääsee näkemään kokonaisuuden. Härskiä promootiotahan tämä on mutta koulutus on oikeasti mahtava jos nykymaailmassa Java EE alusta toimenkuvaan millään lailla kuuluu. 😉

IMG_8172

Jo viime kerralla JavaOnessa bloggasin ja twiittasin ahkerasti reaaliajassa mitä kaikkea osui tutkaimiin. Nyt kollega antoi vinkin Vine-nimisestä palvelusta jossa ideana on kuuden sekunnin videot aiheesta mistä hyvänsä. Kissavideot näyttivät olevan suosiossa nykyisellään, mutta vaikutti sen verran hauskalta Nexus 7 tabletista käsin että saatan pajauttaa pari mietelmää paikan päältä sinnekin puolelle.

JavaOne taskuversio oli lifesaver kun sessioita oli siellä sun täällä. Go mobile! ;)

Se tämän hetken kovin Java-kurssi eli Java EE -ohjelmointi löytyy täältä – mukaan vain jos rahkeet riittävät:

http://www.tieturi.fi/kurssit/kurssi.html?course=85000180

Kaikki Tieturin Java-kurssit (Ja Scala ja Groovy) tarjolla osoitteessa:

http://www.tieturi.fi/java

JavaOne 2013 agenda – jos olet tulossa niin moikkaa toki paikan päällä:

http://www.oracle.com/javaone/agenda/index.html