adopting grails - gr8conf europe

23
Klaus Baumecker Hewlett-Packard Adopting Grails

Upload: klausbaumecker

Post on 14-Apr-2017

368 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: Adopting Grails - GR8Conf Europe

Klaus Baumecker Hewlett-Packard

Adopting Grails

Page 2: Adopting Grails - GR8Conf Europe

About me

2

Klaus Baumecker

Software Architect & Technologist @

Hewlett-Packard, Böblingen, Germany

Professional Software Developer since 1992

Java Programmer since 12+ years

Using Groovy & Grails since 3+ years

Page 3: Adopting Grails - GR8Conf Europe

Introduction

3

We started using Grails in production 2 years ago.

We used Grails already for in-house projects (version 1.0.x)

The following episodes show

… what we’ve learned and

… a few best practices derived from it.

Page 4: Adopting Grails - GR8Conf Europe

Context

4

• Large product suite for IT-Management in HP Software

• Two teams developing the next release of a product

–One using classic JEE approach

–Other using Grails

• Both web-apps share a common data model based on POJOs and

Hibernate mapping files

• All web-apps run inside a JBoss application server

• Continuous integration builds based on maven

• Time-boxed development cycles

• Agile approach with features and stories (SCRUM like)

Page 5: Adopting Grails - GR8Conf Europe

Episode 1 – GORM Constraints

5

The Grails web-app uses GORM constraints to enforce rules on the

domain classes

There was and (and still is) a general attempt to reduce footprint by

moving common web-app libraries into shared lib space

therefore the shared domain model (incl. hibernate mapping) became

a shared library (among others like apache-commons-*, etc)

GORM constraints work fine in

development (run-app), but are

ignored while running production

code inside JBoss

Page 6: Adopting Grails - GR8Conf Europe

Episode 1

6

GORM constraints were part of the Grails source

code (src/groovy/…)

They were loaded by the web-app class loader

Domain classes and mapping file have been

loaded by the shared class loader (and loaded

before the constraints)

The shared class loader cannot access classes

within the web-app (only the other way around)

GORM constraints are ignored!

Extract constraints and move to shared lib

space

Page 7: Adopting Grails - GR8Conf Europe

Episode 2 – Flex UI

7

Demand for graphical editor has led to Flex based UIs.

Communication was XML based.

Then we’ve seen too many Flex timeouts. So we moved to faster

communication with Blaze-DS using the BlazeDS grails-plugin.

We mapped domain classes to Flex classes (Blaze feature).

Better performance now, but…

After a round-trip of a data object

(grails - flex - grails) we got empty

fields in the received object. Although

there were properly set before and

not modified in the UI.

Page 8: Adopting Grails - GR8Conf Europe

Episode 2

8

Our POJO based domain classes have some

protected fields (public getter, private setter).

No problem for hibernate.

Blaze-DS uses commons-bean utilities for mapping

from/to POJOs and ignores asymmetric fields.

Need DTO and some tool to define mapping. We

use Dozer (dozer.org)

Page 9: Adopting Grails - GR8Conf Europe

Grails with BlazeDS or not?

9

Motivation: Optimization (High performance data transfer)!...But

sometimes you really need

–a different rendering strategy (partial vs. all at once)

–a fix for your slow performing back end (Flex timeouts)

Use cases

–Event Browser for IT-Mgmt:

• Large list of IT events to be viewed by an operator (> 20000 events)

• Interactive operations on events (e.g. filtering, dynamic updates from the server)

–More advanced client/server communication (pub/sub, push)

Main issues

–Another layer in your communication

–No controller level (Blaze works on services directly) breaks Grails paradigm

• Same with other communication extensions directly working on services (remoting plugin).

• Some security plugins do not work as expected

Page 10: Adopting Grails - GR8Conf Europe

Generalizing the Controller layer

10

• Grails services w/

controller semantics

• Avoiding redundant

authorization

Business Logic

Layer (optional)

Services

Layer (atomic ops,

caller neutral)

Controller

Layer

(transport spec.)

Business

Logic Service

HTTP

Business

Logic Services

BlazeDS

Business

Service

Remoting Other

Access

Transaction Grails

Controller

Grails

Service

Page 11: Adopting Grails - GR8Conf Europe

Episode 3 – Design your web services

11

We’re using XML for most of our UI/backend communication.

Our backend provides web services for UI and automation tools.

The Flex guy says: Add a special attribute to the XML to make my

rendering easier.

Architect says: Don’t fiddle with the automation interface!

How to setup my web services to

fit the needs for UI and

automation?

Page 12: Adopting Grails - GR8Conf Europe

Episode 3

12

Flex = Rich UI Treat your UI as another

automation client.

Don’t allow UI specifics to show up in the XML. If

you don’t, you’ll end up in maintaining parallel XML

