AWS Certified Solutions Architect – Associate

Kävin viime viikolla suorittamassa tuon otsikossa mainitun sertifikaatin – vaikeampi kuin odotin mutta läpi meni. Ajattelin kirjailla tähän vähän fiiliksiä, ajatelmia ja vinkkejäkin tuohon liittyen.

Nykyisessä pajassani (Solita) ollaan aika pilvinatiiveja. Meillä on omaa pilveä, ja aina kun projektit sen sallivat, pyritään tarjoamaan alustaksi jotain pilven nurkkaa. Syyt tähän ovat ilmeisiä. Pilvi tarjoaa parhaimman DevOps kokemuksen (tai ainakin mahdollistaa sen), koska on mahdollista välttää siiloutumista, ja pääsy ja työvälineet ja hallinta ovat ensiluokkaisia. Pilvi tarjoaa loistavan alustan kokeilulle edukkaasti, investoimatta raskaaseen rautaan, ja sieltä saa resursseja nopeasti, nappia painamalla. Pilven skaalautuvuus on myös (hyvin tehdyille sovelluksille) lähes rajaton, ja vikasietoisuutta saa globaaleilla pilvillä ruuvattua todella erinomaiseksi. Juuri mitään näistä hyödyistä ei saa paikallisesta konesalista, ja siihen on monissa paikoin suorastaan totuttu.

Itse olen puljaillut AWS EC2 koneiden kanssa jo pitkiä aikoja, mutta oikeastaan vasta nykyisissä hommissa havahduin siihen, mitä muuta AWS tarjoaa. Kiitokset siitä Data Science-puolen väelle. Yksi ensimmäisiä hommiani Solitalla oli tukea Data Science projektia teknisessä mielessä, jossa haluttiin vertailla kalliin kaupallisen datan rouskutusvälineen kyvykkyyksiä open source pinoon. (Kallis kaupallinen veti kokonaiskustannuksiltaan liput kotiin mennen tullen tässä skenaariossa). Myös firman HipChat kanavalla huhuillaan aika ajoin kiinnostavia juttuja mm. Lambdoista ja Serverless-malleista, tai S3-website hostauksesta. Vanhana hardcore koodinvääntäjänä jolle aiemmin oli kunnia-asia tehdä kaikki työkalut itse, olen sittemmin kokenut tietynlaista tuottavaa laiskuutta, ja näin tällaiset ovat nykyään kiinnostavia huhuiluja, kun pyritään tekemään entistä enemmän entistä fiksummin.

Mitäs niitä serttejä löytyy?

No niin, joka tapauksessa, AWS pilvestä löytyy sertifiointeja joka lähtöön. Kovan ytimen muodostaa viisi sertifikaattia, joista kolme on perustasoa, ja kaksi on professional-tasoa. Jenkkien palkkavertailuissa jo perustason arkkitehtisertifikaatti oli arvostetuin ja paraspalkkaisin mitä sertifiointeihin tulee. Pro-tason arkkitehtisertifikaatti on jo käytännössä hyvän työpaikan tae, etenkin jos sen mukana tulee kykyä kommunikoida ja oikeasti ratkoa ongelmia. Näiden viiden päälle löytyy sitten erikoistumissertifikaatteja, mm. tietoturvasta, ja verkoista.

Sertifikaatit ovat vain monivalintakysymyksiä, ja niitä usein kritisoidaan. Ne eivät ole hyvä osaamisen ja soveltamisen mittari. Mutta samoin kuin aikanaan Java-sertifikaateissa, itse puolustan niitä silti. Koska jos on henkilö, joka on suorittanut tietyn sertifikaatin, se kertoo minulle, että hän on ainakin jossain vaiheessa hallinnut kokonaiskuvan teknologia-alustasta, yksityiskohtia myöden. Henkilö jolla ei sertifikaattia ole, voi osata jonkun nurkan erinomaisesti, toisen surkeasti, ja kolmatta ei ollenkaan. Hänestä en tiedä siis mitään.

