Spring Boot 2.0.0RC1 julkaistu

En ole hetkeen kirjoitellut omaa blogiani, olen pahasti laiminlyönyt sitä ja kirjoitellut firmablogin puolelle englanniksi. En paranna pahoja tapojani vieläkään, mutta linkkaan mehukkaan artikkelini Java 9 moduuleista, jlinkistä, Spring Boot 2.0 versiosta, ja Dockerista, ja miten ihania mikropalveluita niillä saakaan aikaan.

http://dev.solita.fi/2018/01/24/Java9-modules-Spring-Boot-2-Docker.html

Ja tähän tarpeeton kuva koiranpennusta

Ja tähän tarpeeton kuva koiranpennusta

Tänään Spring Boot pääsi 2.0 beta ja snapshot statuksesta eroon, ja julkaistiin release candidate 1. Se tarkoittaa, että rajapinnat on jo melkolailla hyydytetty, ja muutokset tapahtuvat syvemmällä ennen julkaisuversiota. Sen saa Mavenista imaistua mm. näin:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RC1</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies><repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

Mitä ihmeellistä siinä sitten on? No paljonkin. Itseä kiehtoo ensinnäkin se, että se toimii Java 9 version kanssa suoraan yhteen. Mikään Spring 1.x versio ei toimi, eikä tule toimimaan. Sen lisäksi siellä on mm. reaktiivista ohjelmointimallia tuotu perinteisen service mallin rinnalle, ja turvapuolen asioita möyhitty parempaan suuntaan. Laajempaa tarinointia mikä on uutta löytyy mm:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0.0-RC1-Release-Notes

Java 9 taas on ihanuutta mm. Stream api parannusten, jshellin, ja etenkin modulaarisuuden myötä. Tuossa linkkaamassani dev blogi artikkelissa mm. kuvataan, miten parisataamegaisesta JDK:sta saadaan tiristettyä muutaman kymmenen megaa kooltaan oleva virtuaalikone, joka pyörittää kyllä Spring Boot REST palveluita, mutta omaa paljon vähemmän turhaa kirjastoa ja koodia kuin ennen. Eli vähemmän tietoturvahaavoittuvuuksia, vähemmän levyn ja muistinkäyttöä.

Tuohon kun länttäät päälle Dockerin, aletaan olla jännän äärellä. Jos et tee jo serverlessiä, tuo on pino jolla taas pärjää pitkään.

Alunperin Java versio 8 oli menossa jo kohti elinkaarensa loppua tämän vuoden syyskuussa – mikä olisi tarkoittanut, että esim. tietoturvapäivityksiä ei siihen enää tipu. Mutta mene ja tiedä, joku ehkä tajusi miten iso paukku Java 9 siirtymä voi olla. Joten Java 8 EOL deadlinea lykättiin ja pehmennettiin isosti.

https://blogs.oracle.com/java-platform-group/extension-of-oracle-java-se-8-public-updates-and-java-web-start-support

Eli, Java versiolla 8 voi hyvin räpytellä vielä 2019 tammikuuhun asti, ja miksei pidemmällekin jos tykkää elää vaarallisesti. Tai voi maksaa tuesta Oraclelle tai IBM:lle ja räpytellä vuoteen 2025. Mutta toisaalta Java versioon 9 voi siirtyä vaikka nyt, heti, tänään. Itselläni se on jo ensisijainen JDK koneessa, ja ensisijainen valinta uutta tehdessä.

Eli ehkä tuosta taas vähän mietintöjä potkimaan vuosi 2018 käyntiin. Tietysti katsoessa tulevaisuuteen, Java versio 9 on jo aika legacyä – sehän on jo monella käytössä. Kiinnostaako Java version 15 julkaisuaikataulu ja tuki?

Lähde: https://www.infoq.com/news/2018/01/JavaSupportJan18

Tuosta ehti jo jokunen vääräleuka päättelemään, että turha päivitellä ysiin, kun samantien voi hypätä versioon 11, kun Java 8 tuki päättyy? 😉 Siitä lisää ehkä myöhemmin.

 

 

 

Mainokset

Java 9 on ulkona

No niin, tällä kertaa vain nopea heads-up, eli Java 9 putkahti juuri putkesta:

