Your SlideShare is downloading. ×
0
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Grails EE
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Grails EE

2,574

Published on

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

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

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,574
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
56
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • \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
  • 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

    ×