Grails EE
Upcoming SlideShare
Loading in...5
×
 

Grails EE

on

  • 3,036 views

Slides from GR8Conf EU 2012: http://gr8conf.eu/Presentations/Grails-EE

Slides from GR8Conf EU 2012: http://gr8conf.eu/Presentations/Grails-EE

Statistics

Views

Total Views
3,036
Views on SlideShare
1,952
Embed Views
1,084

Actions

Likes
3
Downloads
52
Comments
0

8 Embeds 1,084

http://groovyflow.com 760
http://gr8conf.eu 245
http://feeds.feedburner.com 23
http://www.groovyflow.com 20
http://lanyrd.com 18
http://www.linkedin.com 8
http://localhost 5
http://gr8conf.org 5
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Grails EE Grails EE Presentation Transcript

  • Grails EEIvo Houbrechts Ixor
  • About myself ▸ Ivo Houbrechts ▸ Belgium ▸ Grails user and plugin developer ▸ ivo.houbrechts@ixor.be2
  • About Ixor ▸ Since 2002 ▸ 40 experienced ICT professionals ▸ Software development for the JVM ▸ Consultancy and product development ▸ Loyal customers in Finance, Telecom and Government3
  • Agenda ▸ Grails as part of Java EE ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions4
  • Agenda ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions4
  • Enterprise application5
  • The application ▸ Order intake and customer care – used by call center and dealers – 1000 users ▸ 75 tailored screens – complex compositions6
  • Deployment ▸ ESB backend – SOAP web services – no direct database access – domain defined in XSD’s – Spring / JAXB (code generation) ▸ Weblogic 10 cluster7
  • Development environment8
  • To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ▸ project behind schedule ➭ speed up with Grails9
  • To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ? ▸ project behind schedule ➭ speed up with Grails9
  • Build ▸ Multi module Maven project –Command line Grails • Mix Ivy and maven dependency resolution • CI agents need both Maven and Grails • Improved maven support in Grails 2.1 –9 modules • JAXB / WS • AST • Grails inline plugins • Grails war, ear, config resources10
  • Development team ▸ 2 scrum teams, 14 developers ▸ Groovy / Grails experience is rare ▸ Learning curve – 2 weeks self study – dynamic language – Intellij IDEA ▸ Vast majority enthusiastic11
  • Development productivity12
  • Modularization ▸ (inline) plugin system ▸ plugins are standalone apps – views, web.xml, bootstrap, spring beans, url mappings... ▸ reuse across applications ▸ plugin compilation time – Grails 2 binary plugins13
  • AST transformations ▸ Compiler plugin ▸ Rather complex ▸ Only for framework developers?14
  • AST transformations ▸ Compiler plugin ▸ Rather complex14
  • AST example 1BillingType getBillingType() { return data.customer.customerBillingInfo.customerBillType}void setBillingType(BillingType billingType) { data.customer.customerBillingInfo.customerBillType = billingType.data}15
  • AST example 1 BillingType getBillingType() { return data.customer.customerBillingInfo.customerBillType } void setBillingType(BillingType billingType) { data.customer.customerBillingInfo.customerBillType = billingType.data }@PropertyDelegate(customer.customerBillingInfo.customerBillType)BillingType billingType15
  • AST example 2private productOfferingProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering}16
  • AST example 2 private productOffering ProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering }@ProductCatalog(typeInfo.productOfferingId)ProductOffering productOffering16
  • AST example 3List<ContactInfo> getContactInfoList() { List<ContactInfo> result = [] for (contactInfo in data.customer.contactInfoList.contactInfo) { result << contactInfo.createNewWrapperInstance() } return result}void clearContactInfoList() { data.customer.contactInfoList.contactInfo.clear()}void addToContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo << contactInfo.data}void addAllToContactInfoList(List<ContactInfo> contactInfoList) { for (contactInfo in contactInfoList) { addToContactInfoList(contactInfo) }}void removeFromContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo.remove(contactInfo.data)}17
  • AST example 3 List<ContactInfo> getContactInfoList() { List<ContactInfo> result = [] for (contactInfo in data.customer.contactInfoList.contactInfo) { result << contactInfo.createNewWrapperInstance() } return result } void clearContactInfoList() { data.customer.contactInfoList.contactInfo.clear() } void addToContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo << contactInfo.data } void addAllToContactInfoList(List<ContactInfo> contactInfoList) { for (contactInfo in contactInfoList) { addToContactInfoList(contactInfo) } } void removeFromContactInfoList(ContactInfo contactInfo) { data.customer.contactInfoList.contactInfo.remove(contactInfo.data) }@PropertyDelegate(customer.contactInfoList.contactInfo)List<ContactInfo> contactInfoList17
  • AST summary ▸ AST transformation code: 800 lines – Java – Groovy in separate module ▸ But: – 200+ domain classes – 1000+ usages – ~10K lines omitted – improved readability!18
  • UI components ▸ Version 1 – 12 screens – html tags in GSPs – Example: first name edit field19
  • UI components 2.0 ▸ Version 220
  • UI components 2.0 ▸ Version 220
  • UI components ▸ Html in GSPs becomes problematic – huge GSPs – virtual impossible to change look and feel – inconsistent development ➭ custom tags / components with documented API21
  • UI components22
  • UI components22
  • UI components ▸ Reusable Grails plugin with kitchen sink ▸ 65 components – Form row – Input – Layout (section, box, buttons, links ...) – Ajax – Behavior (autocomplete, menu, toggle ...)23
  • UI components ▸ Grails tag – documented component API, code completion – ideal for logic – not suited for markup:def box = { attrs, body -> out << “<div class=”box $clazz>”<div class=”boxHeader”>” out << attrs.header << “</div><div class=”boxBody”>” out << body() out << “<div>”}24
  • UI components ▸ tmpl namespace – markup in GSP – simple to use – no documented API, no code completion, etc. ▸ render template from tag – markup in GSP – documented API, code completion, etc. – maintenance hell25
  • UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy26
  • UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy26
  • Plugins27
  • Rich domain validation ▸ Validation for non-Grails domain classes – web services – deep nested objects – limited build-in support ▸ Extended validation – cascaded validation – partial validation – constraint groups – instance validation28
  • Rich domain validationclass OrderItem {... ▸ Validation for non-Grails domain classes static web services = { – constraints – deep nested objects //instance constraint – limited build-in support forbiddenAtLineLevel(validator: { ... }) Extended validation ▸ – cascaded validation //constraint group – partial validation characteristicsOnly { – constraint groups characteristics(cascade: true) instance validation –childOrderItems(cascade: [excludes:forbiddenAtLineLevel]]) } }}orderItem.validate(groups: [“characteristicsOnly”], includes: [“*.delivery”], 28 excludes: [...])
  • 29
  • order.validate(groups: [“deliveryInformation”])29
  • Rich domain DI ▸ DI for non-Grails domain classes – @Inject, @Resource – auto wiring at object initialization and de-serialization – move logic from controllers to domain classes ▸ see http://livesnippets.cloudfoundry.com@RichDomainclass Customer { @Inject transient CustomerWebService customerWebService ...}30
  • Geb ▸ In-browser functional tests ▸ Maintainable tests – Pages / Modules ▸ Test javascript and (partial) css – Ajax timing issues31
  • Webflow ▸ Indispensable for – wizards – page flows ▸ see http://livesnippets.cloudfoundry.com32
  • Resources ▸ Organize javascript and css – jawr – less css ▸ Grails 2.0 : resources plugin33
  • Conclusions34
  • Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic35
  • Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic35
  • Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability36
  • Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability36
  • Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability36
  • Development cost ▸ Fast kickoff with Grails – GORM – Scaffolding ▸ Short term development cost – Determined by domain complexity – Technology is minor factor ▸ Long term benefits – Code size – Code readability36
  • ?38