First8 Java Consultancy https://www.first8.nl First8 is gespecialiseerd in het pragmatisch ontwikkelen van bedrijfskritische Java toepassingen. Wed, 07 Jun 2017 09:21:24 +0000 nl hourly 1 https://wordpress.org/?v=4.8 First8Friday Editie 6 2017 – Devoxx4Kids Nijmegen https://www.first8.nl/first8friday/first8friday-editie-6-2017-devoxx4kids-nijmegen/ Fri, 02 Jun 2017 06:39:46 +0000 https://www.first8.nl/?p=5757 Welkom bij de First8Friday van juni 2017, je terugkerende dosis Open Source inspiratie die we elke eerste vrijdag van de maand met je delen. In deze videoblog blikt Linda Elbersen terug op Devoxx4Kids, gehouden op zaterdag 22 april bij First8 in Nijmegen.  

Het bericht First8Friday Editie 6 2017 – Devoxx4Kids Nijmegen verscheen eerst op First8 Java Consultancy.

]]>
Welkom bij de First8Friday van juni 2017, je terugkerende dosis Open Source inspiratie die we elke eerste vrijdag van de maand met je delen. In deze videoblog blikt Linda Elbersen terug op Devoxx4Kids, gehouden op zaterdag 22 april bij First8 in Nijmegen.

 

First8Friday_logo

 

Het bericht First8Friday Editie 6 2017 – Devoxx4Kids Nijmegen verscheen eerst op First8 Java Consultancy.

]]>
Gr8Conf, de Gr8test Groovy conferentie https://www.first8.nl/nieuws/gr8conf-de-gr8test-groovy-conferentie/ Fri, 02 Jun 2017 04:54:18 +0000 https://www.first8.nl/?p=5783 Met een groep van 5 First8-ers zitten we deze week op Gr8Conf, de grootste conferentie in Europa op het gebied van onze dierbare Groovy technologie. In Kopenhagen, de stad van de Deense Groovy rockstar Soren Berg Glasius (oprichter van de wereldwijde Gr8Conf conferenties). In de prachtige ICT universiteit van Kopenhagen wordt jaarlijks het auditorium afgehuurd voor Gr8Conf. Grote zalen, geweldig … Lees verder Gr8Conf, de Gr8test Groovy conferentie

Het bericht Gr8Conf, de Gr8test Groovy conferentie verscheen eerst op First8 Java Consultancy.

]]>
Met een groep van 5 First8-ers zitten we deze week op Gr8Conf, de grootste conferentie in Europa op het gebied van onze dierbare Groovy technologie. In Kopenhagen, de stad van de Deense Groovy rockstar Soren Berg Glasius (oprichter van de wereldwijde Gr8Conf conferenties). In de prachtige ICT universiteit van Kopenhagen wordt jaarlijks het auditorium afgehuurd voor Gr8Conf. Grote zalen, geweldig internet en altijd electriciteit in de buurt: want de echte Groovy developer codeert gewoon mee tijdens de sessies!

Op Gr8Conf faciliteerde ik namens First8 een Groovy codeerwedstrijd, net als bij de Spaanse Greach conferentie in maart (zie deze blog voor een terugblik). Dit ging goed en we werden na afloop uitgenodigd op een developers conferentie in 2018. Ook gaaf is dat ons competitie-framework steeds verder groeit qua nuttige features. Zo is het maken van puzzels enorm vereenvoudigd: leuk om met collega’s wat mee te gaan doen! De conferentie gaf Ted en mij ook veel materiaal voor de aanstaande Groovy university bij First8 (op dinsdagavond 20 juni). De awesomeness van Groovy kunnen we dan extra benadrukken en ook hoe je als Java development team het makkelijkste kunt upgraden naar Groovy.

Dr. Paul King in actie: wat maakt Groovy krachtig?

De conferentie is voor ons allen ontzettend leerzaam geweest. Dagelijks optrekken met vele Groovy rockstars maakt dat je zelf makkelijker je grenzen verlegt. Na bijvoorbeeld een avondje bier drinken met de Australiër Dr. Paul King, een van de grondleggers van Groovy, wist ik handige details van de laatste releases. Hij deelde tevens visie over zijn favoriete mogelijkheden van Groovy. Grooviness kun je overal gebruiken in je development stack: van DevOps tot Testing, van Css tot Concurrency. Dit laatste onderwerp werd trouwens besproken door Dr. Venkat, een van de bekendste sprekers in de Java community en een groot voorstander van de Groovy taal.

De leukste sessie van de conferentie is wat velen betreft de Groovy puzzlers sessie. De puzzlers sessies zijn inmiddels een traditie op Groovy conferenties. Alle deelnemers krijgen ludieke Groovy puzzels voorgelegd en moeten het goede antwoord raden. Diegene die het antwoord weet en het goed kan uitleggen, wint een shirt van El Groovisimo (de Mexicaanse Java champion Andres Almiray). Hieronder een voorbeeldpuzzel, de functie call “hello 09” levert “Gr8Conf 2017” op (iets wat niemand verwachtte). De runtime code die dit veroorzaakt staat eronder ( de oplossing: 09 wordt gezien als 2 getallen en alleen de eerste wordt gebruikt in de functie hello).

Zo, blog klaar en de dag begint: straks weer met de groep van First8 gezellig ontbijten en weldra beginnen we dan aan de laatste dag op de conferentie, een dag geheel in het teken van DevOps (zie programma). More Groovy Gr8ness!     

Voorbeeld puzzel: “hello 09” wordt “GR8Conf 2017” (Groovy denkt mee)

