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    ▸   Consul...
Agenda    ▸   Grails as part of Java EE    ▸   Enterprise telco app    ▸   Development environment    ▸   Development prod...
Agenda    ▸   Enterprise telco app    ▸   Development environment    ▸   Development productivity    ▸   Plugins    ▸   Co...
Enterprise application5
The application    ▸ Order intake and customer care      – used by call center and dealers      – 1000 users    ▸ 75 tailo...
Deployment    ▸ ESB backend      – SOAP web services      – no direct database access      – domain defined in XSD’s      –...
Development environment8
To Grails or not to Grails    ▸ Spring MVC + Freemarker       – no components       – (almost) no IDE support    ▸ project...
To Grails or not to Grails    ▸ Spring MVC + Freemarker       – no components       – (almost) no IDE support             ...
Build     ▸ Multi module Maven project       –Command line Grails        • Mix Ivy and maven dependency resolution        ...
Development team     ▸ 2 scrum teams, 14 developers     ▸ Groovy / Grails experience is rare     ▸ Learning curve       – ...
Development productivity12
Modularization     ▸ (inline) plugin system     ▸ plugins are standalone apps       – views, web.xml, bootstrap, spring be...
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 setBilli...
AST example 1                BillingType getBillingType() {                        return data.customer.customerBillingInf...
AST example 2private productOfferingProductOffering getProductOffering() {    if (!productOffering) {        productOfferi...
AST example 2                private productOffering                ProductOffering getProductOffering() {                ...
AST example 3List<ContactInfo> getContactInfoList() {    List<ContactInfo> result = []    for (contactInfo in data.custome...
AST example 3                List<ContactInfo> getContactInfoList() {                    List<ContactInfo> result = []    ...
AST summary     ▸ AST transformation code: 800 lines       – Java       – Groovy in separate module     ▸ But:       –   2...
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 fee...
UI components22
UI components22
UI components     ▸ Reusable Grails plugin with kitchen sink     ▸ 65 components       –   Form row       –   Input       ...
UI components     ▸ Grails tag          – documented component API, code completion          – ideal for logic          – ...
UI components     ▸ tmpl namespace       – markup in GSP       – simple to use       – no documented API, no code completi...
UI components     ▸ GSP taglib plugin       –   simple to use       –   documented API, code completion, etc.       –   ta...
UI components     ▸ GSP taglib plugin       –   simple to use       –   documented API, code completion, etc.       –   ta...
Plugins27
Rich domain validation     ▸ Validation for non-Grails domain classes       – web services       – deep nested objects    ...
Rich domain validationclass OrderItem {... ▸ Validation for non-Grails domain classes  static web services = {        – co...
29
order.validate(groups: [“deliveryInformation”])29
Rich domain DI     ▸ DI for non-Grails domain classes       – @Inject, @Resource       – auto wiring at object initializat...
Geb     ▸ In-browser functional tests     ▸ Maintainable tests       – Pages / Modules     ▸ Test javascript and (partial)...
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       ...
Developer experience     ▸ Frustrations       –   Build       –   debugger       –   Runtime vs compile time errors       ...
Development cost     ▸ Fast kickoff with Grails       – GORM       – Scaffolding     ▸ Short term development cost       –...
Development cost     ▸ Fast kickoff with Grails       – GORM       – Scaffolding     ▸ Short term development cost       –...
Development cost     ▸ Fast kickoff with Grails       – GORM       – Scaffolding     ▸ Short term development cost       –...
Development cost     ▸ Fast kickoff with Grails       – GORM       – Scaffolding     ▸ Short term development cost       –...
?38
Grails EE
Upcoming SlideShare
Loading in...5
×

Grails EE

2,595

Published on

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,595
On Slideshare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
56
Comments
0
Likes
3
Embeds 0
No embeds

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
  • Grails EE

    1. 1. Grails EEIvo Houbrechts Ixor
    2. 2. About myself ▸ Ivo Houbrechts ▸ Belgium ▸ Grails user and plugin developer ▸ ivo.houbrechts@ixor.be2
    3. 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. 4. Agenda ▸ Grails as part of Java EE ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions4
    5. 5. Agenda ▸ Enterprise telco app ▸ Development environment ▸ Development productivity ▸ Plugins ▸ Conclusions4
    6. 6. Enterprise application5
    7. 7. The application ▸ Order intake and customer care – used by call center and dealers – 1000 users ▸ 75 tailored screens – complex compositions6
    8. 8. Deployment ▸ ESB backend – SOAP web services – no direct database access – domain defined in XSD’s – Spring / JAXB (code generation) ▸ Weblogic 10 cluster7
    9. 9. Development environment8
    10. 10. To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ▸ project behind schedule ➭ speed up with Grails9
    11. 11. To Grails or not to Grails ▸ Spring MVC + Freemarker – no components – (almost) no IDE support ? ▸ project behind schedule ➭ speed up with Grails9
    12. 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. 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. 14. Development productivity12
    15. 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. 16. AST transformations ▸ Compiler plugin ▸ Rather complex ▸ Only for framework developers?14
    17. 17. AST transformations ▸ Compiler plugin ▸ Rather complex14
    18. 18. AST example 1BillingType getBillingType() { return data.customer.customerBillingInfo.customerBillType}void setBillingType(BillingType billingType) { data.customer.customerBillingInfo.customerBillType = billingType.data}15
    19. 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. 20. AST example 2private productOfferingProductOffering getProductOffering() { if (!productOffering) { productOffering = ProductCatalog.get(ProductOffering, data.typeInfo.productOfferingId) } return productOffering}16
    21. 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. 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. 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. 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. 25. UI components ▸ Version 1 – 12 screens – html tags in GSPs – Example: first name edit field19
    26. 26. UI components 2.0 ▸ Version 220
    27. 27. UI components 2.0 ▸ Version 220
    28. 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. 29. UI components22
    30. 30. UI components22
    31. 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. 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. 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. 34. UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy26
    35. 35. UI components ▸ GSP taglib plugin – simple to use – documented API, code completion, etc. – tags in taglib directory – generated xxxTagLib.groovy26
    36. 36. Plugins27
    37. 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. 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. 39. 29
    40. 40. order.validate(groups: [“deliveryInformation”])29
    41. 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. 42. Geb ▸ In-browser functional tests ▸ Maintainable tests – Pages / Modules ▸ Test javascript and (partial) css – Ajax timing issues31
    43. 43. Webflow ▸ Indispensable for – wizards – page flows ▸ see http://livesnippets.cloudfoundry.com32
    44. 44. Resources ▸ Organize javascript and css – jawr – less css ▸ Grails 2.0 : resources plugin33
    45. 45. Conclusions34
    46. 46. Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic35
    47. 47. Developer experience ▸ Frustrations – Build – debugger – Runtime vs compile time errors – Grails upgrades ▸ Satisfaction – Groovy power – Convention over configuration – Fun ▸ Generally enthusiastic35
    48. 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. 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. 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. 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. 52. ?38
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×