flows.

My recommendation for XML generation

• gsp.xml

• Plain XML code is easy to read and maintain

• No DTO required (as in BlazeDS or JAXB). Map

domain data to XML inside the gsp.

Page 13: Adopting Grails - GR8Conf Europe

Episode 4 – Meta Programming

13

Due to a change of the architecture some domain classes are no longer

stored in our DB. They stored with a different technique (out of our

control).

GORM methods are no longer available.

Store and retrieval is replaced by new a persistence API incl. new DAOs

We still have many consumers of

the (original) classes all over the

place.

How to minimize refactoring?

Page 14: Adopting Grails - GR8Conf Europe

Episode 4

14

Enhance the meta-class of the old classes by the

missing GORM functions (get(..), simple finders).

Meta-class methods map to the new API.

Existing code remains unchanged.

But do this with care!

Comment your code and explain it in your tech

meeting.

Page 15: Adopting Grails - GR8Conf Europe

Episode 5 – Developer Support

15

Programmers with strong Java background often feel lost with reduced

IDE support.

They miss(ed) code completion, static analysis, compile errors, etc.

How can we reduce the whining

and complaining, while moving

them into the Groovy/Grails

world?

Page 16: Adopting Grails - GR8Conf Europe

Episode 5

16

Get a good IDE.

Spent effort in installing analysis tools into your

build. E.g. run CodeNarc analysis.

Write your own CodeNarc rules according to your

internal regulations and needs

Own rule brought some safety back: “Finding

dynamic variable”.

Page 17: Adopting Grails - GR8Conf Europe

Episode 6 – Modularization with Plugins

17

Each web-app developed services which became useful in the other

web-app.

Inter-web-app communication is easy to set-up but not really a solution

–Architecture, security, etc.

–E.g. RMI

Reusing a Grails service inside a Java web-app is not straight-forward.

How can we leverage functionality

across multiple web-apps, keep good

architecture and independent web-app

development in two teams?

Page 18: Adopting Grails - GR8Conf Europe

Episode 6

18

Grails-ify the Java web-app. Now you have two

Grails apps.

Extract shared services into additional Grails

plugin(s).

Create a new umbrella Grails app that loads the two

main web-apps as plugins.

The two Grails apps consume the extracted services

plugins.

Each of the main web-apps run independently (run-

app) to keep lightweight development for each team.

Page 19: Adopting Grails - GR8Conf Europe

From applications to plugins

19

• Refactor your beans from resources.groovy to a resource location, e.g.

src/java/myBeans.groovy

–Watch out:

• Before: “beans = {“

• After: “beans {”

• For each web-app :

–Refer to the new beans file within resources.groovy

• Merging beans in the umbrella app

–Refer to the new beans files from the underlying web-apps

–Wire beans between web-apps (optional)

• Add plugin descriptor

• Adjust URL mapping

• Merge other resources (e.g. files under web-app/)

–Requires extra scripting

Page 20: Adopting Grails - GR8Conf Europe

From applications to plugins (con’t)

20

web-app 1 (java, spring,

grailsified)

web-app 2 (pure grails)

plugin plugin

plugin plugin (shared

services)

umbrella web-app (grails)

resource.groovy

beans = {

loadBeans(‘/beans1.groovy’)

}

src/java/beans1.groovy

beans {

<your beans here>

}

resource.groovy

beans = {

loadBeans(‘/beans2.groovy’)

loadBeans(‘/beans1.groovy’)

}

resource.groovy

src/java/beans2.groovy

Page 21: Adopting Grails - GR8Conf Europe

Summary & Best Practices

21

• Clearly articulate the benefits of the framework

–Not just cool stuff

• Reduce emotion (they know what you think anyway)

• Create a local community

– find the people that think like you

• Use the external community and help others using it

–Mailing-lists, IRC, etc.

• Provide tools

– IDE, static analysis, plugins

• Find situations/cases in which Groovy/Grails really makes a difference

–E.g grails run-app vs. classical web-app redeploy cycle with heavy app servers is a

huge time saver

• Stay close to the Grails sweet-spot as long as possible

–E.g. Groovy domain model vs. Java domain model

Page 22: Adopting Grails - GR8Conf Europe

Summary & Best Practices (cont’d)

22

• Be available

–Provide help when necessary

–Don’t let the team swim alone

• Offer/Initiate code reviews/pair-programming

• Maintain a catalog of design principles and guidelines

–HowTo(s)

–Coding guidelines (e.g. use of types, inheritance vs. composition, controller and

services responsibilities, XML generation strategies, Java vs. Groovy coding etc.)

• Ideas:

–Use the create-* scripts to introduce own templates for controllers and services

–Provide own scripts for lab-specific tools

Page 23: Adopting Grails - GR8Conf Europe

23

Thank You!

Questions?