Having Fun with Play

Download Having Fun with Play

Post on 12-May-2015




4 download


  • 1.Having Fun withor, how a perfectly normaldynamic language developerfell in love with Java Clinton R. Nixon, Viget Labs

2. i am a robot comeAbout Mefrom the year 2082 in order to preventjava from becomingstale 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 doesnt 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 doesnt 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: PDFlessA way to build PDFs using simple tools: HTML + CSS.Good candidate for a system like Play. Uses FlyingSaucer, a Java library. 6. Starting our appcnixon@moro ~/Projects> play new pdfless ~ _ _ ~ _ __ | | __ _ _ _| |Look at tha t ASCII art!~ | _ | |/ _ | || |_|~ | __/|_|____|__ (_) Now werehaving 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! 7. Our model 8. Creating our modelpackage models;import play.data.validation.Email;app/models/Document.javaimport play.data.validation.Required; public fieldsimport play.data.validation.URL;import play.db.jpa.Model;import javax.persistence.Entity;@Entitypublic 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. Wheres 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, Im 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=secretTheres 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 12. Our controller 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 pageGET / Documents.indexGET /documents Documents.indexPOST /documents Documents.create# Map static resources from the /app/public folder to their pathsGET /public/ staticDir:public# Catch all* /{controller}/{action} {controller}.{action} sigh - but it is helpful with rapid development 15. Live demonstration 16. In case you didnt catch that No compiling Awesome error pages Request params bind to controller method params 17. Lets 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 humanBefore each method, addIf were already in an action callctMethod.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. 19. Our view 20. #{extends main.html /} this is Groovy#{set title:PDFLess /}#{ifErrors}

Please correct the errors below.

#{/ifErrors}#{form @Documents.create()}

Enter the URL to make a PDF out of: #{ifError doc.url} #{error doc.url /} #{/ifError}

this is gross

Enter the email address to send your PDF to: #{ifError doc.email} #{error doc.email /} #{/ifError}

#{/form} but this is kind of awesome 21. tags are justapp/views/tags/textField.html

HTML + Groovy #{doBody /} #{ifError _arg} #{error _arg /} #{/ifError}

and are used likeapp/views/Documents/index.htmlbuilt-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}

#{/form} 22. Processing jobs 23. JobsJobs 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 jobspackage jobs;import play.jobs.Job;import play.jobs.OnApplicationStart;@OnApplicationStartpublic class SeedDataJob extends Job { public void doJob() { loadSeedData("db/seed.yml"); }} 25. Periodic jobspackage jobs;import play.jobs.Job;import play.jobs.Every;@Every("2h")public class TempDirCleanJob extends Job { public void doJob() { cleanUpOldPDFs(); }} 26. Using modules 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! 28. Testing this thing 29. Integrated testing toolsJUnit, SeleniumYou cannot be told what the JUnit is. 30. Community 31. This guy is a moronThis 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 dont 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. SummaryPlay comes to Java with as few preconceptions as possible.It hooks into existing Java libraries easily.Its surprisingly fun to use and quick to develop with.Its 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.orgMy free tial ends in 3 days. @crnixon