http://www.oracle.com/technetwork/java/javase/downloads/index.html

Olen blogaillut tästä jo useampia kertoja, mutta nyt on aika asentaa se ja ottaa ensisavut, katsoa miten release versio toimii käytännössä.

jrepl ja modulet paukkumaan.

[edit]

Tuikataan nyt heti tähän huomio: Spring 1.x ei futaa JDK 9 kanssa, ei siis käänny, eikä tulekaan kääntymään. Siellä on sorkittu JDK internalseja joita ei enää ysissä saa sorkkia.

Spring 2 tulee tukemaan Java versiota 9 – Milestonesta 4 alkaen pitäisi jo periaatteessa tukea. En ole vielä ehtinyt varmentamaan.

Docker + Java Trixx

Sattuneesta syystä Docker työkalupakin käyttö on itsellä lisääntynyt suorastaan räjähdysmäisesti viime aikoina. Se ei ole aina helppoa, mutta on kyllä palkitsevaa. Kun ensi kertaa saa hallittua kunnon könttiä palveluita parilla komentorivikomennolla, sensijaan että aiemmin seikkaili siellä ja täällä ja saastutti konettaan X kappaleella erilaisia asennuksia… Ja kun aiemmin Vagrant-koneet haukkasivat suurimman osan muistista, IntelliJ loput, ja nyt docker-kontteja voi läiskiä samaan tilaan tusinan.. Niin olen myyty.

Miten kontit juttelevat?

Pari niksiä on tullut opittua – tai oikeastaan luettua manuaalia tarkemmin. Niksi yksi oli, miten saada docker-compose alla docker-palvelut näkemään toisensa? Ratkaisu oli häkellyttävän yksinkertainen: Käytä docker-compose.yml versiota 2.0, tähän tapaan:

version: '2'
 services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

That’s all you need. Versiossa yksi piti linkitellä palveluita, mutta versiossa kaksi oletuksena saman docker-composen osat ovat samassa virtuaaliverkossa. Se tarkoittaa että ne näkevät toisensa suoraan imagen nimen mukaan, esim. jos web haluaa viitata redis-palveluun http protokollalla porttiin 6379, homma hoituu:

http://redis:6379

Tietysti voi olla että ajat palveluita välillä dockerissa, välillä ei. Itse olen havainnut käteväksi Spring Boot sovelluksissa käyttää tähän profiileja, docker-profiili ylikirjoittaa tarvittavat url viitteet tai vastaavat palvelinviitteet näillä image nameilla, ja perusprofiilissa voi olla että viitataan vielä localhostiin, testiympäristössä voidaan viitata taas ihan muualle.

Dockerin verkkoja voi hallita myös manuaalisesti, ja niistä voi koostaa haluamiaan kokoonpanoja. Kuitenkin, oletuksena siis kontit näkevät toisensa kunhan ovat samassa verkossa. Ei tarvitse avata mitään portteja, ellet sitten halua niihin ulkoapäin viitata.

Miten kontti viittaa hostiin?

Nogh, kaikkea ei saa konttiin vieläkään. Omassa OSX koneessa esim. Windows SQL server ei konttina pyöri, vaikka konttina löytyykin. Docker for Mac antaa vain herjaa, ympäristön pitäisi olla Docker for Windows. Joten joudun tekemään vähemmän ideaalin ratkaisun: Viittaamaan kontista ulospäin.

Onneksi homma hoituu, pitää vain välittää Dockerille tieto siitä ip-osoitteesta jossa host toimii. Se onnistuu esim. näin (OSX kone):

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)

Dockerfilessa ei voi valitettavasti viedä ihan helpolla sisään env muuttujia, ja oletuksena kontit eivät näe ympäröivien hostien muuttujia. Vaan eipä hätää. Olen itse siirtynyt enenevässä määrin käyttämään docker-composea, ja siellä homma hoituu. Määritellään env muuttuja uudestaan docker-composessa, sitten käytetään sitä java-komentorivillä, viedään todellinen url sisään joka siis viittaa env muuttujan mukaiseen ip-osoitteeseen.