Het bericht Gr8Conf, de Gr8test Groovy conferentie verscheen eerst op First8 Java Consultancy.

]]>
First8Friday Editie 5 2017 – OWASP Top 10 https://www.first8.nl/first8friday/first8friday-editie-5-2017-owasp-top-10/ Fri, 05 May 2017 06:37:12 +0000 https://www.first8.nl/?p=5745 Welkom bij de First8Friday van mei 2017, je terugkerende dosis Open Source inspiratie die we elke eerste vrijdag van de maand met je delen. In deze videoblog neemt Arjan Gelderblom de nieuwe OWASP Top 10 met je door.    

Het bericht First8Friday Editie 5 2017 – OWASP Top 10 verscheen eerst op First8 Java Consultancy.

]]>
Welkom bij de First8Friday van mei 2017, je terugkerende dosis Open Source inspiratie die we elke eerste vrijdag van de maand met je delen. In deze videoblog neemt Arjan Gelderblom de nieuwe OWASP Top 10 met je door.

 

First8Friday_logo

 

 

Het bericht First8Friday Editie 5 2017 – OWASP Top 10 verscheen eerst op First8 Java Consultancy.

]]>
Wat een enthousiasme bij Devoxx4Kids in Nijmegen https://www.first8.nl/nieuws/wat-een-enthousiasme-bij-devoxx4kids-in-nijmegen/ Tue, 25 Apr 2017 13:21:20 +0000 https://www.first8.nl/?p=5728 Afgelopen zaterdag 22 april werd bij First8 in Nijmegen weer een uitverkochte editie van Devoxx4Kids Oost-Nederland gehouden. Veertig kinderen in de leeftijd van 10 tot 14 jaar leerden in drie verschillende workshops spelenderwijs kennismaken met programmeren. Bij binnenkomst kregen ze allemaal een leuk t-shirt als herinnering en een USB-stick met daarop de opdrachten, ze kunnen thuis verder programmeren. De kinderen … Lees verder Wat een enthousiasme bij Devoxx4Kids in Nijmegen

Het bericht Wat een enthousiasme bij Devoxx4Kids in Nijmegen verscheen eerst op First8 Java Consultancy.

]]>
Afgelopen zaterdag 22 april werd bij First8 in Nijmegen weer een uitverkochte editie van Devoxx4Kids Oost-Nederland gehouden. Veertig kinderen in de leeftijd van 10 tot 14 jaar leerden in drie verschillende workshops spelenderwijs kennismaken met programmeren.

Bij binnenkomst kregen ze allemaal een leuk t-shirt als herinnering en een USB-stick met daarop de opdrachten, ze kunnen thuis verder programmeren. De kinderen werden in twee groepen verdeeld en in tweetallen zijn ze om 10.00 uur aan de slag gegaan met Minecraft, LEGO Mindstorms en Scratch. Per workshop waren er diverse opdrachten en uiteraard waren er een paar bonusopdrachten.  

Vanaf 16.30 uur is er aan de ouders gepresenteerd en gedemonstreerd wat hun kinderen hadden geleerd. Zij waren onder de indruk van de resultaten. “Mijn dochter heeft een toffe dag gehad, ze vond met name Scratch heel leuk om te doen en kon niet wachten om ons thuis een demonstratie te geven”.

Wat een mooi gezicht om al die enthousiaste kinderen bezig te doen, de een nog fanatieker dan de andere! Ook wij hebben, net als de kinderen, genoten van deze dag.

De foto’s zijn gemaakt door Tamara Siebes van Kraft Media. Op zaterdag 14 oktober organiseren we weer een nieuwe Devoxx4Kids dag in Nieuwegein.

« 1 van 3 »

Het bericht Wat een enthousiasme bij Devoxx4Kids in Nijmegen verscheen eerst op First8 Java Consultancy.

]]>
Open Tech Day 2017 – Continuous Security https://www.first8.nl/blog/open-tech-day-2017-continuous-security/ Mon, 24 Apr 2017 18:08:06 +0000 https://www.first8.nl/?p=5713 Afgelopen donderdag 20 april vond de allereerste editie van Open Tech Day plaats. Ruim 700 professionals hebben dit event bezocht en onze collega Arjan Gelderblom heeft voor een volle Expedit zaal een presentatie gehouden over Continuous Security. We hebben veel enthousiaste reacties ontvangen, ook met de vraag of we de presentatie willen delen, uiteraard. Bekijk hieronder de presentatie. Continuous Security – Arjan Gelderblom  … Lees verder Open Tech Day 2017 – Continuous Security

Het bericht Open Tech Day 2017 – Continuous Security verscheen eerst op First8 Java Consultancy.

]]>
Afgelopen donderdag 20 april vond de allereerste editie van Open Tech Day plaats. Ruim 700 professionals hebben dit event bezocht en onze collega Arjan Gelderblom heeft voor een volle Expedit zaal een presentatie gehouden over Continuous Security. We hebben veel enthousiaste reacties ontvangen, ook met de vraag of we de presentatie willen delen, uiteraard. Bekijk hieronder de presentatie.

Continuous Security – Arjan Gelderblom 
In today’s fast and ‘ continuous development’ – cycle security is forced, but most of the time failing, to keep up with this pace. Security is almost all the time implemented as “hurdle” after releasing which needs to be taken before we can go to production. Being included after the fact means that you have to catch up on design and implementation before you can test for security related issues. By integrating security in the CI/CD pipeline and in our daily work flow it will be involved throughout the whole life cycle of the development of a feature and thus security can and will be involved from inception of a feature.