Jos työhaastattelussa haastateltavalla on esittää sertifikaatti, se ei kerro että hän on loistava ohjelmoija, mutta antaa silti tietyn baseline-tason laadulle. Henkilö jolla ei sertifikaattia ole, vaatii huomattavasti pidempää tenttausta jos haluaa päästä osaamisesta selville. Projekteissa olen havainnut, että sertifioitumattomat henkilöt voivat olla suorastaan hasardeja: Tehdä enemmän vahinkoa kuin hyvää. Tämä johtuu siitä, että työkalupakki on, metaforaa käyttääkseni, vajavainen. Siellä voi olla yksi upea, kiiltävä vasara, mutta ei mitään muuta. Palkkaan mielummin työmaalle tyypin jolla on kulunut pakki jonka kaikkia perustyökaluja on käytetty tasapuolisesti. Häneltä löytyy hihasta vaihtoehtoja ja joustavuutta. Se kiiltävän vasaran kaveri etsii vain kaikkialta nauloja.

No liittyykö sertifikaatti sitten juuri tähän? Ei välttämättä, sama oire voi olla sertifioituneillakin. Mutta käytännnössä olen suuri fani sille että jos haluaa syvälle tekkiin, aloitetaan sertifikaatista, ja siitä alkaa opiskelu. Vähän kuin taistelulajeissa, musta vyö aloittaa varsinaisen oppimispolun – ei päätä sitä.

Vinkkejä

Vinkkejä opiskeluun? AWS sertifikaatit ovat huomattavasti vaikeampia kuin esim. SUN/Oracle Java-sertifikaatit, vaikka puitteet ovat suunnilleen samat. Perustason sertifikaateissa on yleensä n. 60 kysymystä, ja muutama tunti aikaa. Läpäisyyn piisaa 65-70% oikein. Mutta AWS on yhä vain laajempi kokonaisuus, palveluiden määrä lisääntyy koko ajan, tätäkin kirjoittaessa. Ja sertifiointikysymykset ovat todella yksityiskohtaisia, sieltä voi tulla esim. kysymyksiä koskien kapasiteettia, kaistaa, jne. Osa on onneksi ihan terveen järjen kysymyksiä, niistä selviää jos on oikeasti tehnyt jotain AWS konsolissa.

Mutta tässä pari vinkkiä:

  • Kaikkein tärkeintä on mock exam/testi-testit, että totut kysymyksien tyyppeihin, tapaan, ajoitukseen. Niitä löytyy jonkun verran ilmaisia, mutta parhaat maksavat jonkun verran. Amazonin kautta saa ’virallisen’ harjoitustestin, mutta itse löysin loistavia harjoitustehtäviä myös android-sovelluksista, joita voi mukavasti naputella tabletilla läpi vaikka työmatkalla
  • Valmistautumiseen tärkeintä on lukea AWS Whitepaperit ja FAQ lätyskät, ainakin tärkeimpien palveluiden osalta. Core palveluita ovat EC2, S3, VPC, RDS, ja DynamoDB, mutta niiden ohella yllättävät paljon tulee myös kysymyksiä myös esim. SNS, SQS ja SWF osista.
  • Ehdottomasti kannattaa investoida johonkin online-preppaukseen koskien sertifikaattia. Niitä saa alennus-aikaan muutamalla kympillä, itse käytin acloud.guru kursseja (jotka ovat itsessään tehty AWS Serverless+Lambda arkkitehtuurilla, kustannustehokkuussyistä)

Itse ajattelin jatkaa sertifioitumista tällä suunnalla, koska tämä on hyvin kiinnostava suunta, ja viimein antaa mukavan oppimishaasteen. Osa asioista on jo käytännön tasolla tuttuja, mutta osa ei. Bonuksena kakun päällä olen myös kiinnostunut AWS Alexa rajapinnoista, ja harrastepuolella olen jo niiden kanssa näperrellyt. Acloudguru sitella on tehty muuten Alexan päälle botti joka kyselee AWS sertifiointiin testikysymyksiä 😉

 

 

 

 

Mainokset

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… 😉

 

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

 

 

Kuolema nullpointerexceptioneille: Kotlin ftw!