mah_service:
  environment: 
    - HOST_ADDRESS="localhost"
  build: ./mah_service
  command: echo "HOST ADDRESS FOR SQL SERVER $HOST_ADDRESS"
  command: java -Dspring.profiles.active=docker -Dspring.datasource.url="jdbc:jtds:sqlserver://${DOCKERHOST}:1433;DatabaseName=demo" -jar mah_app.jar
  ports:
    - "8080:8080"

Tah-dah, magic happens. Joka tapauksessa, tämä ei ole nätti ratkaisu, vain workaround. Windows dockesterijat eivät tarvitse tätä, vaan käyttävät mieluiten sql serveriä kontissa. Se on aina paras vaihtoehto. Lienee ihan reilua että MacOS puolellakin saa joskus kärvistellä. MS SQL Server for Linuxia ootellessa…

No, siinä tällä kertaa havainnot. Postailen tänne itselleni muistiin jatkossakin niksejä, ettei unohdu. Pian tulee Docker 1.3 ja lisää kivaa… 😉

 

Java 9 on kymmenen kertaa nopeampaa!

Törmäsin mielenkiintoiseen ilmiöön taannoin. Valmistelin esitystä suorituskyvystä ja Java muistimallista, ja ajoin eräänlaista benchmark sovellusta Dockerin avulla eri virtuaalikoneissa. Sovelluksen ideana on sisältää aika typerästi kirjoitettua mutta varsin tavanomaista Java-koodia. Silmukoita, ehtolauseita, merkkijonojen käsittelyä, laskentaa, kokoelmien käsittelyä, ja kellottaa paljonko kaikkeen menee aikaa. Tällä voidaan myös nähdä nykyaikaisen virtuaalikoneen itseään optimoiva vaikutus – kun ajo jatkuu, nopeus yleensä kasvaa. Tässä on sovelluksen mittaustuloksia Oracle Java 6 Docker kontissa ajettuna:

Screenshot 2016-10-16 13.19.54.png

Eli, yhden kierroksen aika on n. 84 sekuntia, laskien 82 sekuntiin jahka virtuaalikone vähän ”lämpenee” eli käytännössä jit-kääntää enemmän koodia ja tekee muita tarvittavia optimointeja.

 

Tässä on OpenJDK+Java 8 ajotulokset:

Screenshot 2016-10-16 13.23.31.png

Kuten tuloksista näkyy, uudempi virtuaalikone optimoi usein tehokkaammin. Tässä kierrosajat pyörivät n. 62 sekunnin pinnassa – Java 6 verraten on irronnut noin 20 sekuntia, tai 1/4 suoritusajasta. Paras kierrosaika oli jopa 52 sekuntia. Aika hyvä tulos!

Kokeillaanpa G1 roskankeruualgoritmilla:

Screenshot 2016-10-16 13.35.12.png

Oops! Vaikka G1 on teoriassa kauneinta ja uusinta mitä roskankeruualgoritmeihin tulee, se ei ole joka ongelmaan optimaalinen ratkaisu. Suoritusajat vaihtelevat 98 ja 104 sekunnin välillä ja ovat nousemaan päin. Tällä sovelluksella ja tämän koneen muistilla tässä tuli takapakkia, huonompi suorituskyky. Varmaan tästä syystä G1 ei ole vielä oletusalgoritmina vaan pitää erikseen kytkeä päälle lisäparametrilla -XX:+UseG1GC.

Java 9 julkaistaan vasta pitkällä ensi vuonna. Siitä on kuitenkin jo prereleaseja liikkeellä, ja jopa Docker virtuaalikuva. Tämän ansiosta on lasten leikkiä ajaa sama koodi Java 9:llä. Tulokset tässä:

Screenshot 2016-10-16 13.36.26.png

WUT? Sama koodi, tekee saman asian, sama koneympäristö ja resurssit. Suoritusajat vaihtelevat 9 ja 12 sekunnin  välillä. Karkeasti ottaen noin kymmenen kertaa nopeampaa kuin useimmat muut testiajot, ja yli viisi kertaa nopeampaa kuin paras tulos tähän asti.

