Groovy/Grails DevJam
Act I
“When you program in Groovy, in many ways
 you’re writing a special kind of Java.”


                               -Dierk...
.groovy
.java
hugobook:groovy mjhugo$ groovyc
usage: groovyc [options] <source-files>
options:
    --encoding <encoding>   Specify the e...
20%



      80%
getters and setters
1    package com.piragua.java;
2
3    public class SimpleBook {
4        private String title;
5        private String aut...
1   package com.piragua.groovy
2
3   class SimpleBook {
4       String title
5       String authorName
6   }
javap -private SimpleBook

Compiled from quot;SimpleBook.groovyquot;
public class com.piragua.groovy.SimpleBook ... {

   ...
javap -private SimpleBook

Compiled from quot;SimpleBook.groovyquot;
public class com.piragua.groovy.SimpleBook ... {

   ...
1    package com.piragua.java;                                                                     1    package com.piragu...
constructor convenience




http://flickr.com/photos/9229859@N02/1052409181/
1    package com.piragua.java;
2
3    import junit.framework.TestCase;
4
5    import java.util.ArrayList;
6    import java...
1    package com.piragua.groovy
2
3    public class BookTest extends GroovyTestCase {
4        Book book
5        Chapter ...
null safe dereferencing




http://flickr.com/photos/synthesisstudios/352834727/
32   public String toString() {
33       String upperCaseTitle = null;
34       if (title != null){
35           upperCase...
String toString(){
    title?.toUpperCase()
}
// more complex
String toString(){
    book?.publisher?.address?.city?.toUpperCase()
}
groovy strings




http://flickr.com/photos/austinevan/416813459/
// Java Example

public String displayString() {
    return quot;<u>quot; + title + quot;</u> by quot; +
        authorNam...
// Java Example

public String displayString() {
    return quot;<u>quot; + title + quot;</u> by quot; +
        authorNam...
String displayString() {
    quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot;
}
String multiLineDisplayString() {

quot;quot;quot;<u>${title}</u>
by ${authorName}
(${numberOfPages} pages)quot;quot;quot;...
collections




http://flickr.com/photos/stibbons/375342559/
11 private List<Chapter> chapters;
//...
55 public Chapter findChapterByTitle(String chapterTitle) {
56     Chapter foundC...
11 private List<Chapter> chapters;
//...
55 public Chapter findChapterByTitle(String chapterTitle) {
56     Chapter foundC...
8     List chapters
//...
17    Chapter findChapterByTitle(String title) {
18        // finding the first item that matche...
8     List chapters
//...
22    List findChaptersByTitleStartingWith(String searchKeyword) {
23        // finding all matc...
8     List chapters
//...
27    void printChapterTitles() {
28        // iterating over a list
29        chapters.each {ch...
duck typing




http://flickr.com/photos/davidw/380277419/
1    package com.piragua.java;
2
3    import javax.servlet.ServletException;
4    import javax.servlet.http.*;
5    import...
1    package com.piragua.groovy
2
3    import javax.servlet.http.*
4    import com.piragua.java.MyServlet
5
6    public cl...
23   void testDoGetFoundUser() {
24       params.username = 'mike'
25       new MyServlet().doPost(request as HttpServletR...
If we had more time...
•   file handling

•   really easy regular expressions

•   groovy truth

•   case / switch

•   clo...
http://groovy.codehaus.org/   http://groovy.mn/
Act II
Web MVC Framework
convention




http://flickr.com/photos/markpasc/92779595
configuration




http://flickr.com/photos/clintjcl/169886338
DRY


http://flickr.com/photos/joshsommers/935470210/
Development
Deployment
Artifacts



http://flickr.com/photos/ragesoss/118620722/
Artefacts



http://flickr.com/photos/ragesoss/118620722/
grails create-app devjam
mysql> describe event;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         |...
mysql> describe event;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         |...
mysql> describe event;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         |...
Zero
Customer

           class Customer {
           ! Address address
           }

Address
class Customer {
! static hasMany = [incidents:Incident]
}




    Customer               Incident
class Customer {
! static hasMany = [products:Product]
}

class Product {
    static hasMany = [customers:Customer]
    st...
http://server/devjam/event/list

 name of application
http://server/devjam/event/list

  name of controller
http://server/devjam/event/list

   name of action
http://server/devjam/event/list?max=10
Data Binding
Dependency Injection
Demo
If we had more time...
•   testing

•   tag libraries

•   services

•   plugins

•   content negotiation
http://grails.org   http://grails.org/doc/1.0.x/
Act III
http://flickr.com/photos/johnniewalker/359440369
http://flickr.com/photos/philliecasablanca/2473728872
Learning Curve
100




 75




 50




 25




  0

      * data for this chart is completely fabricated
Learning Curve
100




 75




 50




 25




  0

      * data for this chart is completely fabricated
http://flickr.com/photos/13010608@N02/2441101135/
+   +
http://flickr.com/photos/kevint/85911467
1    package com.piragua.groovy
2
3    import javax.servlet.http.*
4    import com.piragua.java.MyServlet
5
6    class MyS...
http://flickr.com/photos/nengard/82039595
200,000       1 Million    $250/month
 users    page views/month     VPS
http://flickr.com/photos/oxygenws/39895404
XYZ Thing
http://flickr.com/photos/thatblondegirl/467513888
Thank You
Groovy/Grails DevJam




https://duke.dev.java.net/images/guitar/DukeAsKeith-daylight.png
http://svn.codehaus.org/groovy/t...
3 things to talk about tonight:
-Brief overview of Groovy
-High level Grails (and Live Coding!)
-Thumbs up and Thumbs Down...
Act I




What is Groovy? - ask the audience...possible answers:
- answers.com: “Very pleasing; wonderful.”
- agile langua...
“When you program in Groovy, in many ways
                     you’re writing a special kind of Java.”


                 ...
.groovy
                     .java




In fact, most of the time you can take .java file and rename
it .groovy and it will ...
Groovy and Java work seamlessly together

-your java classes can reference groovy classes and groovy
classes can reference...
hugobook:groovy mjhugo$ groovyc
                usage: groovyc [options] <source-files>
                options:
         ...
What this means is if you’re already using Java, it works with
everything you already have
- IDEs
- Open Source Frameworks...
20%



                                         80%

For me, it comes down to the 80/20 rule.
Groovy gives me the ability ...
getters and setters




Getters and Setters Example
Standard stuff - create some properties and have your IDE of choice ge...
1    package com.piragua.java;
                 2
                 3    public class SimpleBook {
                 4      ...
1   package com.piragua.groovy
                    2
                    3   class SimpleBook {
                    4     ...
javap -private SimpleBook

                   Compiled from quot;SimpleBook.groovyquot;
                   public class co...
javap -private SimpleBook

                     Compiled from quot;SimpleBook.groovyquot;
                     public clas...
1    package com.piragua.java;                                                                     1    package com.piragu...
constructor convenience




http://flickr.com/photos/9229859@N02/1052409181/
1    package com.piragua.java;
                     2
                     3    import junit.framework.TestCase;
         ...
1    package com.piragua.groovy
                   2
                   3    public class BookTest extends GroovyTestCase ...
null safe dereferencing




http://flickr.com/photos/synthesisstudios/352834727/
32   public String toString() {
                  33       String upperCaseTitle = null;
                  34       if (ti...
String toString(){
                          title?.toUpperCase()
                      }




In Groovy, you can use the ?...
// more complex
                       String toString(){
                           book?.publisher?.address?.city?.toUpp...
groovy strings




http://flickr.com/photos/austinevan/416813459/
// Java Example

                  public String displayString() {
                      return quot;<u>quot; + title + qu...
// Java Example

                  public String displayString() {
                      return quot;<u>quot; + title + qu...
String displayString() {
                    quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot;
        ...
String multiLineDisplayString() {

                quot;quot;quot;<u>${title}</u>
                by ${authorName}
       ...
collections




http://flickr.com/photos/stibbons/375342559/
11 private List<Chapter> chapters;
                    //...
                    55 public Chapter findChapterByTitle(Stri...
11 private List<Chapter> chapters;
                   //...
                   55 public Chapter findChapterByTitle(String...
8     List chapters
                 //...
                 17    Chapter findChapterByTitle(String title) {
             ...
8     List chapters
                //...
                22    List findChaptersByTitleStartingWith(String searchKeyword)...
8     List chapters
                 //...
                 27    void printChapterTitles() {
                 28        /...
duck typing




                           http://flickr.com/photos/davidw/380277419/




http://en.wikipedia.org/wiki/Duck...
oh wait. you canquot;t do this in java. no example here.
1    package com.piragua.java;
                 2
                 3    import javax.servlet.ServletException;
           ...
1    package com.piragua.groovy
                    2
                    3    import javax.servlet.http.*
               ...
23   void testDoGetFoundUser() {
                   24       params.username = 'mike'
                   25       new MySe...
If we had more time...
                                         •   file handling

                                        ...
http://groovy.codehaus.org/   http://groovy.mn/




Two resources:
Groovy website @ codehaus - api, documentation, and lot...
Three books:
-Groovy in Action (Dierk König)
-Groovy Recipies (Scott Davis)
-Programming Groovy (Venkat Subramaniam)


htt...
Act II




So now, on to Grails...What is Grails?
Web MVC Framework




Grails is a Web Model/View/Controller framework
that leverages the power of Groovy, Hibernate, Spring and Java
convention




                   http://flickr.com/photos/markpasc/92779595




With it you can do rapid application devel...
configuration




                   http://flickr.com/photos/clintjcl/169886338




instead of configuration (AKA convention...
DRY


                   http://flickr.com/photos/joshsommers/935470210/




And “Don’t Repeat Yourself”
Why add all sorts ...
Development




Grails provides a full *development* environment out of the box
including an:
- in-memory HSQL DB
- Jetty ...
Deployment




Jetty and HSQLDB are just the defaults -
You can deploy a grails application on any application server that...
Artifacts



                        http://flickr.com/photos/ragesoss/118620722/




Artifacts. or, if you’re british
Artefacts



                      http://flickr.com/photos/ragesoss/118620722/




A lot of the core contributors to Grail...
grails create-app devjam




Every Grails Application has a common structure
Underneath the ‘grails-app’ directory there a...
The domain subdirectory is for any class that you want to be
persistent.
These classes are automatically mapped to the DB ...
Grails will automatically create your database tables based on
your domain classes using Hibernate’s hbm2ddl
There are oth...
mysql> describe event;
               +------------+--------------+------+-----+---------+----------------+
              ...
mysql> describe event;
                +------------+--------------+------+-----+---------+----------------+
             ...
mysql> describe event;
                 +------------+--------------+------+-----+---------+----------------+
            ...
The next couple examples are screen shots of the “Grails Console”
- an interactive Swing console that is wired up with hib...
Not only are the domain classes automatically mapped to the DB,
Grails adds persistent methods like

.save() - inserts or ...
.get(id)

pass in the ID of a persistent object and hibernate will retrieve it
.list()

select * from table
and last but not least, dynamic finders like “findByTitle”
and you can even add criteria like ‘EventDateLessThan’
how about a query using case insensitive ‘like’?
or a query using HQL?
or a query using criteria?
Zero
All of this with: Zero - the amount of configuration and DAO lines
of code you have to do to perform crud on a domain ...
Customer

                                    class Customer {
                                    ! Address address
     ...
class Customer {
                ! static hasMany = [incidents:Incident]
                }




                    Custome...
class Customer {
                 ! static hasMany = [products:Product]
                 }

                 class Product...
Controllers are servlets in the Grails world. Any groovy class in
this directory will have a url mapping by convention - n...
http://server/devjam/event/list

                      name of application




The context root of your app is the name of...
http://server/devjam/event/list

                      name of controller




The next part of a URL is the name of the co...
http://server/devjam/event/list

                       name of action




and the final part is the name of the action (wh...
http://server/devjam/event/list?max=10




Grails puts all the parameters coming in to a controller in to a
map called ‘pa...
Data Binding




This is also fantastic for data binding
- on a new object you can pass the ‘params’ map straight to a
obj...
Dependency Injection




Grails artifacts like controllers and services are created as spring
beans - and grails autowires...
Views are GSP (grails server pages) instead of JSPs
you can reference anything that is in the ‘model’ with ${} notation
(like eventInstance)
there’s a convention for where the views go - by default views for
the “EventController” go in the “views/event” subdirect...
Grails uses SiteMesh to decorate pages - so your GSPs are simple
HTML
that have a layout applied to them
Demo


Demo - build a simple Grails app to
-list events (demo scaquot;olding)
-create a new event (demo domain constraints...
If we had more time...
                                   •   testing

                                   •   tag librarie...
http://grails.org   http://grails.org/doc/1.0.x/




Two resources:
Grails.org website - great starting point - and a grai...
Two excellent books coming out very soon (early editions
available from publisher now)

GIA (May?): http://www.amazon.com/...
Act III




Act III:
- when should you consider using these tools in an existing
environment?
- greenfield environment?
- W...
The first question I ask is “Are you already a Java shop?”
http://flickr.com/photos/johnniewalker/359440369




If you are - then you already have the infrastructure you need to
buil...
http://flickr.com/photos/philliecasablanca/2473728872




And you also have resources that understand Java
If your company/client is open source friendly
Then bringing Groovy into your existing environment is a piece of
cake.
Learning Curve
                 100




                  75




                  50




                  25




       ...
Learning Curve
                 100




                  75




                  50




                  25




       ...
Integrating Grails into an existing environment may not be quite
as easy
If you’re already using Hibernate for the ORM layer, then it’s
possible. You can take your existing database, existing hib...
http://flickr.com/photos/13010608@N02/2441101135/




But where Grails really excels is in a green field
+         +




-If your team is familiar with Hibernate and Spring
-Your process includes iterative development and a fas...
Then you should seriously be considering Grails for your next
project
http://flickr.com/photos/kevint/85911467




Where has it worked?
1    package com.piragua.groovy
                2
                3    import javax.servlet.http.*
                4    im...
http://flickr.com/photos/nengard/82039595




“internal” apps are a great place for Grails - it’s very easy to
develop a fu...
There are tons of success stories for Grails (http://grails.org/
Success+Stories)
Some very large, some smaller.
200,000       1 Million    $250/month
                    users    page views/month     VPS




Like this example - this B...
Linked in uses Grails for some of its sites for corporate customers

http://blog.linkedin.com/2008/06/11/grails-at-linkedi...
Hot oquot; the press - a full case study is coming soon!
wired.com/reviews is Grails powered and more of Wired.com is
movi...
http://flickr.com/photos/oxygenws/39895404




Where has it failed?
I have seen projects run into trouble when they don’t test enough.
The dynamic nature of Groovy/Grails means that the comp...
XYZ Thing




Too far outside the box

For instance - one project that didn’t use the conventions that
GORM provides and t...
I hope youquot;ve enjoyed the overview of Groovy/Grails and some thoughts
to consider when choosing them
http://flickr.com/photos/thatblondegirl/467513888




Obviously, I’m drinking the Koolaid
But I’ve also been working with Groovy and Grails for almost 2
years and I’m still a happy camper.
I encourage you to go download Groovy or download Grails and
walk through the “Getting Started” tutorials - and see how th...
Thank You
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Upcoming SlideShare
Loading in...5
×

Groovy Grails DevJam Jam Session

6,396

Published on

Groovy is a dynamic programming language that runs on the JVM and seamlessly interacts with Java. Grails melds the concept of "Convention over Configuration" and the dynamic power of Groovy to create a framework that greatly simplifies the development of web based applications. This slideshow explores the two - dive into some Groovy vs. Java code examples and see some examples of Grails. We'll also discuss when to introduce either into an existing (or greenfield) environment and where they have worked and where they have failed

Published in: News & Politics, Technology
4 Comments
24 Likes
Statistics
Notes
No Downloads
Views
Total Views
6,396
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
543
Comments
4
Likes
24
Embeds 0
No embeds

No notes for slide

Groovy Grails DevJam Jam Session

  1. 1. Groovy/Grails DevJam
  2. 2. Act I
  3. 3. “When you program in Groovy, in many ways you’re writing a special kind of Java.” -Dierk König Groovy in Action
  4. 4. .groovy .java
  5. 5. hugobook:groovy mjhugo$ groovyc usage: groovyc [options] <source-files> options: --encoding <encoding> Specify the encoding of the user class files. -F <flag> -J <property=value> -d Specify where to place generated class files. -e,--exception Print stack trace on error. -h,--help Print a synopsis of standard options. -j,--jointCompilation Attach javac compiler to compile .java files. -v,--version Print the version.
  6. 6. 20% 80%
  7. 7. getters and setters
  8. 8. 1 package com.piragua.java; 2 3 public class SimpleBook { 4 private String title; 5 private String authorName; 6 7 public String getTitle() { 8 return title; 9 } 10 11 public void setTitle(String title) { 12 this.title = title; 13 } 14 15 public String getAuthorName() { 16 return authorName; 17 } 18 19 public void setAuthorName(String authorName) { 20 this.authorName = authorName; 21 } 22 }
  9. 9. 1 package com.piragua.groovy 2 3 class SimpleBook { 4 String title 5 String authorName 6 }
  10. 10. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... }
  11. 11. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... }
  12. 12. 1 package com.piragua.java; 1 package com.piragua.groovy 2 2 3 import java.util.Date; 3 class Book { 4 import java.util.List; 4 String title 5 5 String authorName 6 public class Book { 6 Integer numberOfPages 7 private String title; 7 String subTitle 8 private String authorName; 8 List chapters 9 private Integer numberOfPages; 9 Date publishDate 10 private String subTitle; 10 String publisher 11 private List<Chapter> chapters; 11 12 private Date publishDate; 12 String toString() { 13 private String publisher; 13 title?.toUpperCase() 14 14 } 15 public String getPublisher() { 15 16 return publisher; 16 String displayString() { 17 } 17 quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; 18 18 } 19 public void setPublisher(String publisher) { 19 20 this.publisher = publisher; 20 Chapter findChapterByTitle(String title) { 21 } 21 // finding the first item that matches criteria 22 22 chapters?.find({it?.title == title}) 23 public Date getPublishDate() { 23 } 24 return publishDate; 24 } 25 } 26 27 public void setPublishDate(Date publishDate) { 28 this.publishDate = publishDate; 29 } 30 31 public List getChapters() { 32 return chapters; 33 } 34 35 public void setChapters(List chapters) { 36 this.chapters = chapters; 37 } 38 39 public String getTitle() { 40 return title; 41 } 42 43 public void setTitle(String title) { 44 this.title = title; 45 } 46 47 public String getAuthorName() { 48 return authorName; 49 } 50 51 public void setAuthorName(String authorName) { 52 this.authorName = authorName; 53 } 54 55 public Integer getNumberOfPages() { 56 return numberOfPages; 57 } 58 59 public void setNumberOfPages(Integer numberOfPages) { 60 this.numberOfPages = numberOfPages; 61 } 62 63 public String getSubTitle() { 64 return subTitle; 65 } 66 67 public void setSubTitle(String subTitle) { 68 this.subTitle = subTitle; 69 } 70 71 public String toString() { 72 String upperCaseTitle = null; 73 if (title != null) { 74 upperCaseTitle = title.toUpperCase(); 75 } 76 return upperCaseTitle; 77 } 78 79 public String displayString() { 80 return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; 81 } 82 83 public Chapter findChapterByTitle(String chapterTitle) { 84 Chapter foundChapter = null; 85 86 if (chapterTitle != null && chapters != null) { 87 for (int i = 0; i < chapters.size(); i++) { 88 if (chapters.get(i) != null && 89 chapterTitle.equals(chapters.get(i).getTitle())) { 90 foundChapter = chapters.get(i); 91 break; 92 } 93 } 94 } 95 return foundChapter; 96 } 97 }
  13. 13. constructor convenience http://flickr.com/photos/9229859@N02/1052409181/
  14. 14. 1 package com.piragua.java; 2 3 import junit.framework.TestCase; 4 5 import java.util.ArrayList; 6 import java.util.Date; 7 8 public class BookTest extends TestCase { 9 Book book; 10 Chapter chapter; 11 12 public void setUp() { 13 book = new Book(); 14 book.setNumberOfPages(300); 15 book.setAuthorName(quot;Mike Hugoquot;); 16 book.setTitle(quot;Groovy Jamquot;); 17 book.setSubTitle(quot;Jamminquot;); 18 book.setPublisher(quot;Piragua Pressquot;); 19 book.setPublishDate(new Date()); 20 }
  15. 15. 1 package com.piragua.groovy 2 3 public class BookTest extends GroovyTestCase { 4 Book book 5 Chapter grails, groovy, why 6 7 void setUp() { 8 book = new Book(title: quot;Groovy Jamquot;, subTitle:quot;Jamminquot;, 9 authorName: quot;Mike Hugoquot;, numberOfPages: 300, 10 publishDate:new Date(), publisher: quot;Piragua Pressquot;) 11 }
  16. 16. null safe dereferencing http://flickr.com/photos/synthesisstudios/352834727/
  17. 17. 32 public String toString() { 33 String upperCaseTitle = null; 34 if (title != null){ 35 upperCaseTitle = title.toUpperCase(); 36 } 37 return upperCaseTitle; 38 }
  18. 18. String toString(){ title?.toUpperCase() }
  19. 19. // more complex String toString(){ book?.publisher?.address?.city?.toUpperCase() }
  20. 20. groovy strings http://flickr.com/photos/austinevan/416813459/
  21. 21. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; }
  22. 22. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; }
  23. 23. String displayString() { quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; }
  24. 24. String multiLineDisplayString() { quot;quot;quot;<u>${title}</u> by ${authorName} (${numberOfPages} pages)quot;quot;quot; }
  25. 25. collections http://flickr.com/photos/stibbons/375342559/
  26. 26. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 }
  27. 27. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 }
  28. 28. 8 List chapters //... 17 Chapter findChapterByTitle(String title) { 18 // finding the first item that matches criteria 19 chapters?.find({it?.title == title}) 20 }
  29. 29. 8 List chapters //... 22 List findChaptersByTitleStartingWith(String searchKeyword) { 23 // finding all matching items 24 chapters?.findAll({it?.title?.startsWith(searchKeyword)}) 25 }
  30. 30. 8 List chapters //... 27 void printChapterTitles() { 28 // iterating over a list 29 chapters.each {chapter -> 30 println chapter?.title 31 } 32 }
  31. 31. duck typing http://flickr.com/photos/davidw/380277419/
  32. 32. 1 package com.piragua.java; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.*; 5 import java.io.IOException; 6 7 public class MyServlet extends HttpServlet { 8 9 @Override 10 protected void doPost(HttpServletRequest request, 11 HttpServletResponse response) 12 throws ServletException, IOException { 13 14 String username = request.getParameter(quot;usernamequot;); 15 if (username != null) { 16 HttpSession session = request.getSession(true); 17 session.setAttribute(quot;loggedInUserquot;, username); 18 } 19 20 } 21 } 22
  33. 33. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 public class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }] 17 18 request = [ 19 getParameter: {param -> return params[param]}, 20 getSession: {createNew -> return mockSession as HttpSession}] 21 }
  34. 34. 23 void testDoGetFoundUser() { 24 params.username = 'mike' 25 new MyServlet().doPost(request as HttpServletRequest, 26 [:] as HttpServletResponse) 27 assertEquals(params.username, session.loggedInUser) 28 } 29 30 void testDoGetNoUser() { 31 params.username = null 32 new MyServlet().doPost(request as HttpServletRequest, 33 [:] as HttpServletResponse) 34 assertNull(session.loggedInUser) 35 }
  35. 35. If we had more time... • file handling • really easy regular expressions • groovy truth • case / switch • closures • meta programming
  36. 36. http://groovy.codehaus.org/ http://groovy.mn/
  37. 37. Act II
  38. 38. Web MVC Framework
  39. 39. convention http://flickr.com/photos/markpasc/92779595
  40. 40. configuration http://flickr.com/photos/clintjcl/169886338
  41. 41. DRY http://flickr.com/photos/joshsommers/935470210/
  42. 42. Development
  43. 43. Deployment
  44. 44. Artifacts http://flickr.com/photos/ragesoss/118620722/
  45. 45. Artefacts http://flickr.com/photos/ragesoss/118620722/
  46. 46. grails create-app devjam
  47. 47. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
  48. 48. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
  49. 49. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec)
  50. 50. Zero
  51. 51. Customer class Customer { ! Address address } Address
  52. 52. class Customer { ! static hasMany = [incidents:Incident] } Customer Incident
  53. 53. class Customer { ! static hasMany = [products:Product] } class Product { static hasMany = [customers:Customer] static belongsTo = Customer //Customer owns the relationship } Customer Customer Product Product
  54. 54. http://server/devjam/event/list name of application
  55. 55. http://server/devjam/event/list name of controller
  56. 56. http://server/devjam/event/list name of action
  57. 57. http://server/devjam/event/list?max=10
  58. 58. Data Binding
  59. 59. Dependency Injection
  60. 60. Demo
  61. 61. If we had more time... • testing • tag libraries • services • plugins • content negotiation
  62. 62. http://grails.org http://grails.org/doc/1.0.x/
  63. 63. Act III
  64. 64. http://flickr.com/photos/johnniewalker/359440369
  65. 65. http://flickr.com/photos/philliecasablanca/2473728872
  66. 66. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated
  67. 67. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated
  68. 68. http://flickr.com/photos/13010608@N02/2441101135/
  69. 69. + +
  70. 70. http://flickr.com/photos/kevint/85911467
  71. 71. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }]
  72. 72. http://flickr.com/photos/nengard/82039595
  73. 73. 200,000 1 Million $250/month users page views/month VPS
  74. 74. http://flickr.com/photos/oxygenws/39895404
  75. 75. XYZ Thing
  76. 76. http://flickr.com/photos/thatblondegirl/467513888
  77. 77. Thank You
  78. 78. Groovy/Grails DevJam https://duke.dev.java.net/images/guitar/DukeAsKeith-daylight.png http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/cruise/reporting-app/images/DukeGroovyChair.jpg
  79. 79. 3 things to talk about tonight: -Brief overview of Groovy -High level Grails (and Live Coding!) -Thumbs up and Thumbs Down: ! -When should you choose to use Groovy/Grails in existing or greenfield project ! -Where it has worked (and why) and where it has failed (and why)
  80. 80. Act I What is Groovy? - ask the audience...possible answers: - answers.com: “Very pleasing; wonderful.” - agile language - scripting language for the JVM - dynamically typed language - build tool - runtime tool for the JVM - high level language for the JVM that compiles to byte code - open source java language
  81. 81. “When you program in Groovy, in many ways you’re writing a special kind of Java.” -Dierk König Groovy in Action Groovy is all of those things, but most of all I like this definition. What is Groovy? - answer by Dierk König, Groovy committer and author of “Groovy in Action” - dynamic language for the JVM
  82. 82. .groovy .java In fact, most of the time you can take .java file and rename it .groovy and it will compile and run
  83. 83. Groovy and Java work seamlessly together -your java classes can reference groovy classes and groovy classes can reference java classes
  84. 84. hugobook:groovy mjhugo$ groovyc usage: groovyc [options] <source-files> options: --encoding <encoding> Specify the encoding of the user class files. -F <flag> -J <property=value> -d Specify where to place generated class files. -e,--exception Print stack trace on error. -h,--help Print a synopsis of standard options. -j,--jointCompilation Attach javac compiler to compile .java files. -v,--version Print the version. This is because of something unique to groovy - the Groovy Joint Compiler - you can compile .groovy and .java files at the same time allowing that seamless interaction
  85. 85. What this means is if you’re already using Java, it works with everything you already have - IDEs - Open Source Frameworks - Application Servers, etc.
  86. 86. 20% 80% For me, it comes down to the 80/20 rule. Groovy gives me the ability to write concise code thatquot;s straight to the point of what Iquot;m trying to do. I donquot;t have to include “ceremony” - code that doesnquot;t relate to the task at hand (Stuart Halloway, http://blog.thinkrelevance.com/ 2008/4/1/ending-legacy-code-in-our-lifetime) and can focus directly on the goal my code is trying to achieve. Examples...
  87. 87. getters and setters Getters and Setters Example Standard stuff - create some properties and have your IDE of choice generate the getters and setters but WHY generate them? they add so much noise to your code...
  88. 88. 1 package com.piragua.java; 2 3 public class SimpleBook { 4 private String title; 5 private String authorName; 6 7 public String getTitle() { 8 return title; 9 } 10 11 public void setTitle(String title) { 12 this.title = title; 13 } 14 15 public String getAuthorName() { 16 return authorName; 17 } 18 19 public void setAuthorName(String authorName) { 20 this.authorName = authorName; 21 } 22 } Java example: two properties, 15 lines of code for getters/ setters Now, letquot;s look at the same class in Groovy...
  89. 89. 1 package com.piragua.groovy 2 3 class SimpleBook { 4 String title 5 String authorName 6 } Same class, 0 lines of code for getters/setters Also notice that the attributes and the class are not scoped - thatquot;s because Groovy provides sensible defaults for these - Lets take a look at a snippet of the byte code as shown by javap
  90. 90. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... } - getters and setters are provided automatically ! - You can add your own getters and setters to define custom behavior - but how often do you really do this?
  91. 91. javap -private SimpleBook Compiled from quot;SimpleBook.groovyquot; public class com.piragua.groovy.SimpleBook ... { private java.lang.String title; private java.lang.String author; public java.lang.String getTitle(); public void setTitle(java.lang.String); public java.lang.String getAuthor(); public void setAuthor(java.lang.String); ... } - no need to define class as public - thatquot;s the default - attributes are private by default - methods are public by default
  92. 92. 1 package com.piragua.java; 1 package com.piragua.groovy 2 2 3 import java.util.Date; 3 class Book { 4 import java.util.List; 4 String title 5 5 String authorName 6 public class Book { 6 Integer numberOfPages 7 private String title; 7 String subTitle 8 private String authorName; 8 List chapters 9 private Integer numberOfPages; 9 Date publishDate 10 private String subTitle; 10 String publisher 11 private List<Chapter> chapters; 11 12 private Date publishDate; 12 String toString() { 13 private String publisher; 13 title?.toUpperCase() 14 14 } 15 public String getPublisher() { 15 16 return publisher; 16 String displayString() { 17 } 17 quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; 18 18 } 19 public void setPublisher(String publisher) { 19 20 this.publisher = publisher; 20 Chapter findChapterByTitle(String title) { 21 } 21 // finding the first item that matches criteria 22 22 chapters?.find({it?.title == title}) 23 public Date getPublishDate() { 23 } 24 return publishDate; 24 } 25 } 26 27 public void setPublishDate(Date publishDate) { 28 this.publishDate = publishDate; 29 } 30 31 public List getChapters() { 32 return chapters; 33 } 34 35 public void setChapters(List chapters) { 36 this.chapters = chapters; 37 } 38 39 public String getTitle() { 40 return title; 41 } 42 43 public void setTitle(String title) { 44 this.title = title; 45 } 46 47 public String getAuthorName() { 48 return authorName; 49 } 50 51 public void setAuthorName(String authorName) { 52 this.authorName = authorName; 53 } 54 55 public Integer getNumberOfPages() { 56 return numberOfPages; 57 } 58 59 public void setNumberOfPages(Integer numberOfPages) { 60 this.numberOfPages = numberOfPages; 61 } 62 63 public String getSubTitle() { 64 return subTitle; 65 } 66 67 public void setSubTitle(String subTitle) { 68 this.subTitle = subTitle; 69 } 70 71 public String toString() { 72 String upperCaseTitle = null; 73 if (title != null) { 74 upperCaseTitle = title.toUpperCase(); 75 } 76 return upperCaseTitle; 77 } 78 79 public String displayString() { 80 return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; 81 } 82 83 public Chapter findChapterByTitle(String chapterTitle) { 84 Chapter foundChapter = null; 85 86 if (chapterTitle != null && chapters != null) { 87 for (int i = 0; i < chapters.size(); i++) { 88 if (chapters.get(i) != null && 89 chapterTitle.equals(chapters.get(i).getTitle())) { 90 foundChapter = chapters.get(i); 91 break; 92 } 93 } 94 } 95 return foundChapter; 96 } 97 } This is the same class - on the left is Java (97 lines of code), on the right is Groovy (24 lines of code). 6 pt font Each class has 7 attributes and three methods. When you go to maintain the Book class, which file would you rather work with?
  93. 93. constructor convenience http://flickr.com/photos/9229859@N02/1052409181/
  94. 94. 1 package com.piragua.java; 2 3 import junit.framework.TestCase; 4 5 import java.util.ArrayList; 6 import java.util.Date; 7 8 public class BookTest extends TestCase { 9 Book book; 10 Chapter chapter; 11 12 public void setUp() { 13 book = new Book(); 14 book.setNumberOfPages(300); 15 book.setAuthorName(quot;Mike Hugoquot;); 16 book.setTitle(quot;Groovy Jamquot;); 17 book.setSubTitle(quot;Jamminquot;); 18 book.setPublisher(quot;Piragua Pressquot;); 19 book.setPublishDate(new Date()); 20 } Constructor Shortcut Happens all the time in unit testing, but also sometimes in real code for setting defaults New up an object, then call all the setters to populate some values
  95. 95. 1 package com.piragua.groovy 2 3 public class BookTest extends GroovyTestCase { 4 Book book 5 Chapter grails, groovy, why 6 7 void setUp() { 8 book = new Book(title: quot;Groovy Jamquot;, subTitle:quot;Jamminquot;, 9 authorName: quot;Mike Hugoquot;, numberOfPages: 300, 10 publishDate:new Date(), publisher: quot;Piragua Pressquot;) 11 } In groovy, you can use named parameters in the constructor to build objects - can happen in any order - can pass all, some, or none of the attributes to the constructor - itquot;s descriptive - you know whatquot;s being set because it says it right here (e.g. title: “groovy jam”)...if you created a java constructor how would you remember which order to pass the parameters?
  96. 96. null safe dereferencing http://flickr.com/photos/synthesisstudios/352834727/
  97. 97. 32 public String toString() { 33 String upperCaseTitle = null; 34 if (title != null){ 35 upperCaseTitle = title.toUpperCase(); 36 } 37 return upperCaseTitle; 38 } In Java, you often have times where you check to see if something is null before performing an action on it
  98. 98. String toString(){ title?.toUpperCase() } In Groovy, you can use the ? operator to safely traverse the tree of an object graph
  99. 99. // more complex String toString(){ book?.publisher?.address?.city?.toUpperCase() } If any of the attributes in this example are null, groovy will stop at that point and return null
  100. 100. groovy strings http://flickr.com/photos/austinevan/416813459/
  101. 101. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; } Yeck. String concatenation is evil So is using string buffer
  102. 102. // Java Example public String displayString() { return quot;<u>quot; + title + quot;</u> by quot; + authorName + quot;, (quot; + numberOfPages + quot; pages)quot;; } Yeck. String concatenation is evil So is using string buffer
  103. 103. String displayString() { quot;<u>${title}</u> by ${authorName}, (${numberOfPages} pages)quot; } Groovy strings allow you to construct strings using ${} notation You can also do multi line strings
  104. 104. String multiLineDisplayString() { quot;quot;quot;<u>${title}</u> by ${authorName} (${numberOfPages} pages)quot;quot;quot; } You can also do multi line strings
  105. 105. collections http://flickr.com/photos/stibbons/375342559/
  106. 106. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 } Java example of finding a chapter by title - iterate over the the list until you find the one youquot;re looking for, set it in a temp variable and break
  107. 107. 11 private List<Chapter> chapters; //... 55 public Chapter findChapterByTitle(String chapterTitle) { 56 Chapter foundChapter = null; 57 58 if (chapterTitle != null && chapters != null) { 59 for (int i = 0; i < chapters.size(); i++) { 60 if (chapters.get(i) != null && 61 chapterTitle.equals(chapters.get(i).getTitle())) { 62 foundChapter = chapters.get(i); 63 break; 64 } 65 } 66 } 67 return foundChapter; 68 } Java example of finding a chapter by title - by the way, did you notice all the null checking going on that distracts from the essence of the code: finding a chapter by title
  108. 108. 8 List chapters //... 17 Chapter findChapterByTitle(String title) { 18 // finding the first item that matches criteria 19 chapters?.find({it?.title == title}) 20 } Groovy example - use .find and pass a closure - closure is executed against every item in the list until a match is found - #itquot; is an implicit parameter passed to a closure, can be named
  109. 109. 8 List chapters //... 22 List findChaptersByTitleStartingWith(String searchKeyword) { 23 // finding all matching items 24 chapters?.findAll({it?.title?.startsWith(searchKeyword)}) 25 } - can also use .findAll
  110. 110. 8 List chapters //... 27 void printChapterTitles() { 28 // iterating over a list 29 chapters.each {chapter -> 30 println chapter?.title 31 } 32 } or .each to iterate over a collection
  111. 111. duck typing http://flickr.com/photos/davidw/380277419/ http://en.wikipedia.org/wiki/Duck_typing If it walks like a duck and quacks like a duck, I would call it a duck. Rather than create an interface to define the contract, use behavior at runtime to determine the functionality So now, a Java example
  112. 112. oh wait. you canquot;t do this in java. no example here.
  113. 113. 1 package com.piragua.java; 2 3 import javax.servlet.ServletException; 4 import javax.servlet.http.*; 5 import java.io.IOException; 6 7 public class MyServlet extends HttpServlet { 8 9 @Override 10 protected void doPost(HttpServletRequest request, 11 HttpServletResponse response) 12 throws ServletException, IOException { 13 14 String username = request.getParameter(quot;usernamequot;); 15 if (username != null) { 16 HttpSession session = request.getSession(true); 17 session.setAttribute(quot;loggedInUserquot;, username); 18 } 19 20 } 21 } 22 Herequot;s an example of a Java Servlet. It takes a parameter from the request, and if it is not null, sets it in to the session. If I wanted to test this, I would have to provide a full implementation of HttpServletRequest and HttpServletResponse just in order to call the method. Note: Spring (and other frameworks) provide Mock implementations of HttpServletRequest and HttpServletResponse,
  114. 114. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 public class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }] 17 18 request = [ 19 getParameter: {param -> return params[param]}, 20 getSession: {createNew -> return mockSession as HttpSession}] 21 } But using Groovy, I can utilize Duck Typing to mock out the implementation. Line 20 has an example: “mockSession as HttpSession” more in the tests
  115. 115. 23 void testDoGetFoundUser() { 24 params.username = 'mike' 25 new MyServlet().doPost(request as HttpServletRequest, 26 [:] as HttpServletResponse) 27 assertEquals(params.username, session.loggedInUser) 28 } 29 30 void testDoGetNoUser() { 31 params.username = null 32 new MyServlet().doPost(request as HttpServletRequest, 33 [:] as HttpServletResponse) 34 assertNull(session.loggedInUser) 35 } Line 25: “request as HttpServletRequest” - my map (defined in the setup method) now looks like a HttpServletRequest to the Servlet under test Line 33: “[:] as HttpServletResponse” just acts as a non-null HttpServletResponse. How would you do this in Java? Create a class, implement the HttpServletResponse interface with a bunch of empty methods, then new it up and pass it into the doPost method. That sucks. Now, I know duck typing is controversial. Interfaces can be a good thing, and they enforce the contract at compile time. With duck typing, you donquot;t
  116. 116. If we had more time... • file handling • really easy regular expressions • groovy truth • case / switch • closures • meta programming For reference in the handout: - File: Convenience methods for writing and reading files: http://docs.codehaus.org/display/GROOVY/JN2015-Files - Truth: .equals is the same as ==; 1 is true, 0 is false; null is false; empty string is false; etc. : http://docs.codehaus.org/ display/GROOVY/Groovy+Truth - Regular expressions are so easy! http://naleid.com/blog/2008/05/19/dont-fear-the-regexp/ - Case / Switch: can switch on any type: http://groovy.codehaus.org/Logical+Branching - Closures: named block of code. pass it around, reuse it, do all sorts of fun things: http://groovy.codehaus.org/Closures - Meta Programming: http://groovy.dzone.com/articles/metaprogramming-groovy-ii-expa , also http://naleid.com/blog/ 2008/05/07/what-methods-does-my-groovygrails-class-have/ - See more differences from Java: http://groovy.codehaus.org/Differences+from+Java
  117. 117. http://groovy.codehaus.org/ http://groovy.mn/ Two resources: Groovy website @ codehaus - api, documentation, and lots of examples Groovy Users Group of MN - meets the second Tuesday of the month in NE minneapolis Also see this presentation by Guillaume LaForge (groovy project manager) on Groovy http://www.slideshare.net/glaforge/groovy-and-grails-in-action-devoxx-2008- university-guillaume-laforge-presentation
  118. 118. Three books: -Groovy in Action (Dierk König) -Groovy Recipies (Scott Davis) -Programming Groovy (Venkat Subramaniam) http://www.amazon.com/Groovy-Action-Dierk-Koenig/dp/ 1932394842 http://www.amazon.com/Groovy-Recipes-Greasing-Pragmatic-
  119. 119. Act II So now, on to Grails...What is Grails?
  120. 120. Web MVC Framework Grails is a Web Model/View/Controller framework
  121. 121. that leverages the power of Groovy, Hibernate, Spring and Java
  122. 122. convention http://flickr.com/photos/markpasc/92779595 With it you can do rapid application development by using the concepts of Convention...
  123. 123. configuration http://flickr.com/photos/clintjcl/169886338 instead of configuration (AKA convention over configuration)
  124. 124. DRY http://flickr.com/photos/joshsommers/935470210/ And “Don’t Repeat Yourself” Why add all sorts of ceremony to your code in configuration when it could be implied?
  125. 125. Development Grails provides a full *development* environment out of the box including an: - in-memory HSQL DB - Jetty application server - Automatic reloading of most artifacts But you’re not limited to that in Development or even in Production -
  126. 126. Deployment Jetty and HSQLDB are just the defaults - You can deploy a grails application on any application server that can handle a WAR file and any database that has a JDBC driver But I’m getting ahead of myself...let’s get started with some Grails basics
  127. 127. Artifacts http://flickr.com/photos/ragesoss/118620722/ Artifacts. or, if you’re british
  128. 128. Artefacts http://flickr.com/photos/ragesoss/118620722/ A lot of the core contributors to Grails are in the UK, so you sometimes run into this (in the Grails code base)
  129. 129. grails create-app devjam Every Grails Application has a common structure Underneath the ‘grails-app’ directory there are sub-directories for “special” grails artifacts. Let’s look at a few
  130. 130. The domain subdirectory is for any class that you want to be persistent. These classes are automatically mapped to the DB through Hibernate
  131. 131. Grails will automatically create your database tables based on your domain classes using Hibernate’s hbm2ddl There are other ways to manage DB migrations, this is just the default
  132. 132. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) ! - the domain class name becomes the table name
  133. 133. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) ! - attribute names are converted into column names
  134. 134. mysql> describe event; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | version | bigint(20) | NO | | NULL | | | event_date | datetime | NO | | NULL | | | title | varchar(255) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+ 4 rows in set (0.00 sec) - id (PK) and version (optimistic locking) columns are added to DB, but don’t need to be explicitly specified in code all of these defaults can be overridden through a mapping DSL or through explicit Hibernate configuration
  135. 135. The next couple examples are screen shots of the “Grails Console” - an interactive Swing console that is wired up with hibernate and all your spring beans and everything
  136. 136. Not only are the domain classes automatically mapped to the DB, Grails adds persistent methods like .save() - inserts or updates an object
  137. 137. .get(id) pass in the ID of a persistent object and hibernate will retrieve it
  138. 138. .list() select * from table
  139. 139. and last but not least, dynamic finders like “findByTitle”
  140. 140. and you can even add criteria like ‘EventDateLessThan’
  141. 141. how about a query using case insensitive ‘like’?
  142. 142. or a query using HQL?
  143. 143. or a query using criteria?
  144. 144. Zero All of this with: Zero - the amount of configuration and DAO lines of code you have to do to perform crud on a domain class.
  145. 145. Customer class Customer { ! Address address } Address Associations are also supported - you can have - one to one
  146. 146. class Customer { ! static hasMany = [incidents:Incident] } Customer Incident - one to many
  147. 147. class Customer { ! static hasMany = [products:Product] } class Product { static hasMany = [customers:Customer] static belongsTo = Customer //Customer owns the relationship } Customer Customer Product Product - many to many
  148. 148. Controllers are servlets in the Grails world. Any groovy class in this directory will have a url mapping by convention - no xml config required:
  149. 149. http://server/devjam/event/list name of application The context root of your app is the name of the application, in this case “devjam”
  150. 150. http://server/devjam/event/list name of controller The next part of a URL is the name of the controller
  151. 151. http://server/devjam/event/list name of action and the final part is the name of the action (which is a closure defined in the controller) These are the defaults - you can change URL mappings to your liking
  152. 152. http://server/devjam/event/list?max=10 Grails puts all the parameters coming in to a controller in to a map called ‘params’ - you can access them using ‘dot’ notation (like ‘params dot max’ to get the ‘max’ parameter)
  153. 153. Data Binding This is also fantastic for data binding - on a new object you can pass the ‘params’ map straight to a object constructor (thank you Groovy constructor convenience)
  154. 154. Dependency Injection Grails artifacts like controllers and services are created as spring beans - and grails autowires beans together by name. In the case, AuthenticateService will automatically be injected into the EventController - no config needed
  155. 155. Views are GSP (grails server pages) instead of JSPs
  156. 156. you can reference anything that is in the ‘model’ with ${} notation (like eventInstance)
  157. 157. there’s a convention for where the views go - by default views for the “EventController” go in the “views/event” subdirectory
  158. 158. Grails uses SiteMesh to decorate pages - so your GSPs are simple HTML
  159. 159. that have a layout applied to them
  160. 160. Demo Demo - build a simple Grails app to -list events (demo scaquot;olding) -create a new event (demo domain constraints) -allow users to RSVP to them (demo reloading of controller and dependency injection) -create RSS feed of events list (install and use feeds plugin)
  161. 161. If we had more time... • testing • tag libraries • services • plugins • content negotiation For reference in the handout: Testing: http://www.grails.org/Testing+Plugin Tag Libraries: http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.3%20Tag%20Libraries Services: http://grails.org/doc/1.0.x/guide/8.%20The%20Service%20Layer.html Plugins: http://grails.org/Plugins Content Negotiation: http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.8%20Content%20Negotiation
  162. 162. http://grails.org http://grails.org/doc/1.0.x/ Two resources: Grails.org website - great starting point - and a grails app itself Grails reference guide - excellent documentation of Grails
  163. 163. Two excellent books coming out very soon (early editions available from publisher now) GIA (May?): http://www.amazon.com/Grails-Action-Glen-Smith/ dp/1933988932/ DGG (Jan): http://www.amazon.com/Definitive-Guide-Grails- Second/dp/1590599950
  164. 164. Act III Act III: - when should you consider using these tools in an existing environment? - greenfield environment? - Where have they worked and where havenquot;t they? When should you consider using these tools in an existing environment?
  165. 165. The first question I ask is “Are you already a Java shop?”
  166. 166. http://flickr.com/photos/johnniewalker/359440369 If you are - then you already have the infrastructure you need to build and deploy applications with Groovy/Grails...
  167. 167. http://flickr.com/photos/philliecasablanca/2473728872 And you also have resources that understand Java
  168. 168. If your company/client is open source friendly
  169. 169. Then bringing Groovy into your existing environment is a piece of cake.
  170. 170. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated The learning curve for a new language might look like this
  171. 171. Learning Curve 100 75 50 25 0 * data for this chart is completely fabricated With Groovy, your Java developers will have a jump start on learning the language -the syntax is basically the same -all the Java APIs are available to you -can immediately be productive with the language and conveniences it provides
  172. 172. Integrating Grails into an existing environment may not be quite as easy
  173. 173. If you’re already using Hibernate for the ORM layer, then it’s possible. You can take your existing database, existing hibernate mapping files and Java domain classes and take advantage of all the features Grails has to oquot;er. (See “Grails In Action” book for using Grails to map the “Legacy Database from Hell”)
  174. 174. http://flickr.com/photos/13010608@N02/2441101135/ But where Grails really excels is in a green field
  175. 175. + + -If your team is familiar with Hibernate and Spring -Your process includes iterative development and a fast feedback loop -And testing is important
  176. 176. Then you should seriously be considering Grails for your next project
  177. 177. http://flickr.com/photos/kevint/85911467 Where has it worked?
  178. 178. 1 package com.piragua.groovy 2 3 import javax.servlet.http.* 4 import com.piragua.java.MyServlet 5 6 class MyServletTest extends GroovyTestCase { 7 8 Map params 9 Map session 10 11 def request 12 13 protected void setUp() { 14 params = [:] 15 session = [:] 16 def mockSession = [setAttribute: {k, v -> session[k] = v }] Unit Testing is a great way to start integrating Groovy into your code base - collections / xml / file convenience features reduce the amount of ceremony in your tests - can make mocking is easier (as shown in earlier groovy slides)
  179. 179. http://flickr.com/photos/nengard/82039595 “internal” apps are a great place for Grails - it’s very easy to develop a fully functional web app very quickly I built one at my last client in 12 hours (full user login, search, audit history and workflow task management)
  180. 180. There are tons of success stories for Grails (http://grails.org/ Success+Stories) Some very large, some smaller.
  181. 181. 200,000 1 Million $250/month users page views/month VPS Like this example - this Brazilian Entertainment website has 200k users, 1 million page views per month and runs on a $250/month VPS - no load balancing or major performance tuning Feb 2008 reference: http://www.nabble.com/Grails-1.0.1-is-out- td15548113.html
  182. 182. Linked in uses Grails for some of its sites for corporate customers http://blog.linkedin.com/2008/06/11/grails-at-linkedin/
  183. 183. Hot oquot; the press - a full case study is coming soon! wired.com/reviews is Grails powered and more of Wired.com is moving to Grails soon
  184. 184. http://flickr.com/photos/oxygenws/39895404 Where has it failed?
  185. 185. I have seen projects run into trouble when they don’t test enough. The dynamic nature of Groovy/Grails means that the compiler won’t find certain errors - you need good testing to mitigate this
  186. 186. XYZ Thing Too far outside the box For instance - one project that didn’t use the conventions that GORM provides and tried to roll their own persistence mechanism didn’t go so well.
  187. 187. I hope youquot;ve enjoyed the overview of Groovy/Grails and some thoughts to consider when choosing them
  188. 188. http://flickr.com/photos/thatblondegirl/467513888 Obviously, I’m drinking the Koolaid
  189. 189. But I’ve also been working with Groovy and Grails for almost 2 years and I’m still a happy camper.
  190. 190. I encourage you to go download Groovy or download Grails and walk through the “Getting Started” tutorials - and see how these new tools can help you be more equot;ective
  191. 191. Thank You
  1. A particular slide catching your eye?

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

×