Lomaillessa ja sairastaessa on hyvin aikaa leikkiä jollain jolle ei ole ollut kysyntää ns oikeissa, hiellä ja tuskalla väännetyissä Wakavissa Projekteissa. Tällä kertaa tutkaan osui Kotlin, johon on ollut tarkoitus perehtyä tilaisuuden tullen.

Kotlin on tuorein lisäys JVM-perheen kieliin; Eli kuten Scala, Clojure, ja Groovy, se on ihan oma erillinen kielensä, syntaksinsa, ja filosofiansa, mutta kun se menee kääntäjän läpi, putkesta ulos tulee Java-virtuaalikoneen bytecodea – vaatii tosin minimitasoksi Java 6 myllyn.

Ajonaikaiset virheet ohjelmissa ovat nykypäivän ohjelmistokehityksessä niitä kalleimpia virheitä – koska ne löytyvät vain kattavalla testauksella, voivat vaatia hyvinkin eksoottisia tiloja ja kombinaatioita ilmentyäkseen, ja mitä myöhemmin ne löytyvät, sitä enemmän ne maksavat. Esim. käyttöönottovaiheen jälkeen löytyvä bugi pitää ensin havaita, sitten raportoida, sitten toistaa, sitten ymmärtää, sitten korjata, sitten testata korjaus, ja testata ettei korjaus rikkonut mitään muualla, jne. Tästä kertyy ihan kohtuullisesti hintaa pienille asioille. Java-kielessä on alusta alkaen ilmennyt kahta eri virhettä yli kaiken muun: ClassCastException, sekä NullPointerException. Java 5 onnistui aikanaan hävittämään edellisen lähes sukupuuttoon Generics tyypitettyjen kokoelmien myötä. Mutta NullPointer on edelleen valitettavan yleinen virhe. Ja kun se paukahtaa, se usein valuu pinossa ylöspäin, ja voi ilmentyä hyvin mielikuvituksellisin tavoin – tai voi aiheuttaa seurauksia jotka näkyvät jossain aivan muualla myöhemmin. Eli pirullisia virheitä.

Nullpointereita on jahdattu eri tavoin. Olen itse opettanut ja kirjoitellut siitä miten Java-kielellä koodatessa voi tiedostaa tämän, ja koodata fiksusti. NullPointer paholainen iskee tyypillisemmin kun metodi palauttaa kokoelman sijasta null-arvon. Eli parempi filosofia on palauttaa aina ei-null arvo, esim. tyhjä. Jos jossain oikeasti tulee vastaan niin harvinainen tapaus, että null ja tyhjä ovat eri asia ja molemmat tarpeen palauttaa, niin se poikkeus on hyvä dokumentoida ja nimetä selkeästi, jotta kutsuja osaa käsitellä arvot oikein. Scala ja Groovy hoitavat nulleja omilla tavoillaan, mutta molemmat kielet edelleen sallivat null arvoja. Java 8 esitteli uuden Optional-tyypin, josta olen myös kirjaillut, ja se tuo vähän helpotusta ongelmiin oikein käytettynä – mutta ei sekään ongelmaa poista, ja mikään ei sitä pakota käyttämään.

Joten – long story short – Kotlin kielen mainostetuin uutuuspiirre on juurikin kuolema nullpointtereille, taas uudella ja tuoreella näkökulmalla. Mutta ei mennä asioiden edelle. Kotlin on syntaksiltaan ja toiminnaltaan eniten lähellä Scala-kieltä, ja Java-koodaajillekin tuttu.

fun main(args: Array<String>) {
  print("Kuolema NULLPOINTEREILLE!")
}

Jeah, puolipisteet valinnaisia, pääohjelman voi tehdä ilman luokkaa. Itse asiassa on myös mahdollista tehdä Kotlin scriptitiedosto, joka sisältää vain pääohjelman koodin:

print("Kuolema NULLPOINTEREILLE scriptissä!")

Kotlin käännetään kotlinc-kääntäjällä, joka voi suoraan paketoida java-kirjastot mukaan. Lopputuotos voi olla .class tiedostoja, tai suoraan ajettava .jar. Kotlin voi vapaasti importoida ja kutsua Java-kirjastoja, sekä JVM sisältä että mitä hyvänsä lisäkirjastoa mitä on tehty sitten vuoden 1995.