Jotain on muuttunut. Mitä, en tiedä vielä. Epäilen että yksi tekijä voi olla Jigsaw moduulimallit. Toinen tekijä lienee, että on taas opittu tunnistamaan joku negatiivinen koodaustapa, ja optimoimaan sen suoritus. Tulokset tuskin ovat yleispäteviä, ne pätevät lähinnä tähän tyypilliseen koodiesimerkkiin mitä käytin, ja tähän ympäristöön. Docker välissä voi myös vaikuttaa jotain, tuskin kuitenkaan paljoa. Niin tai näin, koodi otti taas kerran hurjan tehokkuushypyn. Tätä herkkua olisi luvassa ensi vuonna.

Virtuaalikoneiden ihanuus on siinä, että nautit kaikista edistysaskelista, ilman koodimuutoksiakin. IBM nimesi juuri oman open source JDK 9 versionsa JIT-kääntäjän Testarossaksi, joten veikkaisin että sieltä on myös suurta hyvyyttä tulossa.

p.s. Docker on ihana keksintö!

p.p.s. Niin on Cathode terminaalikin :p

 

Java 9 viivästyy – saatavana heinäkuussa 2017

Tuoretta uutista, tosin ei yllättävää. Java 9 – jota on jo lykätty useita kertoja, ja jonka ominaisuudet ovat kaikki aiemmista versioista lykättyjä – viivästyy vielä. Tällä kertaa ihan ymmärrettävästä syystä. Se ei vain ole vielä valmis, ei ehdi, ja muutokset ovat merkittäviä.

Mutta käytännössä siis mennään Java 8:lla vielä tovi, ja aikaa on oppia mikä kaikki muuttuu Java 9 myötä. Tämä viimeisin lykkäys ei ole kuin 4kk lykkäys, ja toki nyt jo saatavana olevat EA buildit ovat varsin pitkällä. Mutta kun corea sorkitaan, pienikin muutos on iso muutos ja vaatii aikaa ja rakkautta. 😉

Tieto ei ole toki vielä vahvistettua, mutta lykkäystä on ehdotettu, ja ehdotus menenee läpi koska valmista ei vain tule aiemmalla aikataululla.

Lähde: http://mail.openjdk.java.net/pipermail/jdk9-dev/2016-September/004887.html

JavaOne 2016 häämöttää

Viikko vielä aikaa JavaOne seminaariin – viikon päästä paikallista aikaa sunnuntaina olen paikan päällä San Franciscossa, pää pyörällä jetlagista ja sessioista, absorboimassa kaiken tiedon ja vaikutelmat mitä saatavilla on. Pitäisi olla mielenkiintoinen viikko tulossa.

Yli neljästäsadasta sessiosta on jotakuinkin mahdotonta valita edes suurin osa mikä kiinnostaa. Itse priorisoin Java 9 asioita, Docker ja Microservices asioita, ja sitten hiukan Java EE 8 puolta myös. Voisin löydä vetoa että sitä valaistaan muutenkin keynoteissa. Ohjelman ulkopuolella on myös muutama kiinnostava yhteisötapaaminen ja keskustelu luvassa, ja tietenkin yritän bongata mahdollisimman paljon suomalaisia Javastajia.

 

 

Nyt olisi tarkoitus bloggailla paikan päältä päivittäin jotain pientä, vaikutelmia ja highlighteja. Blogaus tapahtuu tällä kertaa englanniksi, Solitan dev-blogin puolella, eli sitä kannattaa pitää silmällä. Sitä kannattaa muutenkin pitää toki silmällä – raudankovaa settiä tulossa usealta muultakin kirjoittajalta taas lähiaikoina:

http://dev.solita.fi/

 

Kotlin ja JavaFX – ihanaa!

Aloin kesäloman ratoksi perehtymään hiukan Kotlin ohjelmointikieleen – kirjailin siitä jo ensivaikutelmia aiempaan blogiini. Koska en näillä näkymin pääse hetikohta käyttelemään Kotlinia työprojekteissa, päätin harrastella sillä jotain muuta ominpäin.

JavaFX on entuudestaan suuri rakkaus – harmillisen vähän käytettyä tekniikkaa sekin, mutta toimivaa. Ajattelin yhdistellä näitä ja katsoa mitä siitä syntyy, voi olla että peli vielä jossain vaiheessa. Peliohjelmointi ei ole oma vahva lajini – mutta huonommankin pelin koodailusta tulee opittua paljon. 😉