Heb je vragen of wil je over dit onderwerp van gedachten wisselen? Neem dan contact met ons op via l.elbersen@first8.nl of a.gelderblom@first8.nl.

Het bericht Open Tech Day 2017 – Continuous Security verscheen eerst op First8 Java Consultancy.

]]>
devcon 2017 https://www.first8.nl/blog/devcon-2017/ Tue, 11 Apr 2017 12:23:18 +0000 https://www.first8.nl/?p=5674      Afgelopen donderdag (6 april) ben ik naar devcon geweest. Dit is een jaarlijkse conferentie georganiseerd door Luminis en is voor en door (Luminis) developers gemaakt. Het is een jaarlijkse conferentie die wordt gehouden in de CineMec bioscoop in Ede. De focus bij deze conferentie ligt op vakmanschap en het delen van kennis. Nadat de conferentie officieel geopend was, … Lees verder devcon 2017

Het bericht devcon 2017 verscheen eerst op First8 Java Consultancy.

]]>
 

opening devcon, vlak voor aanvang
opening devcon, vlak voor aanvang

  

Afgelopen donderdag (6 april) ben ik naar devcon geweest. Dit is een jaarlijkse conferentie georganiseerd door Luminis en is voor en door (Luminis) developers gemaakt. Het is een jaarlijkse conferentie die wordt gehouden in de CineMec bioscoop in Ede. De focus bij deze conferentie ligt op vakmanschap en het delen van kennis.

Opening devcon door Bert Ertman
Opening devcon door Bert Ertman


Nadat de conferentie officieel geopend was, was het tijd voor de eerste keynote: AI or Death, Redefining what it means to be human in the age of software van Alix Rübsaam. Zij gaf een filosofische kijk op Artificial Intelligence vanuit het perspectief van humanisme.

"Visions of technology reflect the time and space where they originate" by Genevieve Bell & Paul Pourish, Divining a digital future, p. 17
AI or Death

 

Vervolgens ben ik naar The story map – new dimensions to your product backlog van Walter Treur geweest. Dit ging over wat een story map is, dat een story map gebruikersperspectief/context toevoegt aan je project, hoe je een story map kunt toepassen binnen je project (voor zowel kleine projecten, grote projecten als legacy projecten) en hoe het zich verhoudt tot een product backlog.

In Digital security for engineers heeft Angelo van der Sijpt een aantal security breaches die de afgelopen tijd in het nieuws zijn geweest belicht en hierover zijn visie gegeven over hoe goed of slecht de verschillende voorvallen door de verantwoordelijken zijn opgepakt. Hij gaf vooral ook aan dat digitale beveiliging iedereens verantwoordelijkheid is. Aan de hand van de ISO-standaard en voorbeelden heeft hij de begrippen attack, threat, control en risk uitgelegd. Aan het einde heeft hij nog een aantal tools aangereikt die je kunnen helpen, zoals FireEye en Splunk.

Na de lunch was het tijd voor de tweede keynote IoT and the web of systems door Jens Wellmann. Hij begon zijn praatje in het Duits totdat de dagvoorzitter hem onderbrak en vroeg te vervolgen in het Engels (of Nederlands), waarna het praatje in het Nederlands verder ging met allerlei grappen. Dit was een nepspeech van Pieter de Rijk (een komiek). Hij heeft het erg overtuigend gebracht en de humor na de lunch is een prima invulling voor wat normaal gesproken de ‘graveyard slot’ genoemd wordt.

Angela Lengkeek vertelde in HTTP/2 – What’s in it for you de belangrijkste verbeteringen in HTTP 2.0 t.o.v. HTTP 1.1. Hierbij moet je denken aan:

    • Multiplexing
    • Binair protocol
    • Header-compressie
    • Server push
    • Stream prioritering

Tevens heeft ze ook als tip meegegeven om bij HTTP 2 geen gebruik meer te maken van inline resources en alles JavaScript, CSS, afbeeldingen, enz. in losse bestanden te zetten. Dit heeft er mee te maken dat wanneer er iets wijzigt in één van de bestanden alleen van dat bestand een nieuwe versie hoeft te worden opgevraagd, i.p.v. de gehele inhoud.

Verder heeft ze laten zien met de chrome ontwikkelaarstools wat het verschil is in het laden van webpagina’s via HTTP 1 & HTTP 2.

Modules or Microservices ging erover of je modules of microservices moet gebruiken. Zijn antwoord was meteen ‘het hangt ervan af’. In deze presentatie zette Sander Mak zijn mening uiteen over dat dit een OR en geen XOR is. In zijn ogen wordt er te veel gefocust op de lange termijn winst die microservices opleveren en vergeten dat deze een hoge ‘cost’ aan het begin hebben. Voor modules geldt dat ze tevens winst opleveren voor de lange termijn en de kosten aan het begin zijn hiervan veel lager, zoals op onderstaande foto te zien is (uit de presentatie van Sander Mak). Zijn conclusie was dat voor producten op een schaal van bijvoorbeeld Netflix het zeker nut heeft om met microservices te werken en dat voor producten op een wat kleinere schaal (wat voor de meeste ontwikkelaars het geval is) je beter voor modules kunt kiezen.

Monolith vs. modules vs. microservices
Monolith vs. modules vs. microservices

 

Tot besluit

Al met al vond ik het een erg leerzame en inspirerende dag en heb ik weer nieuwe dingen om mee aan de slag te gaan.

 