kotlinc app.kt -include-runtime -d app.jar

Miten Kotlin sitten auttaa nullpointerien kanssa? Kotlin ei salli normaalien tyyppien asettamista null-arvoon: kääntäjä estää sen. Esim. tyyppi String vaatii aina ei-null arvon. Jos haluat asettaa null-arvon, tyypin perään tulee kysymysmerkki merkiksi, esim. String?

var name:String?
var email:String
name = null
email = null // This line does not compile at all!
print("HELLO " + name + "!")
print("Your email is " + email)

Ylläolevassa koodiesimerkissä näet molemmat käytössä. Jos halutaan siis varata oikeus käyttää null-arvoja, se pitää näkyä jo alunperin tyyppimäärityksessä. On siis varsin mahdollista käyttää null-arvoja – mutta useimmiten ne ovat vain puhdasta laiskuutta. Useimmiten kun on mielijohde palauttaa null-arvo, onkin fiksumpaa palauttaa ns tyhjä arvo, esim. tyhjä String, tyhjä List, jne, tai heittää poikkeus. Niihin harvoihin tapauksiin kun null arvo on oikeasti kätevä, se on helppo ottaa käyttöön.

Mitä muuta jännää on Kotlinissa, verrattuna Java/Scala kieliin esim? Aika paljolti paletti molempien parhaita puolia. Primitiivityypit on poistettu: Kaikki ovat oliotyyppejä. Ei ns checked exceptions poikkeuksia, kaikki ovat nykymuodin mukaan runtime exception tyyppiä, eli käsitellään kun halutaan, ei ole pakko. Nykymuodin mukaan myös kielessä on paljon älykkyyttä ja päättelyä: esim. muuttuja/vakiotyyppiä ei tarvitse määrittää jos kääntäjä sen jo osaa päätellä arvon perusteella. Erikseen löytyy val ja var avainsanat immutable/mutable käyttöä varten. Tottakai lambda expressionit pelaavat mainiosti.

Kielestä on sitten vastaavasti jätetty pois monia piirteitä, joilla Java/Scala koodaajat ampuvat itseään lahjakkaasti jalkaan, esim. static avainsanat ja osat, implicit conversions, ja rohkaisu on ratkoa ongelmia siten että koodi pysyy luettavana ja selkeänä. Toisin kuin Scala, kieli on myös rakennettu modernin Java 8 pohjalle, eli on lähempänä nykysyntaksia mm. Lambdojen ja Stream käsittelyn osalta. Itse pidän myös esim. funktioparametrien oletusarvoista, ja mahdollisuudesta asettaa parametreille arvot nimen perusteella. Tämä vähentää tarpeetonta polymorfismia – toki kohtuudella käytettynä tämäkin, muuten polymorfisuus korvautuu modaalisuudella joka taas ei ole hyvä vaihtokauppa.

2016-06-10 13.13.59

Firman Flamingo hyväksyy Kotlinin

Kotlin on tosiaan melko tuore tulokas kentällä: JetBrains niminen paja lanseerasi sen vuonna 2011, vuonna 2012 se vapautettiin Apache lisenssillä open sourceksi, ja nyt vuonna 2016 siitä on julkaistu vakaaksi laskettava versio 1.0, vuoden alusta. Sen osuus on sen verran marginaalinen ettei vielä näy esim. TIOBE indeksissä, mutta se ei toki tarkoita etteikö sitä jo kentällä käytettäisi.

Kannattaisiko siis käyttää Kotlinia seuraavaan projektiin? Omalta puoleltani annan vahvan peukutuksen. Clojure uskovaiset tuskin kokevat halua kääntyä tänne, se on edelleen oma maailmansa. Java uskovaisten kannattaisi tehdä seuraava projekti ihan millä hyvänsä modernimmalla kielellä, Java on nykymuodossaan aika rasitettu ja päällelaastaroitu sekamelska, ja Scala, Clojure, ja Kotlin ovat kaikki huimia parannuksia siihen. Scala kielen pieni haitta on se että se oli kentällä aikaisin, ja nyt sen linjaus Java 8 mukaiseksi on vähän isompi operaatio. Scalassa on myös turhankin voimallisia tapoja ampua itseään jalkaan, jotka ovat Kotlinista tahallisesti poistettuja.