No niin, joka tapauksessa, kaikki alkaa hello worldistä. Eli miltä näyttää Kotlinilla tehty pääohjelma joka käynnistää JavaFX ikkunan?

import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.layout.Pane
import javafx.stage.Stage

class Test : Application() {

  override fun start(stage: Stage) {
    var pane = Pane()
    var scene = Scene(pane, 200.0, 200.0)
    stage.scene = scene
    stage.show()
  }

  companion object {
    @JvmStatic
    fun main(args: Array<String>) {
      launch(Test::class.java)
    }
  }

}

Mitä juuri tapahtui? 😉 Kotlinissa on tosiaan vähän yksinkertaistettu syntaksi Javaan verrattuna. Kuten kuvasta näkyy, muutama modifieri puuttuu, tyyppejä ei tarvitse toistaa, vaan ne päätellään fiksusti tarvittaessa. Funktiot määritetään fun avainsanalla. Ehkä kiintoisin osa tässä on Scalasta tuttu Companion Object. Static avainsanaa kun ei Kotlinissa ole, Companion Object on luokan ’automaattinen instanssi’. Tämän lisäksi tietysti ilmeistä, että Kotlinista käsin voi käyttää kaikkia Java kirjastoja, mukaanlukien Java 8 sisältämä JavaFX.

Miten tuon sitten voi kääntää, paketoida, ajaa? Mavenin voi opettaa prosessoimaan Kotlinia. Oma pom.xml sisältää seuraavia osia:

<dependencies>
  <dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>${kotlin.version}</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-test-junit</artifactId>
    <version>${kotlin.version}</version>
    <scope>test</scope>
  </dependency>
</dependencies>

Ylempänä on tietysti määritetty property-muuttujat kotlin.version ja junit.version (1.0.3 ja 4.12 tällä hetkellä). Kotlin käännöksiä varten tarvitaan tietysti kotlin-stdlib riippuvuus. Ilman etukäteen kirjoitettuja yksikkötestejä ei voi ihminen elää, joten siksi junit riippuvuus. Ja lopuksi vielä kotlin-test-junit riippuvuus tuomaan vähän lisämukavuutta liitokseen. Seuraavaksi veivataan build prosessi käsittelemään kotlin-koodit src/main/kotlin, ja src/test/kotlin kansioiden alta:

<build>
  <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
  <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>

  <plugins>
    <plugin>
    <artifactId>kotlin-maven-plugin</artifactId>
    <groupId>org.jetbrains.kotlin</groupId>
    <version>${kotlin.version}</version>
    <configuration/>
      <executions>
        <execution>
          <id>compile</id>
          <phase>compile</phase>
          <goals>
            <goal>compile</goal>
          </goals>
       </execution>
       <execution>
         <id>test-compile</id>
         <phase>test-compile</phase>
         <goals>
           <goal>test-compile</goal>
         </goals>
       </execution>
     </executions>
    </plugin>
  </plugins>
</build>

Jep, ja näin Maven kääntää Kotlin-koodit pluginin avulla bytecodeksi, tavanomaiseen paikkaan, normaaleissa Maven vaiheissa. Lopuksi säädetään vähän paketointia.

<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <mainClass>game.Pong</mainClass>
      </manifest>
    </archive>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Eli, tämä Maven Assembly plugin tekee lopputuotoksesta mega-jar paketin, jossa on kaikki tarvittava. Oman maun mukaan voi tehdä fiksumman käyttäen manifest riippuvuuksia, tai Java 9 moduuleita, mutta tässä kohtaa tämä on ihan bueno, ja helpottaa levitystä ja testausta.

Vein koodia vähän pidemmällekin, otin käyttöön game loopin, animaatiota, piirtoa, mutta puidaa niitä toisella kertaa. Pistin koodit Git repositoryyn, josta löytyy välivaiheita. Nykyinen koodi ei tee vielä paljoa, mutta on hauska tutkimuspöytä sille mitä JavaFX on nykymuodossaan, ja miten Kotlin helpottaa koodin kirjoittelua.

Linkki Gittiin: https://github.com/crystoll/kotlinfx