SlideShare une entreprise Scribd logo
1  sur  34
Télécharger pour lire hors ligne
Having Fun with


or, how a perfectly normal
dynamic language developer
fell in love with Java

                   Clinton R. Nixon, Viget Labs
i am a robot come
About Me    from the year 2082
           in order to prevent
            java from becoming
              stale and borinG
“We  are  fully  aware  that  we  made  choices  that  are  pretty  
uncommon  in  the  Java  world,  and  that  Play  does  not  
blindly  follow  all  the  so-­‐called  Java  ‘good  practices’.  But  
all  members  of  the  Play  teams  are  very  experienced  Java  
developers  and  we  are  totally  aware  of  the  choices  we  
made  and  the  rules  we  broke.

“Java  itself  is  a  very  generic  programming  language  and  
not  originally  designed  for  web  application  development.  
It  is  a  very  different  thing  to  write  a  generic  and  reusable  
Java  library  and  to  create  a  web  application.  A  web  
application  itself  doesn’t  need  to  be  designed  to  be  
reusable.  You  need  less  abstraction,  less  conEiguration.  
Reusability  does  exist  for  Web  applications,  but  through  
Web  service  API  rather  than  language-­‐level  integration.”

      –  Guillaume  Bort,  from  the  Play!  FAQ  (emphasis  mine)
What is Play!?
(a) A  web  framework  with  unnecessary  punctation  
    in  its  name  that  I  am  now  dropping.
(b) A  web  framework  written  in  Java  that  doesn’t  
    use  servlets,  portlets,  XML,  EJBs,  JSPs,  or  PCP.
(c) A  share-­‐nothing,  REST-­‐aware,  super-­‐fast,  MVC-­‐
    structured  web  framework  that  takes  the  best  
    from  Ruby  on  Rails,  Django,  and  the  like  and  
    adds  its  own  strengths.
(d) All  of  the  above.
Our example app: PDFless

A  way  to  build  PDFs  
using  simple  tools:  
HTML  +  CSS.

Good  candidate  for  a  
system  like  Play.  Uses  
FlyingSaucer,  a  Java  
library.
Starting our app
cnixon@moro  ~/Projects>  play  new  pdfless                                                                              
                                                                                                                           
~                _                        _  
~    _  __  |  |  __  _  _    _|  |                                      Look at tha t ASCII art!
~  |  '_  |  |/  _'  |  ||  |_|
~  |    __/|_|____|__  (_)                                             Now we’re  having fun.
~  |_|                        |__/      
~
~  play!  1.1-­‐unstable-­‐r785,  http://www.playframework.org
~
~  The  new  application  will  be  created  in  /Users/cnixon/Projects/pdfless
~  What  is  the  application  name?  PDFless
~
~  OK,  the  application  is  created.
~  Start  it  with  :  play  run  pdfless
~  Have  fun!
Our model
Creating our model
package  models;
import  play.data.validation.Email;
                                              app/models/Document.java
import  play.data.validation.Required;

                                                             public fields
import  play.data.validation.URL;
import  play.db.jpa.Model;
import  javax.persistence.Entity;


@Entity
public  class  Document  extends  Model  {
    @Required  @URL
    public  String  url;

    @Required  @Email
    public  String  email;

    @Required
    public  boolean  processed;                        annotations for validation
    public  Document(String  url,  String  email)  {
        this.url  =  url;
        this.email  =  email;
        this.processed  =  false;
    }
}
Where’s the database?
    #  Database  configuration
#  ~~~~~  
#  To  quickly  set  up  a  development  database,  use  either:
#      -­‐  mem  :  for  a  transient  in  memory  database  (HSQL  in  memory)
#      -­‐  fs    :  for  a  simple  file  written  database  (HSQL  file  stored)
db=fs
#                                for testing, I’m using an in-memory DB
#  To  connect  to  a  local  MySQL5  database,  use:
#  db=mysql:user:pwd@database_name
#
#  If  you  need  a  full  JDBC  configuration  use  the  following  :
#  db.url=jdbc:postgresql:database_name
#  db.driver=org.postgresql.Driver
#  db.user=root
#  db.pass=secret
                                              There’s no migration system:
                                  Hibernate will auto-update your
                         tables unless you configure it otherwise.