Het bericht devcon 2017 verscheen eerst op First8 Java Consultancy.

]]>
First8Friday editie 4 2017 – Ansible https://www.first8.nl/first8friday/first8friday-editie-4-2017-ansible/ Fri, 07 Apr 2017 07:21:48 +0000 https://www.first8.nl/?p=5642 Welkom bij de First8Friday van april 2017, je terugkerende dosis Open Source inspiratie die we elke eerste vrijdag van de maand met je delen. Deze videoblog gaat over Ansible. Ansible is een ‘Configuration Management Tool’ waarmee je geautomatiseerd je infrastructuur kunt uitrollen.       Wil je meer weten over Ansible? Op dinsdag 30 mei organiseren we een First8University over dit onderwerp.

Het bericht First8Friday editie 4 2017 – Ansible verscheen eerst op First8 Java Consultancy.

]]>
Welkom bij de First8Friday van april 2017, je terugkerende dosis Open Source inspiratie die we elke eerste vrijdag van de maand met je delen. Deze videoblog gaat over Ansible. Ansible is een ‘Configuration Management Tool’ waarmee je geautomatiseerd je infrastructuur kunt uitrollen.

 

 

First8Friday_logo

 

 

Wil je meer weten over Ansible? Op dinsdag 30 mei organiseren we een First8University over dit onderwerp.

Het bericht First8Friday editie 4 2017 – Ansible verscheen eerst op First8 Java Consultancy.

]]>
Groovy power op de Greach conferentie https://www.first8.nl/blog/groovy-en-grails-in-madrid/ Wed, 05 Apr 2017 09:13:59 +0000 https://www.first8.nl/?p=5647 Begin april waren Ted Vinke en ik (Koen Aben) op de Spaanse conferentie Greach, om onze open source software te presenteren. Greach is de jaarlijkse conferentie in Madrid voor de Groovy community. De Groovy community is een actieve, internationale community met conferenties over de hele wereld om elkaar te ontmoeten. Vorig jaar waren we ook al naar de Greach conferentie … Lees verder Groovy power op de Greach conferentie

Het bericht Groovy power op de Greach conferentie verscheen eerst op First8 Java Consultancy.

]]>
Begin april waren Ted Vinke en ik (Koen Aben) op de Spaanse conferentie Greach, om onze open source software te presenteren. Greach is de jaarlijkse conferentie in Madrid voor de Groovy community. De Groovy community is een actieve, internationale community met conferenties over de hele wereld om elkaar te ontmoeten. Vorig jaar waren we ook al naar de Greach conferentie geweest (zie blog van vorig jaar). Omdat we dit jaar als sprekers gingen leerden we de Groovy community nog beter kennen, via bv het speakers diner en informele gesprekken. We hebben uiteraard ook veel verdiept in de Groovy techniek.   

Wat is Groovy ook alweer? Waarom is het gaaf? 

Groovy is een JVM taal sinds 2003, om het ontwikkelen van Java applicaties veel leuker te maken (“gaaf” vertaalt in het Engels naar “Groovy”). Groovy maakt Java development vlotter en krachtiger (o.a. minder overbodige code, minder strenge regels en meer ondersteunende features). Groovy heeft een groeiend ecosysteem aan frameworks (zoals Ratpack, Grails en GORM) en dat biedt dus de ontwikkelaar houvast om te ontwikkelen tot een full-stack developer. De laatste jaren neemt in de DevOps wereld het gebruik van de taal Groovy toe, dankzij bijvoorbeeld adoptie door build tools als Gradle en Jenkins. Groovy is een Apache project, met vele actieve committers.

Erg belangrijke ontwikkelingen op deze Groovy conferentie bleken de uitbreidingen van het ecosysteem, met name GORM (zie materiaal uit de keynote van Graeme Rocher).

Graeme Rocher in actie tijdens de keynote

Grails founder Graeme Rocher in actie tijdens de keynote

Onze sessie zelf was een korte game quiz met Groovy puzzels. De sessie was een succes: onze software blijkt goed te gebruiken voor korte coding battles tijdens conferenties. De Masters Of Java software uit 2004, welke de NLJug gebruikte voor hun jaarlijkse competitie, hebben we uitgebreid met moderne Java tools (zoals Maven, SpringBoot, FreeMarker en Groovy). Zo hebben we met Groovy een Ferrari motor ingebouwd, in het oude legacy product! Met de nieuwe software konden we op Greach een coding battle faciliteren van Groovy puzzels. Onze sessie was in de vroege ochtend na de conferentie party en de opkomst viel dus wat tegen. Echter, de deelnemers hadden wel veel plezier met de opdrachten en na afloop zei de organisatie dat we volgend jaar een uitgebreidere coding battle kunnen houden. Hieronder een actie foto:

In actie tijdens onze sessie “the Masters of Groovy Challenge”

Vooruitblik

Al met al een goede voorbereiding op onze First8 Groovy University op 13 juni (voor de Nederlandse Java User Group). We hebben beiden veel geleerd in Madrid: teruggekomen in Nederland gaan we weer actief klussen met leuke open source Groovy projecten. We kijken al genietend vooruit naar onze volgende Groovy conferentie in Denemarken in mei, waar we met een team van 5 First8-ers naartoe gaan! 

Na afloop van de Greach conferentie zijn Ted en ik naar het stadspark van Madrid gegaan om te relaxen. Daar hebben we deze ludieke Groovy blog opgenomen: we bespreken hierin enkele hoogtepunten van de conferentie!

 