Kuten Scala, myös Kotlin on hyvä alusta jossa voit toteuttaa vapaasti haluamaasi yhdistelmää funktionaalista tai olio-ohjelmointityyliä. Voit esim. aloittaa iisisti perinteisemmällä Java oliokoodilla, ja hivuttaa itseäsi kohti korkeamman tason funktioita ja immutable, arvoja. Kotlin käyttöönotto on helppoa, ja sen voi perinteiseen tapaan aloittaa vaikkapa testipuolella. Kotlin toimii myös mukavasti esim. Spring Boot+REST alustana, ja sen saumaton yhteensopivuus olemassaolevien Java-kirjastojen kanssa tuo ratkaisua mm. tietokantojen kanssa pelaamiseen.

Itse ainakin käyttäisin. Rakastuin aikanaan Scalaan, ja Kotlin on Scalalle vähän samaa kuin Scala oli Javalle. Scala on edelleen paljonkin voimallisempi työkalu, ja kypsempi myös, mutta molemmat piirteet ovat kaksiteräisiä miekkoja. Ja Java-kieltä taas kukaan ei varmaan ihan ehdottoman innoissaan halua koodata. Sen paras argumentti lienee Cobol-mainen 20 vuoden tuoma maturiteetti, se on hyvä sveitsin armeijan linkkuveitsi siellä työkalupakin pohjalla. Ehkä sen olisi kielenä jo aika kuolla pois. Mutta toki maailmalta löytyy 10 miljoonaa enemmän tai vähemmän aktiivista koodaajaa jotka sitä ymmärtävät. Digitalisoinnin tarpeiden taas laajentuessa eksponentiaalisesti sekin on hyve.

 

Tuolta lisää:

https://kotlinlang.org/

 

Java 9 ja CORBA

Heh, niinpä. Olen kirjaillut aiemmin useammankin kerran tulevan Java 9:n ihmetyksen aiheista. Silmiin osui hauska artikkeli siitä miten viimeinkin CORBA, Common Object Request Broker, tuo kaikkien väylien ja hajautuksen edelläkävijä ja kaikkien sitä käyttäneiden inhokki, ei enää tule vakiovarusteena perus-Javassa.

Java 9 suuri uudistushan on modulaarisuus, ja sen tärkeimpänä osana ja ajurina Javan n. 20-megainen runtime modularisoidaan, siten että sieltä löytyy tiukka ydin-kernel, ja lukuisia moduuleita joita voi halunsa mukaan ottaa mukaan tai jättää ottamatta. Pitkän tähtäimen strategia on varmasti paluu mobiili ja IoT ympäristöihin uusin voimin.

Eli, oletuspaketti, root moduulit, ei sisällä enää tarpeetonta kuraa, ja osa tarpeellisistakin lähtee erilleen. Jos kaipaat CORBAA, saat sen takaisin kytkimellä:

-addmods java.corba

Hyvä huomata että vastaavia muita moduuleita ovat mm.:

java.activation
java.annotations.common
java.corba
java.transaction
java.xml.bind
java.xml.ws

Näyttäisi siis siltä että viimein Java menee tosissaan tiukalle dieetille. Java 9:stä kuulemme varmaan lisää tämän vuoden JavaOne seminaarissa San Franciscossa – mutta mielenkiintoa näyttäisi olevan. Varmaa on, että jatkossa on syytä opetella käyttämään moduulijärjestelmää ja sen kytkimiä – muuten ei vanhat Java-koodit enää edes käänny.

Toinen tutkaimiin osunut juttu on moneltakin taholta julistettu Java EE 8 kuolema. Oraclen panostus ja mielenkiinto sen suhteen näyttää olevan lopahtamassa. Mielenkiinnolla seuraan mitä tämä tarkoittaa, ja mitä tuo tullessaan. Tutkaimet herkkinä. Tämäkin selvinnee syksymmällä.

 