Document.findById(id);
Document.find("processed  =  ?",  true);
Document.findAll();
Document.count();
Document.delete("email  =  ?",  "crnixon@gmail.com");

Document  document  =  new  Document("http://google.com",  
                                                                  "crnixon@gmail.com");
document.save();
document.delete();
How could this work?
      public  class  JPAEnhancer  extends  Enhancer  {
          public  void  enhanceThisClass(ApplicationClass  applicationClass)  throws  
      Exception  {
              CtClass  ctClass  =  makeClass(applicationClass);
        String  entityName  =  ctClass.getName();          from Javassist,
        //  ...
                                       a Java bytecode manipulation library
        //  count
        CtMethod  count  =  CtMethod.make("public  static  long  count()  {  return  
play.db.jpa.JPQL.instance.count(""  +  entityName  +  "");  }",  ctClass);
        ctClass.addMethod(count);

        //  find                
        CtMethod  find  =  CtMethod.make("public  static  play.db.jpa.JPASupport.JPAQuery  
find(String  query,  Object[]  params)  {  return  play.db.jpa.JPQL.instance.find(""  +  
entityName  +  "",  query,  params);  }",  ctClass);
        ctClass.addMethod(find);
    }
}                                          this looks like some sort
                                     of Ruby metaprogramming nonsense
Our controller
A simple controller
   package  controllers;

import  models.Document;
                                      What does this remind me of?
import  play.data.validation.Valid;
import  play.mvc.Controller;

public  class  Documents  extends  Controller  {
    public  static  void  index()  {
        render();        
    }

    public  static  void  create(@Valid  Document  doc)  {
        if  (validation.hasErrors())  {
            render("Documents/index.html");
        }  else  {
            doc.save();
        }
    }
}
Ok, this smells like a train yard

    #  Routes
#  This  file  defines  all  application  routes  (Higher  priority  routes  first)
#  ~~~~
                                                       this took some getting used to
#  Home  page
GET          /                                                                              Documents.index
GET          /documents                                                            Documents.index
POST        /documents                                                            Documents.create

#  Map  static  resources  from  the  /app/public  folder  to  their  paths
GET          /public/                                                                staticDir:public

#  Catch  all
*              /{controller}/{action}                                    {controller}.{action}



                         sigh - but it is helpful with rapid development
Live demonstration
In case you didn’t catch that

• No  compiling
• Awesome  error  pages
• Request  params  bind  to  
 controller  method  
 params
Let’s see that redirection code
                                                       This is hard to understand,
   if  (Modifier.isPublic(ctMethod.getModifiers())  &&  
               ((ctClass.getName().endsWith("$")  &&  
                                                                   but look at this!
                   !ctMethod.getName().contains("$default$"))  ||  
                   (Modifier.isStatic(ctMethod.getModifiers())  &&  
                   ctMethod.getReturnType().equals(CtClass.voidType)))  &&  
                   !isHandler)  {
           try  {
               ctMethod.insertBefore(
                   "if(!
       play.classloading.enhancers.ControllersEnhancer.ControllerInstrumentation.isActionCallAllowed
       ())  {"+
                   "play.mvc.Controller.redirect(""+ctClass.getName().replace("$",  "")+
            "."+ctMethod.getName()+"",  $args);"+
            "}"+
            "play.classloading.enhancers.ControllersEnhancer.ControllerInstrumentation.stopActionCall();"
            );
    }  catch  (Exception  e)  {  ...  }
}
Translation to human
Before each method, add      “If we’re already in an action call
  ctMethod.insertBefore(
              "if(!play.classloading.enhancers.
  ControllersEnhancer.ControllerInstrumentation.
  isActionCallAllowed())  {"+
              "play.mvc.Controller.redirect(""+    send a redirect
              ctClass.getName().replace("$",  "")+      to this new
              "."+ctMethod.getName()+"",  $args);"+         action
              "}"+                                  to the browser
              "play.classloading.enhancers.
  ControllersEnhancer.ControllerInstrumentation.
  stopActionCall();"
  );
                                and stop the original action.”
Our view
#{extends  'main.html'  /}                               this is Groovy
#{set  title:'PDFLess'  /}

#{ifErrors}
<div  class="error">Please  correct  the  errors  below.</div>
#{/ifErrors}