Het bericht Groovy power op de Greach conferentie verscheen eerst op First8 Java Consultancy.

]]>
Grails Anti-Pattern: Everything is a Service https://www.first8.nl/blog/grails-anti-pattern-everything-is-a-service/ https://www.first8.nl/blog/grails-anti-pattern-everything-is-a-service/#respond Tue, 04 Apr 2017 07:55:42 +0000 https://www.first8.nl/?p=5635 The context Grails makes it very easy to put any logic of your application in a service. Just grails create-service and you’re good to go. There’s a single instance by default, injectable anywhere. Powerful stuff and makes it easy to get up ’n running very fast! Creating a new application, following so-called “best practices” from blogs like these 🙂 and … Lees verder Grails Anti-Pattern: Everything is a Service

Het bericht Grails Anti-Pattern: Everything is a Service verscheen eerst op First8 Java Consultancy.

]]>
The context

Grails makes it very easy to put any logic of your application in a service. Just grails create-service and you’re good to go. There’s a single instance by default, injectable anywhere. Powerful stuff and makes it easy to get up ’n running very fast!

Creating a new application, following so-called “best practices” from blogs like these 🙂 and the ‘idiomatic Grails-way’ described in the docs and in tutorials work in the beginning, but there’s always a tipping point — where the application has grown a reasonable size — where one should start following a different, maybe less-Grailsey, strategy.

So what can go wrong by creating services in your application?

In a previous anti-pattern post about dynamic finders I tried to explain what could happen from Day 1 of your project onwards.

A team really took this advice to heart and started centralising their Album queries in a AlbumService, their Product queries in a ProductService and so on.

Here’s what I saw happening.

Sprint 1: Life is beautiful

This team started out really sharp: they almost were implementing business-like logic in controllers, but could pull those into services just in time. The grails create-service command would even immediately create an empty unit test — ready to implement.

The productivity was unparalleled. The team never had to manually create a class anymore with their IDEs and for the next sprints the team burned through the backlog like a hot knife through the butter.

Fast-forward 6 sprints.

Sprint 6

Looking at their code, it seems their services folder consists of a dozens of classes:

grails-app/services/
└── example
    ├── AnotherProductService.groovy
    ├── ...
    ├── OrderService.groovy
    ├── OrderingService.groovy
    ├── ...
    ├── Product2Service.groovy
    ├── ProductAccountingService.groovy
    ├── ProductBuilderService.groovy
    ├── ProductCatalogService.groovy
    ├── ProductCreateService.groovy
    ├── ProductFinderService.groovy
    ├── ProductLineFileConverterDoodleService.groovy
    ├── ProductLineMakerService.groovy
    ├── ProductLineReaderService.groovy
    ├── ProductLineService.groovy
    ├── ProductLineTaglibHelperService.groovy
    ├── ProductLineUtilService.groovy
    ├── ProductManagementService.groovy
    ├── ProductManagerService.groovy
    ├── ProductMapperService.groovy
    ├── ProductOrderService.groovy
    ├── ProductReadService.groovy
    ├── ProductSaverService.groovy
    ├── ProductService.groovy
    ├── ProductTemplateOrderBuilderService.groovy
    ├── ProductUtilService.groovy
    ├── ProductWriterService.groovy
    ├── ProductsReadService.groovy
    ├── ProductsService.groovy
    └── ...
1 directory, 532 files

The pattern

This happened to me a gazillion times before. Me and the team value the simplicitly and power of Grails. Hence, it’s pretty easy to start using the Grails commands to the fullest, such as all the create-* commands:

grails> create-
create-command                create-controller             
create-domain-class           create-functional-test        
create-integration-test       create-interceptor            
create-scaffold-controller    create-script                 
create-service                create-taglib                 
create-unit-test

In many Grails projects, similar to the fictional one 🙂 above, the create-service command has been over-used, because it seems to be idiomatic way of creating “business logic in the service layer”.

Yes, this command does create a nice, empty unit test, and is automatically a handy Spring bean injectable in controllers, tag libraries and other Grails artefacts.

Yes, using a *Service works well in blog posts, demo’s and tutorials.

However, it seems that we have forgotten basically everything is a “service” to someone else, but that we do not necessarily need to postfix (“Service”) every class as such.

Seems that people usually understand when something needs to be a controller (“let’s do create-controller“) or a tag library (“let’s do create-taglib“) and so forth, and for everything else: boom!, “let’s do create-service“.

In any other, non-Grails project we’re used to calling a builder simply “PersonBuilder”, in Grails projects it’s suddenly “PersonBuilderService”. In any other project a factory is a “PersonFactory”, in a Grails project it’s a weird “PersonFactoryService”.

What if a “PersonReadService” is responsible for getting or finding persons? For years people having been using the Repository pattern for this and this can be reflected with a “Repository” postfix, e.g. “PersonRepository”.

Even in Grails a builder can be a Builder, a factory a Factory, a mapper a Mapper, a repository a Repository, a doodle a Doodle and whatever can end in Whatever — you can name every class the way you want.

What we can we do about it?

Stop calling everything a Service

First, next time you’re about to create a class following one of the Famous Design Patterns, such as Builder, Factory, Strategy, Template, Adapter, Decorator (see sourcemaking.com for a nice overview), or other “well-known” Java (EE) patterns, such as Producer or Mapper or something, ask yourself a question:

Can it be a regular class in src/main/groovy?

Move and choose a better name

  • Yes, then just create the class in src/main/groovy. Maybe choose a nice package, such as example. If you don’t want 532 classes in one package, you can always introduce sub-packages such as example.accounting. Give it a name which does not end in *Service. Don’t forget to manually add an associated *Spec in src\test\groovy.