http://mail.openjdk.java.net/pipermail/jdk9-dev/2016-May/004309.html

 

Angular2 + NPM + Webpack

Lupailin kirjailla vähän lisää fiksusta Angular2 setupista tuotantohommiin. Tarkoitus oli tunkkailla minimaalinen paketti jossa on helppo erottaa eri tekniikoiden tehtävät. Valitettavasti Angular2 on aika liikkuva kohde tällä hetkellä – ja kiirettäkin on pitänyt, joten yksinkertainen POC projekti on jäänyt haaveeksi.

Onneksi joku muu on tehnyt sellaisen. Tällä hetkellä fiksuinta on aloittaa kokeilut ylläpidetystä Angular2 Webpack Starter projektista: https://github.com/AngularClass/angular2-webpack-starter

Valitettavasti tuo projekti ei ole yksinkertainen eikä siisti, mutta hoitaa homman. Ja se on kuitenkin hyvin linjassa sen kanssa mitä itse ajattelen. Angular2 kehittyy vauhdilla juuri nyt, ja joka releasen myötä se on siistimpi ja eheämpi ja vähemmän tarvitaan purkkaa taustalle. Sitä myöten voisin kuvitella että tämä webpack starterkin yksinkertaistuu.

Joka tapauksessa, vähän saatesanoja projektin suhteen. Senhän saa käyttöön nätisti kokeiluun (kun nodet on asennettuna), esim. näin:

 

git clone https://github.com/angularclass/angular2-webpack-starter.git
cd angular2-webpack-starter
npm install
npm start
curl http://localhost:3000

Curlin sijasta voit luonnollisesti tyypittää oikealla selaimella. Kuten kynäilin viimeksi, Bower on vähän menemässä muodista pois, samoin Grunt – paljon kuin sitä ja Gulpia rakastankin. Jos haluaa, voihan molempia noita käytellä vieläkin, ja voi olla joku tehtävä jossa Gulp voi olla esim. hyödyllinen. Mutta vanilla on päivän maku näissä asioissa, ja aikalailla paljon saa aikaan ihan vain puhtaalla JavaScriptillä ja NPM:llä.

Kannattaa luoda silmäys package.json tiedostoon. Se on tässä kaiken avain. Ja voi olla pelottava kokemus tässä vaiheessa jos on tottunut että se on vain kirjastomanifesti. Tosiaan devdependencies-lista on aika kattava näinkin yksinkertaiselle projektille, mutta tulee yksinkertaistumaan jatkossa. Ja toki siinä on jo aika kattavasti testaustyökaluja mukana. Pääjuju kuitenkin, että riippuvuudet on fiksuinta hakea kaikki npm keinoin, softan omat riippuvuudet ovat dependencies kohdassa, ja Boweria ei käytetä.

Mielenkiintoinen osio on kuitenkin scripts-osio. Vielä pari vuotta sitten oli tavanomaista että tämä oli tyhjä tai siinä oli 1-2 kohtaa, build ja test. Nyt tässä näkyy hyvin painopisteen muutos. Perinteiset grunt/gulp työvaiheet on nyt npm scripts työvaiheina, ja ne ovat modulaarisia ja ketjutettuja. Tarvittaessa käytetään noita dpm dev moduuleja, esim. rimraf poistaa tyylikkäästi tarvittavat hakemistopuut. Jos tuosta poimii muutaman mehukkaan ja keskeisen komennon niin ne ovat:

"clean": "npm cache clean && rimraf node_modules doc typings coverage dist"
"build:dev": "webpack --progress --profile --colors --display-error-details --display-cached"
"server:dev": "webpack-dev-server --progress --profile --colors --display-error-details --display-cached --content-base src/"

Näitä pääsee ajamaan komennolla npm run, esim.

npm run build:dev (ajaa kehitysversion buildin)

Samaan listaan on myös määritetty oikopolkuja yleisimpiin, esim:

"build": "npm run build:dev"
"server": "npm run server:dev"