#{form  @Documents.create()}
    <p>
        <label  for="doc.url">Enter  the  URL  to  make  a  PDF  out  of:</label>
        <input  type="text"  id="doc.url"  name="doc.url"  value="${params['doc.url']}"/>
        #{ifError  'doc.url'}
            <span  class="error">#{error  'doc.url'  /}</span>
        #{/ifError}
    </p>                                                         this is gross
    <p>
        <label  for="doc.email">Enter  the  email  address  to  send  your  PDF  to:</label>
        <input  type="text"  id="doc.email"  name="doc.email"  
            value="${params['doc.email']}"/>
        #{ifError  'doc.email'}
            <span  class="error">#{error  'doc.email'  /}</span>
        #{/ifError}
    </p>
    <input  type="submit"  id="doc.submit"  />
#{/form}
                                                           but this is kind of
                                                               awesome
tags are just
app/views/tags/textField.html
<p>                                                           HTML + Groovy
    <label  for="${_arg}">#{doBody  /}</label>
    <input  type="text"  id="${_arg}"  name="${_arg}"  value="${params[_arg]}"/>
    #{ifError  _arg}
        <span  class="error">#{error  _arg  /}</span>
    #{/ifError}
</p>                                                        and are used like
app/views/Documents/index.html                              built-in tags
#{form  @Documents.create()}
    #{textField  'doc.url'}Enter  the  URL  to  make  a  PDF  out  of:#{/textField}
    #{textField  'doc.email'}
        Enter  the  email  address  to  send  your  PDF  to:
    #{/textField}
    #{textField  'code'}Please  type  the  code  below:#{/textField}    
    <p>
        <input  type="hidden"  name="randomID"  value="${randomID}"  />
        <img  class="captcha"  src="@{Application.captcha(randomID)}"  />
    </p>
    <input  type="submit"  id="doc.submit"  value="Make  My  PDF"  />
#{/form}
Processing jobs
Jobs

Jobs  let  you  perform  
actions  outside  of  web  
requests.
They  take  the  place  of  
startup  tasks,  cron  jobs,  
and  can  be  used  instead  
of  queues.
Startup jobs
  package  jobs;
import  play.jobs.Job;
import  play.jobs.OnApplicationStart;

@OnApplicationStart
public  class  SeedDataJob  extends  Job  {
    public  void  doJob()  {
        loadSeedData("db/seed.yml");
    }
}
Periodic jobs
  package  jobs;
import  play.jobs.Job;
import  play.jobs.Every;

@Every("2h")
public  class  TempDirCleanJob  extends  Job  {
    public  void  doJob()  {
        cleanUpOldPDFs();
    }
}
Using modules
Current modules
• CRUD                   • Database  migrations
• Authentication  &      • Sass
 authorization
                         • Routes  via  annotations
• Captcha  generation    • Scala  &  Scalate
• Code  coverage         • Search
• Google  App  Engine    • Guice
• Google  Web  Toolkit   • Spring
• Oauth                  • and  more!
Testing this thing
Integrated testing tools


JUnit,  Selenium
You  cannot  be  told  what  the  JUnit  is.
Community
This guy is a moron




This guy is really nice
Young, but shows promise
             The  mailing  list  for  Play  is  
             very  active,  and  new  
             modules  are  being  created  
             all  the  time.

             Reminds  me  of  Rails  
             around  1.0.

             Could  easily  blow  up;  
             could  easily  slowly  die  off.
Awesome things we don’t have time for

• Suspendable  requests
• Easiest  Eile  uploads  ever
• Bespin  module  to  code  your  application  inside  your  
  application
• Automatic  type  extensions  in  templates
• Simple  i18n
Summary
Play  comes  to  Java  with  as  few  preconceptions  as  
possible.
It  hooks  into  existing  Java  libraries  easily.
It’s  surprisingly  fun  to  use  and  quick  to  develop  with.
It’s  a  project  with  lots  of  room  for  individuals  to  
make  a  difference.

If  you  liked  this  talk,  please   http://playframework.org    
consider  donating  to  the  
Buy  Clinton  IntelliJ  fund.  
                                              http://crnixon.org
My  free  tial  ends  in  3  days.                     @crnixon

Contenu connexe

Tendances

Testing persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitTesting persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitPeter Wilcsinszky
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii명철 강
 
