600 likes | 1.11k Views
Guillaume Laforge Vice-President, Technology G2One, Inc. http://www.g2one.com. Groovy Scripting with Groovy 1.1. Goal of This Talk. Scripting with Groovy 1.1. Learn more about the Groovy dynamic language for the JVM, what’s new in the latest version, and how you can use it in your projects!.
E N D
Guillaume Laforge Vice-President, Technology G2One, Inc. http://www.g2one.com GroovyScripting with Groovy 1.1
Goal of This Talk Scripting with Groovy 1.1 • Learn more about the Groovy dynamic language for the JVM, what’s new in the latest version, and how you can use it in your projects!
Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Initiator of the Grails framework • Co-author of Groovy in Action • By Dierk König, et al. • Vice-President Technology
Agenda • What’s Groovy? • Syntax basics • Groovy APIs • What’s new in Groovy 1.1? • Domain-Specific Languages • Integrating Groovy in your applications • Summary • Q&A
What’s Groovy? • An award-winning alternative dynamic language for the JVM • State of the Groovy Nation
Sugar in your Java • Groovy is Java-like • Easy to learn for a Java developer flat learning curve • Simpler than Java for beginners and subject matter experts • Seamless integration with Java • You can mix Groovy and Java objects together • Groovy class extending Java class implementing Groovy interface, and vice versa… • Same strings, regex, APIs, OO, threads, security • Same paradigm and platform! • No impedance mismatch!
Features at a Glance • Fully object-oriented • Closures: reusable & assignable code blocks • Properties support: don’t wait for Java 7 or 8! • Operator overloading • Native syntax for list, maps and regex • Multimethods: call the right method! • GPath: XPath-like navigation in object graphs • BigDecimal arithmetics by default • Optional semi-colons and parenthesis • SQL, Ant, XML, templates, Swing, XML-RPC, JMX • Perfect for Domain-Specific Languages
Groovy Figures • Groovy is a 4+ years old project – Codehaus • Over 10+ active committers • 4+ on the core, 3 on Eclipse plugin, 3 on Swing • After 1.0, 11K+ downloads in weeks • Highest traffic mailing-lists at Codehaus • Actually, 2nd to Grails (MVC Web Framework) • 1000+ subscribers to our lists • In the process of standardization: JSR-241
Already Integrated Everywhere • AntHill Grails eXo Platform JBoss Seam NanoContainer Eclipse XWiki ServiceMix Tapestry Wicket TestNG SoapUI Turbine Oracle OC4J Blojsom NetBeans OpenEJB Drools 1060NetKernel RIFE GroovyRules Mule FreeMind LuxorXUL Spring Ant Maven IntelliJ IDEA Simple JSPWiki eXist Canoo WebTest Biscuit ThinG Oracle Data Integrator Struts2 Eclipse JMeter JFreeChart, …
Used in Mission-Critical applications • Mutual of Omaha – Fortune 500 US Comp. • 45,000 lines of Groovy (half business code / half test code) • Integrated in an EJB as a risk calculation engine for insurance policies • Involved Java beginners, developers, and subject matter experts • Exact arithmetic support, perfect Java integration, closures ideal for business rules expression
JAX 2007 Innovation Award • 40 proposals / 10 nominees • Groovy won the first prize • Most innovative and creative project • 10,000 euros donation • Past winner was Spring
Syntax Basics • Groovy as a Java-superset • Syntax examples: • Properties, lists, maps, ranges, regex, strings, closures
Valid Java Program • import java.util.List; • import java.util.ArrayList; • class Erase { • private List filterLongerThan(List strings, int length) { • List result = new ArrayList(); • for (int i = 0; i < strings.size(); i++) { • String s = (String) strings.get(i); • if (s.length() <= length) { • result.add(s); • } • } • return result; • } • public static void main(String[] args) { • List names = new ArrayList(); • names.add("Ted"); • names.add("Fred"); • names.add("Jed"); • names.add("Ned"); • System.out.println(names); • Erase e = new Erase(); • List shortNames= e.filterLongerThan(names, 3); • System.out.println(shortNames.size()); • for (inti= 0; i< shortNames.size(); i++) { • String s = (String) shortNames.get(i); • System.out.println(s); • } • } • }
Valid Groovy Program • import java.util.List; • import java.util.ArrayList; • class Erase { • private List filterLongerThan(List strings, int length) { • List result = new ArrayList(); • for (int i = 0; i < strings.size(); i++) { • String s = (String) strings.get(i); • if (s.length() <= length) { • result.add(s); • } • } • return result; • } • public static void main(String[] args) { • List names = new ArrayList(); • names.add("Ted"); • names.add("Fred"); • names.add("Jed"); • names.add("Ned"); • System.out.println(names); • Erase e = new Erase(); • List shortNames= e.filterLongerThan(names, 3); • System.out.println(shortNames.size()); • for (inti= 0; i< shortNames.size(); i++) { • String s = (String) shortNames.get(i); • System.out.println(s); • } • } • }
Groovier solution • def names = ["Ted", "Fred", "Jed", "Ned"] • println names • def shortNames = names.findAll{ • it.size() <= 3 • } • println shortNames.size() • shortNames.each{ println it }
Properties Support • Don’t wait for Java 7/8/9 • Getters / setters are boring boiler-plate code • Groovy adds support for properties • Declared fields get automagic accessors • Example • class Person { String name String firstName}
Litterals for lists, maps, ranges, regex, strings • List: def list = ["Groovy", "Grails"] • Map: def map = [CA: "Calif.", TX: "Texas"] • Ranges: def uptoten = 1..10 • Regex: assert fooooo ==~ /fo*/ • Multiline strings: • def s = """ multi line string""" • Gstring • println "My name is ${name}"
Closures • Don’t wait for Java 7/8/9, get closures now! • Reusable / assignable code blocks • Combine, store, share data and logic • Examples • new File('x.txt').eachLine{ println it } • [0, 1, 2].each { println it } • def numbers = 1..100def odd = { it % 2 == 1 }numbers.findAll { it > 90 }numbers.findAll( odd )
Groovy APIs • Groovy Development Kit • Examples: XML, SQL, Swing and Office automation
Groovy Development Kit • Simplified APIs for common tasks • Mocking / stubbing support • XML parsing and GPath navigation • SQL support with exception & resource handling • Script Ant with the AntBuilder • Create Swing UIs easily with SwingBuilder • Templating support à la Velocity • Script COM / ActiveX components on Windows • Consume / expose XML-RPC / SOAP services • Handle JXM beans as local objects
XML Parsing and GPath Navigation • Given this XML snippet • def xml = """<languages> <language name="Groovy"> <feature coolness="low">SQL</feature> <feature coolness="high">Template</feature> </language> <language name="Perl"/></languages>""“ • Navigate the object graph • def root = new XmlParser().parseText(xml)println root.language.feature[1].text()root.language.feature .findAll{ it['@coolness'] == "low" } .each{ println it.text() }
SQL support • Easy to use JDBC thanks to closures • def sql = Sql.newInstance(url, usr, pwd, driver)sql.execute("insert into table values ($foo, $bar)")sql.execute("insert into table values(?,?)", [a, b])sql.eachRow("select * from USER") { print it.name }def list = sql.rows("select * from USER") • DataSet notion: « poor-man » ORM • def set = sql.dataSet("USER")set.add(name: "Johnny", age: 33)set.each { user -> println user.name }set.findAll { it.age > 22 && it.age < 42 }
SwingBuilder • def theMap = [color: "green", object: "pencil"]def swing = new SwingBuilder()def frame = swing.frame( title: 'A Groovy Swing', location: [240,240], defaultCloseOperation:WC.EXIT_ON_CLOSE) {panel { for (entry in theMap) {label(text: entry.key)textField(text: entry.value) }button(text: 'About', actionPerformed: { def pane = swing.optionPane(message: 'SwingBuilder') def dialog = pane.createDialog(null, 'About') dialog.show() })button(text:'Quit', actionPerformed:{ System.exit(0) }) }}frame.pack()frame.show()
Automating Office Applications • An additional module provide VB-like scripting capabilities with a VB-like syntax • Example • def outlook = new ActiveXProxy("Outlook.Application")def message = outlook.CreateItem(0)def emails = glaforge@gmail.comdef rec= message.Recipients.add(emails)rec.Type = 1message.Display(true)
Domain-Specific Languages • Why create Domain-Specific Languages? • How to create such DSLs?
Why Create a Domain-Specific Language? • Use a more expressive language than a general programming language • Share a common metaphorebetween developers and subject matter experts • Have domain experts help design the business logic of an application • Avoid cluttering business code with too much boilerplate technical code • Cleanly seperate business logicfrom application code
Putting it all together • Optional parens, map syntax, props on ints • move left • compare indicator: ‘NIKEI’, withFund: ‘XYZ’ • account.debit amount: 30.euros, in: 3.days • Custom control structures with closures • unless ( account.balance < 0 ) { account.debit 10.dollars } • execute( withTimeoutOf: 50.seconds ) { … } • Operator overloading • a + b a.plus(b) • taskA | taskB taskA.or(taskB)
Builder pattern at the syntax level • Tree structures are everywhere • XML, GUI components, Ant tasks, conf files… • Through closure & chained method calls • new MarkupBuider().invoices { invoice(id: "4") { line "product 1" line "product 2" }} • Create your own « builder » • Extend BuilderSupport, or FactoryBuilderSupport
What’s new in 1.1? • Java 5 features • New dynamic capabilities • Performance improvements • IDE support
What’s New? • Java 5 features • Annotations, generics, enums, static imports • New powerful dynamic capabilities • ExpandoMetaClass contributed by Grails • Performance improvements • Regular gains of perf. between the last releases • IDE support: IntelliJ IDEA & Eclipse
Java 5 Features • Why adding Java 5 features to Groovy? • To leverage Enterprise frameworks making use of annorations and generics • Spring, JPA, Hibernate, Guice, TestNG, JUnit 4… • Groovy is the sole alternative dynamic language for the JVM supporting annotations • Groovy is Java-like, but is closer to being a pure Java-superset • If you need annotations / generics and want to benefit from a dynamic language • Look no further, Groovy is the sole option
Annotations Example • Taken from JBoss Seam’s documentation • @Entity@Name("hotel")class Hotel implements Serializable {@Id @GeneratedValue Long id@Length(max=50) @NotNull String name@Override String toString() { "Hotel ${name}" }}
Enums example with a Groovy switch • enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, • THURSDAY, FRIDAY, SATURDAY } • def today = Day.SATURDAY • switch (today) { • case [Day.SATURDAY, Day.SUNDAY]: • println "Weekends are cool" • break • case Day.MONDAY..Day.FRIDAY: • println "Boring work day" • break • default: • println "Are you sure this is a valid day?" • }
New dynamic features • Grails contributed the ExpandoMetaClass • Easily add new behavior to existing classes • Symbiotic relationship between both projects • Ex: Adding a meters property to numbers • Integer.metaClass.getMeters = { ->new Distance(delegate, Distance.METER) }println 3.meters
Integrating Groovyin your Applications • Why integrating Groovy in your applications? • The different integration mechanisms
Why Integrating Groovy in your Apps? • Groovy’s great support for testing • Mocks & stubs, GroovyTestCase • More concise & readable tests • Handy tool int the developer toolbox • Externalize business rules • Business rules be written by domain experts • Rules follow their own lifecycle • Providing extension points in your apps • For third-party plugins • Customizing the app to clients’ needs
Several Integration Mechanisms • The « old » Bean Scripting Framework • Java 6’s scripting APIs (JSR-223) • Spring dynamic language support • Groovy’s own mechanisms • Let’s see some of them
JSR-223 – javax.script.* from JDK 6 • One API to rule them all! • Dedicated Groovy engineon scripting.dev.java.net • Drop it in your classpath! • Example • ScriptEngineManager manager = new ScriptEngineManager();ScriptEngine gEngine = manager.getEngineByName("groovy");String result = (String)gEngine.eval("’Foo’ * 2");
GroovyShell • Easily evaluate expressions in your Java app • Pass variables in and out • Can provide global reusable functions • Example • def binding = new Binding()binding.mass = 22.3binding.velocity = 10.6def shell = new GroovyShell( binding )def expression = "mass * velocity ** 2 / 2" assert shell.evaluate(expression) == 1252.814
GroovyClassLoader • Most powerful integration mechanism • With GCL, you can • Parse and compile classes • Provide a resource loader defining the location of sources • Database, flat files, XML files, distant URLs… • Define Java security rules • To avoid System.exit(0) in an Embedded DSL! • Even transform the Abstract Syntax Tree!
Spring 2.x Groovy integration • Spring 2.0 provides support for alternative language bean definitions and configuration • A POGO can be wired the like a POJO and be proxied • You can mix languages in your Spring application • POGO and POJO can be injected within each other • Configuration of a POGO bean with the specific lang namespace, and a custom MetaClass • <lang:groovy id="events" script-source="classpath:dsl/eventsChart.groovy" customizer-ref="eventsMetaClass" />
Let’s Wrap Up • Summary • Resources • Q&A
Summary • The Groovy dynamic language for the JVMsimplifies the life of developersthrough powerful APIs • Groovy opens some interesting perspectives towards extending your application • Groovy provides the most seamless Java integration experience • Groovy lets you create DSLs • Groovy protects your investment in skills, tools, libraries and application servers
Resources • Groovy: http://groovy.codehaus.org • Grails: http://grails.org • Groovy blogs: http://groovyblogs.org • AboutGroovy: http://aboutgroovy.com • G2One: http://www.g2one.com
G2One, Inc. • Groovy & Grails at the source! • Graeme Rocher, Grails lead • Guillaume Laforge, Groovy lead • Plus key committers • Professional Services • Training, support, consulting • Custom developments • Connectors, plugins, etc…