Do you still want to have the benefit of Spring and Dependency Injection?

In other words, do you need an instance of your class to be able to be injected into any Grails classes, such as a controller, as you are used to with a service, like the ProductReadService below?

// grails-app/controllers/example/HomepageController.groovy
class HomepageController {
    ProductReadService productReadService

    def index() { ... }
}

// grails-app/services/example/ProductReadService.groovy
class ProductReadService {
    SecurityService securityService

    Product findByName(String name) {
        assert securityService.isLoggedIn()
        Product.findByName(name)
    }
}

The underlying container is created by the Spring Framework.

  • There’s a great chapter in the docs about Grails and Spring. It’s this framework that will instantiate for example one SecurityService in the application, inject it in the “securityService” property when it creates one instance of ProductReadService which it injects in the HomepageController and so forth.

  • The SecurityService in the example — which might come from a Security plugin and the *Service classes in your own application sources – they’re all automatically picked up and managed by the Spring container and injected in every other managed class that needs it.

  • It’s not so much the move of grails-app/services/example to the src/main/groovy/example folder, but by renaming a class to something which doesn’t end in “Service” anymore, that’s when you lose the automatic management by Spring. This happens when we, as suggested, after the move, rename the class ProductReadService to a ProductRepository class.

Yes, it want them to be a Spring bean!

Declaring Spring beans the Grails way

Sure, we can do this ourselves. The Grails idomatic way is to specify beans in resources.groovy.

// grails-app/conf/spring/resources.groovy
import example.*
beans = {
    productRepository(ProductRepository) {
        securityService = ref('securityService')
    }
}

We’ve defined a a bean named “productRepository” of class ProductRepository and we’ve indicated the SecurityService needs to be injected.

This is how the original code has changed, but the behaviour has not: it’s now using ProductRepository instead.

// grails-app/controllers/example/HomepageController.groovy
class HomepageController {
    ProductRepository productRepository

    def index() { ... }
}

// src/main/groovy/example/ProductRepository.groovy
class ProductRepository {
    SecurityService securityService

    Product findByName(String name) {
        assert securityService.isLoggedIn()
        Person.findByName(name)
    }
}

This is not the only way to declare Spring beans.

Declaring Spring beans the Spring way

We declared Spring beans the Grails way, but we can also declare beans the Spring way.

Ok, there’s not just “a Spring way”, there are many ways, from the old XML declarations, classpath scanning to Java-style configuration.

Having (a subset of) your 532 classes in resources.groovy might be considered not all that better than the XML configuration Spring used in the early days.

Even through the Beans DSL is a lot more powerful here than XML ever was (because: Groovy), we’re not transitioning our automatically picked up service beans to get manual labour back, in my opinion. 😉

This is how it would look:

beans = {
    anotherProductRepository(AnotherProductRepository) {
        securityService = ref('securityService')
        orderingService = ref('orderingService')
    }
    productLineReader(ProductLineReader)
    productFinder(ProductFinder) {
        productRepository = ref('productRepository')
        productLineService = ref('productLineService')
    }
    productRepository(ProductRepository) {
        securityService = ref('securityService')
        productReader = ref('productReader')
        productWriter = ref('productWriter')
    }
    orderingService(OrderingService) {
        securityService = ref('securityService')
        productRepository = ref('productRepository')
    }
    ...

There are use cases where resources.groovy is perfectly fine, but why not get rid of the boiler-plate and leverage the modern features of Spring at our disposal?

Try component scanning instead.

  • Just once, set Spring’s @ComponentScan annotation our Application.groovy class

// grails-app/init/example/Application.groovy
package example

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.context.annotation.ComponentScan

@ComponentScan
class Application extends GrailsAutoConfiguration {
    static void main(String[] args) {
        GrailsApp.run(Application, args)
    }
}

This makes Spring, at application startup, scan all components on the classpath under the package “example” and register them as Spring beans. Or specify @ComponentScan("example") to be more explicit.

What are these “components” you say? All classes annotated with Spring’s stereotype annotation @Component. Or @Service or @Repository which are just specializations.

  • Annotate our classes to make them candidate for auto-detection.

import org.springframework.stereotype.Component

@Component
// or @Repository in this particular case
class ProductRepository {
    SecurityService securityService

    Product findByName(String name) { .. }
}

  • At the moment, when we would restart our app, we’ll get at NullPointerException when we try to invoke anything on securityService.Spring no longer recognizes it should do something with the property — it’s just a mere property now. To make the SecurityService be injected by Spring we need to annotate the property with Spring’s @Autowired, but that’s basically the same as the setter-injection we already had in the beginning. And @Autowired is boiler-plate we don’t need.

While we’re at it, I recommend to use constructor-injection, which means we create (or let the IDE create) a constructor.
* We make the dependencies of ProductRepository explicit.
* Spring will automatically “autowire” our constructor as long as we have exactly one, and inject all parameters of the constructor

import org.springframework.stereotype.Component

@Component
class ProductRepository {
    final SecurityService securityService

    ProductRepository(SecurityService securityService) {
        this.securityService = securityService
    }

This is it.

BTW having an explicit constructor with all the mandatory dependencies, is always a good practice — whether it’s a Spring bean or not.

  • Finally, revert resources.groovy to its initial, empty state – we’re not using it anymore.

Naming is important

Now, if we would have done this to the original, 532 classes we might end up with a more enjoyable tree of files. E.g.

grails-app/services/
└── example
    ├── OrderService.groovy
    ├── ProductService.groovy
    └── SecurityService.groovy
src/main/groovy/
└── example
    ├── order
    │   ├── OrderBuilder.groovy
    │   └── OrderRepository.groovy
    └── product
        ├── ProductBuilder.groovy
        ├── ProductFinder.groovy
        ├── ProductLineReader.groovy
        ├── ProductLineTaglibHelper.groovy
        ├── ProductMapper.groovy
        ├── ProductRepository.groovy
        ├── ProductUtils.groovy
        └── ProductWriter.groovy

Some actual *Service classes cal still reside in grails-app/services and the rest can become clearly named classes, neatly placed in src/main/groovy, while you still enjoy the benefit of using them as Spring beans.

If you and the team early on in the process decide on proper naming conventions (packages, class prefixes and such), you don’t have to reorder everything like we did just now. Together with the team, create and name your classes in an organized place.

Cross-posted from my personal blog

Het bericht Grails Anti-Pattern: Everything is a Service verscheen eerst op First8 Java Consultancy.

]]>
https://www.first8.nl/blog/grails-anti-pattern-everything-is-a-service/feed/ 0
Grails Anti-Pattern: Locally Optimized Dynamic Finders Everywhere https://www.first8.nl/blog/grails-anti-pattern-locally-optimized-dynamic-finders-everywhere/ https://www.first8.nl/blog/grails-anti-pattern-locally-optimized-dynamic-finders-everywhere/#respond Thu, 30 Mar 2017 13:43:35 +0000 https://www.first8.nl/?p=5620 The context Grails makes it very easy to persist and find stuff using domain classes. It uses GORM (Grails’ Object Relational Mapping) under the hood, which by default uses Hibernate to map domain classes to tables in a database. Powerful stuff and makes it easy to get up ’n running very fast! Creating a new application, following so-called “best practices” … Lees verder Grails Anti-Pattern: Locally Optimized Dynamic Finders Everywhere

