Maven projekti JavaEE/ReactJS sovellukseen

Maven projekti JavaEE/ReactJS sovellukseen

Olen käyttänyt Maveniä kohtalaisen paljon Java projekteissa. Myös ReactJS on minulle hyvinkin tuttu viitekehys. Jonkin aikaa sitten tuli kuitenkin ensimmäistä kertaa eteen näiden kahden yhdistäminen Java EE projektissa. Ensi viikolla sattuu tulemaan eteen koulutus, jossa pääsen vastaavan projektirakenteen selittämään ja kouluttamaan. Tekniikoista ja työkaluista tärkeimmät:

  1. Java EE 7, erityisesti JAX-RS & JDBC
  2. Netbeans 8.1 (kyllä, on vanha)
  3. Maven 3.3.9
  4. Glassfish 4.1.1 palvelimena
  5. ReactJS ja Fetch (JAX-RS apin käyttämiseen)
  6. Node ja npm React-osuuden kääntämiseen
  7. Jest React-testien ajamiseen

Tätä kombinaatiota saa ihan vapaasti moittia. Olen itsekin sitä mieltä, että Spring Boot olisi tähän ollut luultavasti paljon miellyttävämpi, silloin Spring Boot, Spring MVC, Tomcat ja STS olisivat korvanneet listan neljä ensimmäistä kohtaa. Versionhallinta ja CI palvelin olisivat tietysti olleet ihan asiallisia, mutta kun olin ainoa koodari tässä projektissa pääsi jotenkin laiskuus iskemään.

Aina ei voi kuitenkaan vapaasti valita. Joten kokemukset toteutuneesta ympäristöstä. Projekti lähti, hämmästyttävää kyllä, ihan tyhjältä pöydältä liikkeelle, joten Netbeansin Maven Web Application projekti antoi sopivan pohjan. React-osuutta varten tein src/main/frontend hakemiston. Sinne aika pitkälle Create React App generoima pohjatoteutus. Seuraava vaihe olikin POMin muokkaaminen automatisoimaan React-osuuden kääntämiseksi staattiseksi versioksi, ja tuloksen lisääminen WARiin.

Tätä vaihettahan ei tehdä googlaamatta, joten aika pian oman virittelyn sijaan valinta osui Eirik Slettebergin tekemään frontend-maven-pluginiin. Dokumentaatiokin oli kohtalainen esimerkkeineen, joten muokkasin pom.xml:n soveltuvin osin sen perusteella. Koska olin päätynyt npm:n käyttöön, niin jätin pois gulpin, bowerin yms. asentamisen. Esimerkit käyttävät Karmaa testien ajamiseen, joten sen osan tein itse. Ensimmäistä kertaa buildia kokeillessa tuli todettua, että Netbeansin vanhan 8.1 version mukana tulee liian vanha versio Mavenista, joten konfiguroin Netbeansin käyttämään uudempaa Mavenia. Pluginin avulla onnistuu nyt mm.

  • Noden ja npm:n asentaminen lokaalisti (plugin oikeastaan vaatiikin lokaalin asentamisen)
  • Riippuvuuksien asentaminen, eli npm install ajaminen
  • React osuuden kääntäminen Webpackin bundlerilla
  • Testien ajaminen

Konfigurointi

Kuten mainitsin, niin pluginin dokumentaation esimerkit voi oikeastaan lähes sellaisenaan kopioida omaan pom.xml:n. Versio täytyy tietysti asettaa, viimeisin on tällä hetkellä 1.3. Testien ajaminen onnistuu komentoriviltä mukavasti npm test komennolla, mutta se käynnistää Watcherin, jonka käyttäminen Netbeansin konsolista ei onnistu. Watcherin käynnistämisen saa pois päältä kertomalla react test runnerille, että sitä ajetaan CI serverin kautta. Koska halusin Watcherin pois lähinnä vain Netbeansin alla, päädyin asettamaan tarvittavan ympäristömuuttujan POMmissa. Näin se osuus konfiguraatiosta muodostui seuraavan kaltaiseksi:

Kun Webpackin builder kääntää React-osuuden, niin käännöksen tulokset on mukava saada automaattisesti oikeaan paikkaan WARiin. Omasta mielestäni tämä onnistui helpoimmin muokkaamalla maven-war-plugin:in konfiguraatiota lisäämällä sinne webResources osa.

package.json-tiedostoa ei paljon tarvinnut muokata, se oli siis oikeastaan suoraan Create React App projektin pohjalta tehty. Oikeastaan vain polun muokkaaminen riitti, esimerkiksi projektille ReactFrontend seuraava lisäys saa Reactin käyttämään oikeita polkuja.

Varsinainen kehitys

Yksi kehitysympäristö olisi tietysti hieno, mutta luovuin siitä ajatuksesta aika pikaisesti. Netbeans ei ymmärrä JSX syntaksia, eikä ainakaan minun käyttämäni versio ymmärtänyt edes ES6 syntaksia. Näin koodin kirjoittamisessa ei Netbeansista ollut oikeastaan mitään apua, lähes päinvastoin kaikkine virheilmoituksineen. Ehkä tärkeämpi syy toisen välineen ottaminen rinnalle oli, että Maven projektin build ei todellakaan ole kaikkein nopein mm. kun koko React toteutus käännetään staattiseksi tuotantoversioksi sen yhteydessä. Päädyin siis tekemään React osuuden käyttäen Visual Codea, samalla pystyin helposti hyödyntämään Webpackin hotdeployta – eli jokainen muutos näkyy heti selaimessa. Visual Code myös integroi ESLintin nätisti mukaan, eli syntaksitarkistus tulee tehtyä automaagisesti. Coden miellyttävä piirre tällaisessa toteutuksessa on myös sen käyttäminen ikään kuin vain editorina ilman omaa projektikäsitystä, joten pystyin muokkaamaan tiedostoja niiden varsinaisessa sijainnissa ilman juurikaan ylimääräisiä tiedostoja.

Netbeans jäi näin ollen vain Java-osuuden, eli backendin REST palvelun toteuttamiseen. Siinä se toimii erittäin hyvin. React-osuuden lisääminen buildiin ei kuitenkaan harmittanut, tai ollut edes turhaa työtä, sillä loppujen lopuksihan se kuuluu lopputulokseen ja tulee mukaan WARiin. Tässä tietysti ehkä hyvä mainita, että Glassfishin kyseisessä versiossa on tunnettu bugi, joka sitten tietysta katsoa taas vaihteeksi kuntoon. Eli JAX-RS ei onnistu tuuppaamaan JSONia ulos ennen kuin sen korjaa, esimerkiksi lisäämällä Jacksonin jar-tiedosto käsin palvelimelle: https://java.net/jira/browse/GLASSFISH-21141

Loppusanat

Pienellä käsityöllä kaiken sai siis toimimaan, mutta minun täytyy tunnustaa, että aika pian kommentoin POMmista pois React-osuuden siksi aikaa kunnes REST toteutus oli jo oikeastaan valmis. Sen verran pitkään Webpackin builderin ajaminen vei aikaa. React osuudenhan tein muutenkin poissa Netbeansista. Kun package.jsoniin vielä lisäsi proxy-asetuksen niin kahden eri serverinkään ajaminen samaan aikaan kehitysaikana ei aiheuttanut ongelmia. Tällöinhän koodissa voi käyttää ihan samoja osoitteita kuin tuotantoversiossakin. Periaatteessa siis tein kahta eri projektia, jotka lopussa yhdistin enabloimalla pom.xml:stä frontend-maven-plugin osuuden. Mutta kuten aina hyvissä tarinoissa: loppu hyvin, kaikki hyvin.