Grails EE
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Grails EE

on

  • 3,098 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,098
Views on SlideShare
2,014
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 Presentation Transcript

  • 1. Grails EEIvo Houbrechts Ixor
  • 2. About myself ▸ Ivo Houbrechts ▸ Belgium ▸ Grails user and plugin developer ▸ ivo.houbrechts@ixor.be2
  • 3. About Ixor ▸ Since 2002 ▸ 40 experienced ICT professionals ▸ Software development for the JVM ▸ Consultancy and product development ▸ Loyal customers in Finance, Telecom and Government3
  • 4. Agenda ▸ Grails as part of Java EE ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions4
  • 5. Agenda ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions4
  • 6. Enterprise application5
  • 7. The application ▸ Order intake and customer care – used by call center and dealers – 1000 users ▸ 75 tailored screens – complex compositions6
  • 8. Deployment ▸ ESB backend – SOAP web services – no direct database access – domain defined in XSD’s – Spring / JAXB (code generation) ▸ Weblogic 10 cluster7
  • 9. Development environment8
  • 10. To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ▸ project behind schedule ➭ speed up with Grails9
  • 11. To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ? ▸ project behind schedule ➭ speed up with Grails9
  • 12. 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
  • 13. 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
  • 14. Development productivity12
  • 15. 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
  • 16. AST transformations ▸ Compiler plugin ▸ Rather complex ▸ Only for framework developers?14
  • 17. AST transformations ▸ Compiler plugin ▸ Rather complex14
  • 18. AST example 1BillingType getBillingType() { return data.customer.customerBillingInfo.customerBillType}void setBillingType(BillingType billingType) { data.customer.customerBillingInfo.customerBillType = billingType.data}15
  • 19. 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
  • 20. AST example 2private productOfferingProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering}16
  • 21. AST example 2 private productOffering ProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering }@ProductCatalog(typeInfo.productOfferingId)ProductOffering productOffering16
  • 22. 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
  • 23. 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
  • 24. AST summary ▸ AST transformation code: 800 lines – Java – Groovy in separate module ▸ But: – 200+ domain classes – 1000+ usages – ~10K lines omitted – improved readability!18
  • 25. UI components ▸ Version 1 – 12 screens – html tags in GSPs – Example: first name edit field19
  • 26. UI components 2.0 ▸ Version 220
  • 27. UI components 2.0 ▸ Version 220
  • 28. UI components ▸ Html in GSPs becomes problematic – huge GSPs – virtual impossible to change look and feel – inconsistent development ➭ custom tags / components with documented API21
  • 29. UI components22
  • 30. UI components22
  • 31. UI components ▸ Reusable Grails plugin with kitchen sink ▸ 65 components – Form row – Input – Layout (section, box, buttons, links ...) – Ajax – Behavior (autocomplete, menu, toggle ...)23
  • 32. 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
  • 33. 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
  • 34. UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy26
  • 35. UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy26
  • 36. Plugins27
  • 37. 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
  • 38. 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: [...])
  • 39. 29
  • 40. order.validate(groups: [“deliveryInformation”])29
  • 41. 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
  • 42. Geb ▸ In-browser functional tests ▸ Maintainable tests – Pages / Modules ▸ Test javascript and (partial) css – Ajax timing issues31
  • 43. Webflow ▸ Indispensable for – wizards – page flows ▸ see http://livesnippets.cloudfoundry.com32
  • 44. Resources ▸ Organize javascript and css – jawr – less css ▸ Grails 2.0 : resources plugin33
  • 45. Conclusions34
  • 46. Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic35
  • 47. Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic35
  • 48. 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
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. ?38