Devoxx 15 equals hashcode
Devoxx 15 equals hashcodeDevoxx 15 equals hashcode
Devoxx 15 equals hashcodebleporini
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsSolution4Future
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald PehlGWTcon
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012Nicholas Zakas
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversBrian Gesiak
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineRiver of Talent
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0Elena Kolevska
 
Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3makoto tsuyuki
 

Tendances (20)

Geotalk presentation
Geotalk presentationGeotalk presentation
Geotalk presentation
 
Testing persistence in PHP with DbUnit
Testing persistence in PHP with DbUnitTesting persistence in PHP with DbUnit
Testing persistence in PHP with DbUnit
 
Spring data iii
Spring data iiiSpring data iii
Spring data iii
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
Devoxx 15 equals hashcode
Devoxx 15 equals hashcodeDevoxx 15 equals hashcode
Devoxx 15 equals hashcode
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Python RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutionsPython RESTful webservices with Python: Flask and Django solutions
Python RESTful webservices with Python: Flask and Django solutions
 
KISS Automation.py
KISS Automation.pyKISS Automation.py
KISS Automation.py
 
Spring 4 - A&BP CC
Spring 4 - A&BP CCSpring 4 - A&BP CC
Spring 4 - A&BP CC
 
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl"Migrate large gwt applications - Lessons Learned" By Harald Pehl
"Migrate large gwt applications - Lessons Learned" By Harald Pehl
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Using Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App EngineUsing Task Queues and D3.js to build an analytics product on App Engine
Using Task Queues and D3.js to build an analytics product on App Engine
 
Gradle Introduction
Gradle IntroductionGradle Introduction
Gradle Introduction
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0
 
Angular beans
Angular beansAngular beans
Angular beans
 
Redis for your boss
Redis for your bossRedis for your boss
Redis for your boss
 
Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3Django - 次の一歩 gumiStudy#3
Django - 次の一歩 gumiStudy#3
 

En vedette

Narwhal and the Adventures of CommonJS
Narwhal and the Adventures of CommonJSNarwhal and the Adventures of CommonJS
Narwhal and the Adventures of CommonJSClinton Dreisbach
 
Unearthed Arcana for Web People
Unearthed Arcana for Web PeopleUnearthed Arcana for Web People
Unearthed Arcana for Web PeopleClinton Dreisbach
 
Ruby On Rails coding conventions, standards and best practices
Ruby On Rails coding conventions, standards and best practicesRuby On Rails coding conventions, standards and best practices
Ruby On Rails coding conventions, standards and best practicesDavid Paluy
 
Ruby on Rails - The Best Track for your Start Up
Ruby on Rails - The Best Track for your Start UpRuby on Rails - The Best Track for your Start Up
Ruby on Rails - The Best Track for your Start UpPrateek Saxena
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 

En vedette (7)

Narwhal and the Adventures of CommonJS
Narwhal and the Adventures of CommonJSNarwhal and the Adventures of CommonJS
Narwhal and the Adventures of CommonJS
 
The Joy Of Ruby
The Joy Of RubyThe Joy Of Ruby
The Joy Of Ruby
 
HTML5 Now
HTML5 NowHTML5 Now
HTML5 Now
 
Unearthed Arcana for Web People
Unearthed Arcana for Web PeopleUnearthed Arcana for Web People
Unearthed Arcana for Web People
 
Ruby On Rails coding conventions, standards and best practices
Ruby On Rails coding conventions, standards and best practicesRuby On Rails coding conventions, standards and best practices
Ruby On Rails coding conventions, standards and best practices
 
Ruby on Rails - The Best Track for your Start Up
Ruby on Rails - The Best Track for your Start UpRuby on Rails - The Best Track for your Start Up
Ruby on Rails - The Best Track for your Start Up
 
Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 

Similaire à Having Fun with Play