Siinäpä nuo yleisimmät. Ja loput hoitaa webpack. Webpackillä on tässä kaksi keskeistä tehtävää: Tärkein on lähdekoodin prosessoiminen halutuksi paketiksi (sisältäen tarpeen mukaan babelifioinnit, minifioinnit, obfuskoinnit, jne), ja sen ohella myös sisäänrakennettu testiserveri on mukava. Konfiguraatiot käännöksiin löytyvät projektin juuresta, esim. tsconfig.json ja webpack.config.js. En pui niiden sisältöä tässä sen enempiä, mutta ne ovat aika selkeitä ja tehtäväänsä keskittyneitä. Ehkä hyvä mainita että toisin kuin Angularin omassa yksinkertaisessa tutoriaalissa, moduulijärjestelmänä SystemJS on korvattu CommonJS:llä.

Mitäpä muuta? Sain aiemman artikkelin suhteen vähän kommenttia/kysymystä tuosta Mavenin käytöstä. Itsehän tyypillisesti teen backendit Javalla/Spring Bootilla, ja frontend on vain osa kokonaisprojektia. Ja koska asiat on kiva pitää yksinkertaisena, samalla kun buildataan Mavenillä backend hyväksi, on mukava rusauttaa läpi myös frontend buildit. Käytän tähän tosiaan eirslett maven plugaria, joka voi yksinkertaisimmillaan näyttää tältä:

<plugin>
  <groupId>com.github.eirslett</groupId>
  <artifactId>frontend-maven-plugin</artifactId>
  <version>0.0.27</version>
  <executions>
    <execution>
      <id>install node and npm</id>
      <goals>
        <goal>install-node-and-npm</goal>
      </goals>
      <configuration>
        <nodeVersion>v5.5.0</nodeVersion>
        <npmVersion>3.3.12</npmVersion>
      </configuration>
    </execution>
    <execution>
      <id>npm install</id>
      <goals>
        <goal>npm</goal>
      </goals>
    </execution>
    <execution>
      <id>npm build</id>
      <goals>
        <goal>npm</goal>
      </goals>
      <configuration>
        <arguments>run build:prod</arguments>
      </configuration>
      <phase>compile</phase>
    </execution>
  </executions>
</plugin>

Käytännössä siis tuo tarkoittaa:

  • Varmista että node ja npm ovat asennettuna paikallisesti
  • Aja npm install
  • Aja npm run build:prod scripti – automaattisesti Mavenin Compile vaiheessa, eli samalla kuin backend kooditkin käännetään

Yksinkertaista. Webpack on konfiguroitu puskemaan prosessoidut .js tiedostot, html:t ja muut staattiset osat sopivaan kansioon, josta Mavenin paketointivaihe ne sitten nappaa mukaan .war pakettiin.

Huomaa että jos haluat ajaa Mavenin läpi muitakin npm taskeja, se onnistuu määrittämällä sopiva Maven property jonka voit komentoriviltä ylikirjoittaa, ja käyttämällä sitä tuon npm taskin konfiguraatiossa, esim. näin:

<execution>
  <id>npm build</id>
  <goals>
    <goal>npm</goal>
  </goals>
  <configuration>
    <arguments>${npm.argument}</arguments>
  </configuration>
  <phase>compile</phase>
</execution>

En kuitenkaan nykyisellään koe tälle erityistä tarvetta. Mavenin päätehtävä on varmistaa että riippumatta koneen varustuksesta paketti osaa buildata itsensä eheäksi itsenäisesti, oli sitten kyseessä Jenkins ympäristö tai uuden projektiin tulevan kehittäjän kone, tai vanhan devaajan uusi kone. Eli toiminta varmistetaan kaikissa olosuhteissa. Mutta noita muita npm käskyjä voi hyvin ajaa ohi mavenin esim. frontend-painotteisten kehittäjien toimesta, esim.watch on varsin hyödyllinen kun haluaa saada käyttöliittymäkehityksessä jatkuvaa palautetta. Siksi perusbuildi Mavenin kautta ajettuna usein riittää, ja oletuksena production buildi on tietysti hyvä.

Tässä mietteitä tällä kertaa. Matka vilkkaassa frontend maailmassa jatkuu….