Het bericht Grails Anti-Pattern: Locally Optimized Dynamic Finders Everywhere verscheen eerst op First8 Java Consultancy.

]]>
The context

Grails makes it very easy to persist and find stuff using domain classes. It uses GORM (Grails’ Object Relational Mapping) under the hood, which by default uses Hibernate to map domain classes to tables in a database. Powerful stuff and makes it easy to get up ’n running very fast!

Creating a new application, following so-called “best practices” from blogs like these 🙂 and the ‘idiomatic Grails-way’ described in the docs and in tutorials work in the beginning, but there’s always a tipping point — where the application has grown a reasonable size — where one should start following a different, maybe less-Grailsey, strategy.

So what can go wrong by using dynamic finders on a domain class?

Perhaps you can recognize following description of the inception of one of your own early Grails applications?

Day 1: Life is beautiful

You create your core domain classes.

I’ve take the example domain classes graciously from The Definitive Guide to Grails by Jeff Brown and Graeme Rocher — a classic!

grails create-domain-class Album
grails create-domain-class Song
grails create-domain-class Artist
...

Awesome.

A simple HomepageController is created to show something on your homepage. It should return a collection of, let’s say, albums for a certain artist and consequently a dynamic finder is obviously the simplest way to make this happen.

class HomepageController {
    def list(Artist artist) {
        [albums: Album.findAllByArtist(artist)]
    }
}

You and your team mates marvel at the magic! The productivity is unparalleled. You can query almost anything like this. You’ve made finder friends for life and for the next days the team is burning through the other homepage user stories like there’s no tomorrow.

Fast-forward 14 days.

Day 14: DOA

The homepage comes to a grinding halt everytime any customer opens it. Performance left the building a few days ago. There’s still magic in the air, but it’s working against you: you haven’t got a clue what’s happening.

Surely all the added widgets, dashboard graphs and reporting on the homepage can’t have anything to do with this?

You turn on Hibernate query logging and try to see what queries happen when you re-open the homepage.

The console displays an avalanche of SQL until the homepage finally finishes loading.

Hibernate: select this_.id as id1_2_0_, this_.version as version2_2_0_, this_.name as name3_2_0_ from artist this_ where this_.name=? limit ?
Hibernate: select this_.id as id1_0_0_, this_.version as version2_0_0_, this_.artist_id as artist_i3_0_0_, this_.title as title4_0_0_ from album this_ where this_.artist_id=?
Hibernate: select this_.id as id1_2_0_, this_.version as version2_2_0_, this_.name as name3_2_0_ from artist this_ where (this_.name=?) limit ?
Hibernate: select this_.id as id1_0_0_, this_.version as version2_0_0_, this_.artist_id as artist_i3_0_0_, this_.title as title4_0_0_ from album this_ where (this_.artist_id=?)
Hibernate: select this_.id as id1_2_0_, this_.version as version2_2_0_, this_.name as name3_2_0_ from artist this_ where (this_.name=?)
Hibernate: select this_.id as id1_0_0_, this_.version as version2_0_0_, this_.artist_id as artist_i3_0_0_, this_.title as title4_0_0_ from album this_ where this_.artist_id in (?) limit ?
Hibernate: select this_.id as id1_2_0_, this_.version as version2_2_0_, this_.name as name3_2_0_ from artist this_
Hibernate: select this_.id as id1_0_0_, this_.version as version2_0_0_, this_.artist_id as artist_i3_0_0_, this_.title as title4_0_0_ from album this_ where this_.artist_id=?
etc etc etc

It’s a bunch of similar looking queries, clogging up your console.

Furthermore, on production it’s clogging up your customer’s valuable time, which is now shopping elsewhere on the competitor’s, faster website.