[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVCAlive Kuo
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolGordon Forsythe
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.jsdavidchubbs
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmersAlexander Varwijk
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gearsdion
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesJohn Brunswick
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebJames Rakich
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerOrtus Solutions, Corp
 
Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018Ortus Solutions, Corp
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQueryBastian Feder
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 

Similaire à Having Fun with Play (20)

[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.js
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Nodejs.meetup
Nodejs.meetupNodejs.meetup
Nodejs.meetup
 
I Feel Pretty
I Feel PrettyI Feel Pretty
I Feel Pretty
 
Boston Computing Review - Java Server Pages
Boston Computing Review - Java Server PagesBoston Computing Review - Java Server Pages
Boston Computing Review - Java Server Pages
 
Everything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the WebEverything is Awesome - Cutting the Corners off the Web
Everything is Awesome - Cutting the Corners off the Web
 
Sprockets
SprocketsSprockets
Sprockets
 
Demystifying Maven
Demystifying MavenDemystifying Maven
Demystifying Maven
 
UNO based ODF Toolkit API
UNO based ODF Toolkit APIUNO based ODF Toolkit API
UNO based ODF Toolkit API
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Into The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and dockerInto The Box 2018 Going live with commandbox and docker
Into The Box 2018 Going live with commandbox and docker
 
Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018Going live with BommandBox and docker Into The Box 2018
Going live with BommandBox and docker Into The Box 2018
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 

Dernier

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 

Dernier (20)

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 

Having Fun with Play

  • 1. Having Fun with or, how a perfectly normal dynamic language developer fell in love with Java Clinton R. Nixon, Viget Labs
  • 2. i am a robot come About Me from the year 2082 in order to prevent java from becoming stale and borinG
  • 3. “We  are  fully  aware  that  we  made  choices  that  are  pretty   uncommon  in  the  Java  world,  and  that  Play  does  not   blindly  follow  all  the  so-­‐called  Java  ‘good  practices’.  But   all  members  of  the  Play  teams  are  very  experienced  Java   developers  and  we  are  totally  aware  of  the  choices  we   made  and  the  rules  we  broke. “Java  itself  is  a  very  generic  programming  language  and   not  originally  designed  for  web  application  development.   It  is  a  very  different  thing  to  write  a  generic  and  reusable   Java  library  and  to  create  a  web  application.  A  web   application  itself  doesn’t  need  to  be  designed  to  be   reusable.  You  need  less  abstraction,  less  conEiguration.   Reusability  does  exist  for  Web  applications,  but  through   Web  service  API  rather  than  language-­‐level  integration.” –  Guillaume  Bort,  from  the  Play!  FAQ  (emphasis  mine)
  • 4. What is Play!? (a) A  web  framework  with  unnecessary  punctation   in  its  name  that  I  am  now  dropping. (b) A  web  framework  written  in  Java  that  doesn’t   use  servlets,  portlets,  XML,  EJBs,  JSPs,  or  PCP. (c) A  share-­‐nothing,  REST-­‐aware,  super-­‐fast,  MVC-­‐ structured  web  framework  that  takes  the  best   from  Ruby  on  Rails,  Django,  and  the  like  and   adds  its  own  strengths. (d) All  of  the  above.
  • 5. Our example app: PDFless A  way  to  build  PDFs   using  simple  tools:   HTML  +  CSS. Good  candidate  for  a   system  like  Play.  Uses   FlyingSaucer,  a  Java   library.
  • 6. Starting our app cnixon@moro  ~/Projects>  play  new  pdfless                                                                                 ~                _                        _   ~    _  __  |  |  __  _  _    _|  | Look at tha t ASCII art! ~  |  '_  |  |/  _'  |  ||  |_| ~  |    __/|_|____|__  (_) Now we’re having fun. ~  |_|                        |__/       ~ ~  play!  1.1-­‐unstable-­‐r785,  http://www.playframework.org ~ ~  The  new  application  will  be  created  in  /Users/cnixon/Projects/pdfless ~  What  is  the  application  name?  PDFless ~ ~  OK,  the  application  is  created. ~  Start  it  with  :  play  run  pdfless ~  Have  fun!
  • 8. Creating our model package  models; import  play.data.validation.Email; app/models/Document.java import  play.data.validation.Required; public fields import  play.data.validation.URL; import  play.db.jpa.Model; import  javax.persistence.Entity; @Entity public  class  Document  extends  Model  {    @Required  @URL    public  String  url;    @Required  @Email    public  String  email;    @Required    public  boolean  processed; annotations for validation    public  Document(String  url,  String  email)  {        this.url  =  url;        this.email  =  email;        this.processed  =  false;    } }
  • 9. Where’s the database? #  Database  configuration #  ~~~~~   #  To  quickly  set  up  a  development  database,  use  either: #      -­‐  mem  :  for  a  transient  in  memory  database  (HSQL  in  memory) #      -­‐  fs    :  for  a  simple  file  written  database  (HSQL  file  stored) db=fs # for testing, I’m using an in-memory DB #  To  connect  to  a  local  MySQL5  database,  use: #  db=mysql:user:pwd@database_name # #  If  you  need  a  full  JDBC  configuration  use  the  following  : #  db.url=jdbc:postgresql:database_name #  db.driver=org.postgresql.Driver #  db.user=root #  db.pass=secret There’s no migration system: Hibernate will auto-update your tables unless you configure it otherwise.
  • 10. Document.findById(id); Document.find("processed  =  ?",  true); Document.findAll(); Document.count(); Document.delete("email  =  ?",  "crnixon@gmail.com"); Document  document  =  new  Document("http://google.com",                                                                    "crnixon@gmail.com"); document.save(); document.delete();
  • 11. How could this work? public  class  JPAEnhancer  extends  Enhancer  {    public  void  enhanceThisClass(ApplicationClass  applicationClass)  throws   Exception  {        CtClass  ctClass  =  makeClass(applicationClass);        String  entityName  =  ctClass.getName(); from Javassist,        //  ... a Java bytecode manipulation library        //  count        CtMethod  count  =  CtMethod.make("public  static  long  count()  {  return   play.db.jpa.JPQL.instance.count(""  +  entityName  +  "");  }",  ctClass);        ctClass.addMethod(count);        //  find                        CtMethod  find  =  CtMethod.make("public  static  play.db.jpa.JPASupport.JPAQuery   find(String  query,  Object[]  params)  {  return  play.db.jpa.JPQL.instance.find(""  +   entityName  +  "",  query,  params);  }",  ctClass);        ctClass.addMethod(find);    } } this looks like some sort of Ruby metaprogramming nonsense
  • 13. A simple controller package  controllers; import  models.Document; What does this remind me of? import  play.data.validation.Valid; import  play.mvc.Controller; public  class  Documents  extends  Controller  {    public  static  void  index()  {        render();            }    public  static  void  create(@Valid  Document  doc)  {        if  (validation.hasErrors())  {            render("Documents/index.html");        }  else  {            doc.save();        }    } }
  • 14. Ok, this smells like a train yard #  Routes #  This  file  defines  all  application  routes  (Higher  priority  routes  first) #  ~~~~ this took some getting used to #  Home  page GET          /                                                                              Documents.index GET          /documents                                                            Documents.index POST        /documents                                                            Documents.create #  Map  static  resources  from  the  /app/public  folder  to  their  paths GET          /public/                                                                staticDir:public #  Catch  all *              /{controller}/{action}                                    {controller}.{action} sigh - but it is helpful with rapid development
  • 16. In case you didn’t catch that • No  compiling • Awesome  error  pages • Request  params  bind  to   controller  method   params
  • 17. Let’s see that redirection code This is hard to understand, if  (Modifier.isPublic(ctMethod.getModifiers())  &&              ((ctClass.getName().endsWith("$")  &&   but look at this!            !ctMethod.getName().contains("$default$"))  ||              (Modifier.isStatic(ctMethod.getModifiers())  &&              ctMethod.getReturnType().equals(CtClass.voidType)))  &&              !isHandler)  {    try  {        ctMethod.insertBefore(            "if(! play.classloading.enhancers.ControllersEnhancer.ControllerInstrumentation.isActionCallAllowed ())  {"+            "play.mvc.Controller.redirect(""+ctClass.getName().replace("$",  "")+            "."+ctMethod.getName()+"",  $args);"+            "}"+            "play.classloading.enhancers.ControllersEnhancer.ControllerInstrumentation.stopActionCall();"            );    }  catch  (Exception  e)  {  ...  } }
  • 18. Translation to human Before each method, add “If we’re already in an action call ctMethod.insertBefore(            "if(!play.classloading.enhancers. ControllersEnhancer.ControllerInstrumentation. isActionCallAllowed())  {"+            "play.mvc.Controller.redirect(""+ send a redirect            ctClass.getName().replace("$",  "")+ to this new            "."+ctMethod.getName()+"",  $args);"+ action            "}"+ to the browser            "play.classloading.enhancers. ControllersEnhancer.ControllerInstrumentation. stopActionCall();" ); and stop the original action.”
  • 20. #{extends  'main.html'  /} this is Groovy #{set  title:'PDFLess'  /} #{ifErrors} <div  class="error">Please  correct  the  errors  below.</div> #{/ifErrors} #{form  @Documents.create()}    <p>        <label  for="doc.url">Enter  the  URL  to  make  a  PDF  out  of:</label>        <input  type="text"  id="doc.url"  name="doc.url"  value="${params['doc.url']}"/>        #{ifError  'doc.url'}            <span  class="error">#{error  'doc.url'  /}</span>        #{/ifError}    </p> this is gross    <p>        <label  for="doc.email">Enter  the  email  address  to  send  your  PDF  to:</label>        <input  type="text"  id="doc.email"  name="doc.email"              value="${params['doc.email']}"/>        #{ifError  'doc.email'}            <span  class="error">#{error  'doc.email'  /}</span>        #{/ifError}    </p>    <input  type="submit"  id="doc.submit"  /> #{/form} but this is kind of awesome
  • 21. tags are just app/views/tags/textField.html <p> HTML + Groovy    <label  for="${_arg}">#{doBody  /}</label>    <input  type="text"  id="${_arg}"  name="${_arg}"  value="${params[_arg]}"/>    #{ifError  _arg}        <span  class="error">#{error  _arg  /}</span>    #{/ifError} </p> and are used like app/views/Documents/index.html built-in tags #{form  @Documents.create()}    #{textField  'doc.url'}Enter  the  URL  to  make  a  PDF  out  of:#{/textField}    #{textField  'doc.email'}        Enter  the  email  address  to  send  your  PDF  to:    #{/textField}    #{textField  'code'}Please  type  the  code  below:#{/textField}        <p>        <input  type="hidden"  name="randomID"  value="${randomID}"  />        <img  class="captcha"  src="@{Application.captcha(randomID)}"  />    </p>    <input  type="submit"  id="doc.submit"  value="Make  My  PDF"  /> #{/form}
  • 23. Jobs Jobs  let  you  perform   actions  outside  of  web   requests. They  take  the  place  of   startup  tasks,  cron  jobs,   and  can  be  used  instead   of  queues.
  • 24. Startup jobs package  jobs; import  play.jobs.Job; import  play.jobs.OnApplicationStart; @OnApplicationStart public  class  SeedDataJob  extends  Job  {    public  void  doJob()  {        loadSeedData("db/seed.yml");    } }
  • 25. Periodic jobs package  jobs; import  play.jobs.Job; import  play.jobs.Every; @Every("2h") public  class  TempDirCleanJob  extends  Job  {    public  void  doJob()  {        cleanUpOldPDFs();    } }
  • 27. Current modules • CRUD • Database  migrations • Authentication  &   • Sass authorization • Routes  via  annotations • Captcha  generation • Scala  &  Scalate • Code  coverage • Search • Google  App  Engine • Guice • Google  Web  Toolkit • Spring • Oauth • and  more!
  • 29. Integrated testing tools JUnit,  Selenium You  cannot  be  told  what  the  JUnit  is.
  • 31. This guy is a moron This guy is really nice
  • 32. Young, but shows promise The  mailing  list  for  Play  is   very  active,  and  new   modules  are  being  created   all  the  time. Reminds  me  of  Rails   around  1.0. Could  easily  blow  up;   could  easily  slowly  die  off.
  • 33. Awesome things we don’t have time for • Suspendable  requests • Easiest  Eile  uploads  ever • Bespin  module  to  code  your  application  inside  your   application • Automatic  type  extensions  in  templates • Simple  i18n
  • 34. Summary Play  comes  to  Java  with  as  few  preconceptions  as   possible. It  hooks  into  existing  Java  libraries  easily. It’s  surprisingly  fun  to  use  and  quick  to  develop  with. It’s  a  project  with  lots  of  room  for  individuals  to   make  a  difference. If  you  liked  this  talk,  please   http://playframework.org     consider  donating  to  the   Buy  Clinton  IntelliJ  fund.   http://crnixon.org My  free  tial  ends  in  3  days. @crnixon