The explanation

Let’s delve into the Grails code, because somewhere something must be causing this.

You remember that simple HomepageController you personally started out with on Day 1, when life was beautiful?

class HomepageController {
    def list(Artist artist) {
        [albums: Album.findAllByArtist(artist)]
    }
}

Well, it’s not there anymore, at least the simple version. For various tables and charts on the homepage, stuff is now split up over multiple classes, such as view builder services and tag libs.

By the logged SQL it looks like every query almost queries the same information, but you can’t tell anymore. Crawling through the code, you can spot around 18 different places where developers copied dynamic finders similar the original one.

At one place:

Artist artist = Artist.findByName(artistName)
Album.findAllByArtist(artist)

(“Ok, not elegant, but it works”)

At another place:

Album.findAllWhere(artist: Artist.findWhere(name: artistName))

(“Sure, seems to do the same, but as a one-liner”)

Again at another place:

def artists = Artist.findAllWhere(name: artistName)
Album.findAllByArtistInList(artists, [max: 1])

(“What, why? And why limiting the results to just 1 here?”)

Again at another place:

Album.where {
    artist == Artist.list().find { a ->
        a.name == artistName
    }
}.findAll()

(“NOOOooo!”)

The pattern

This happened to me a gazillion times before. Me and the team value the simplicitly and power of Grails. Hence, following convention-over-configuration and being idomatic in our Grails development work, we can deliver fast.

The case with the album and artist dynamic finders above is often not far from reality. Even in the same team, different developers eventually will use what I call “locally optimized dynamic finders” everywhere. Why?

  • They’re too easy to start with
  • They’re too easy to keep on using

There’s almost no boilerplate involved in writing what kind of query you need, creating constructs around them or finding collaborators to go through: what you need is as simple as findBy* and what you get is the domain class you’re on.

Dynamic finders are very readable (and easy to unit test) and so team members will

  • copy and adapt them for a slightly different scenario (here we do need sorting, here we only need one instead of the list)
  • try to be smarter by writing the query in a more “clever” way (sometimes resulting in the opposite)
  • not even know of any existing uses in the application and just, by the documentation or by head, try to get the work done from scratch (so they think)

The disadvantages will surface as the application grows:

  • Every query is different in structure, so you can’t tell by the outside whether or not you’ve got actually 18 different queries or just 2. Any query caches (e.g. by Hibernate) are perhaps either less effective or actually not needed — but now just taking up memory.
  • Carefully crafted indices by the DBA created on Day 1 aren’t used 100% anymore at the end by the majority of the queries, because of the arbitrary presence and order of columns in the WHERE-clause. Any database-optimizations become useless, and perhaps slow table scans are introduced instead.
  • Any refactoring to a “find albums for an artist” query, should be carefully hand-crafted at all the 18 different needed places. This causes everyone headaches. And mistakes.

What we can we do about it?

Maybe obvious, but keep it DRY

Centralize things. Just like you do when code gets duplicated for the 2nd or 3rd time, you find a nice place in your application where every developer can find it. You just then need to worry about that one place.

First, the best Grails thing we can do is making such a central place by e.g. creating a regular Grails service such as e.g. an AlbumService.

grails create-service Album
| Created grails-app/services/example/AlbumService.groovy

Secondly, analyse all of your “find albums for an artist” queries and try to converge on just 1 or 2, which should placed into the new service.

Try to find sensible names for some new methods, which in some cases can just be the name of the original dynamic finder such as findAllByArtist:

@Transactional
class AlbumService {

    Album findAllByArtist(Artist artist) {
        Album.findAllByArtist(artist)
    }
}

Third, replace all occurrences of the usage by a call to the new service. Remember our homepage controller? It’ll change like this:

class HomepageController {

    AlbumService albumService

    def list(Artist artist) {
        [albums: albumService.findAllByArtist(artist)]
    }
}

By updating all 18 individual dynamic finders by a call to the newly created service, you’ve given yourself less instead of more maintainance and the freedom to refactor the methods in the new service internally to more performant variants.

By doing this, you might have to change all kinds of unit tests (such as e.g. HomepageControllerSpec, if you have them): where you first used the in-memory store to actually test the dynamic finders on the domain classes, in these tests now you just have to verify the correct service (e.g. AlbumService) is being invoked.

Only the test for AlbumService should deal with testing the queries now.

In the end AlbumService might contain only 1 or 2 resulting queries, which are used from every needed place in the codebase, but are highly optimized for speed, using all kinds of features such as caching, database indices etc. The kind of performance problems which got us in a mess should be a thing of the past. We can now create other problems 🙂

Dynamic finders are great!

If you’re still not sure whether or not I’m advocating to abanondon dynamic finders? No, ofcourse not – dynamic finders are the best thing ever happened since sliced pizza! Start a new project or prototype with them — great! And do the smart thing very soon and, together with the team, _place your queries together__ in an organized place.

Most important lesson I have learned: if all of the queries are in a neat, well-defined place for everyone to see and go to, the most likely it is that team members will default to basic human behaviour — software development is sometimes just psychology — follow the defined path, and color within the nicely defined lines of that part of the codebase. Seeing what’s already there forces people to think of whether or not it’s worth to introduce a completely new query vs altering one of existing ones.

Cross-posted from my personal blog.

Het bericht Grails Anti-Pattern: Locally Optimized Dynamic Finders Everywhere verscheen eerst op First8 Java Consultancy.

]]>
https://www.first8.nl/blog/grails-anti-pattern-locally-optimized-dynamic-finders-everywhere/feed/ 0