openlogic

45
Groovy = Java + Ruby + Python for the JVM Rod Cope

Upload: webuploader

Post on 19-Jan-2015

503 views

Category:

Business


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: OpenLogic

Groovy = Java + Ruby + Pythonfor the JVM

Rod Cope

Page 2: OpenLogic

26/22/2005

Groovy Goals

• Learn what Groovy can do for you• Start using it today!

Page 3: OpenLogic

36/22/2005

Rod Cope• Founder and CTO of OpenLogic

[email protected]

• 9+ years Java experience– Sun Certified Java Architect– J2SE, J2EE, J2ME, Swing, Security, Open Source, etc.– GE, IBM, Ericsson, Manugistics, Digital Thoughts, etc.

• Groovy Lover– Started November 2003– 7,000+ lines of Groovy in production (small apps)– Groovy Presentations

• No Fluff Just Stuff Series• JavaOne• O'Reilly Open Source Convention

Page 4: OpenLogic

46/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 5: OpenLogic

56/22/2005

Agenda

• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 6: OpenLogic

66/22/2005

Sample: Javapublic class Filter {public static void main( String[] args ) {

List list = new ArrayList();list.add( "Rod" ); list.add( "Neeta" );list.add( "Eric" ); list.add( "Missy" );

Filter filter = new Filter();List shorts = filter.filterLongerThan( list, 4 );System.out.println( shorts.size() );

Iterator iter = shorts.iterator();while ( iter.hasNext() ) {System.out.println( iter.next() );

}}public List filterLongerThan( List list, int length ) {

List result = new ArrayList();Iterator iter = list.iterator();while ( iter.hasNext() ) {String item = (String) iter.next();if ( item.length() <= length ) { result.add( item ); }

}return result;

}}

and Groovy!

Page 7: OpenLogic

76/22/2005

Sample: Groovy!

def list = ["Rod", "Neeta", "Eric", "Missy"]def shorts = list.findAll { it.size() <= 4 }println shorts.size()shorts.each { println it }

groovy> 2groovy> Rod

Eric

Page 8: OpenLogic

86/22/2005

Sample in Java (27 lines)public class Filter {public static void main( String[] args ) {

List list = new ArrayList();list.add( "Rod" ); list.add( "Neeta" );list.add( "Eric" ); list.add( "Missy" );

Filter filter = new Filter();List shorts = filter.filterLongerThan( list, 4 );System.out.println( shorts.size() );

Iterator iter = shorts.iterator();while ( iter.hasNext() ) {System.out.println( iter.next() );

}}public List filterLongerThan( List list, int length ) {

List result = new ArrayList();Iterator iter = list.iterator();while ( iter.hasNext() ) {String item = (String) iter.next();if ( item.length() <= length ) { result.add( item ); }

}return result;

}}

Page 9: OpenLogic

96/22/2005

Sample in Groovy (4 lines)

def list = ["Rod", "Neeta", "Eric", "Missy"]def shorts = list.findAll { it.size() <= 4 }println shorts.size()shorts.each { println it }

Page 10: OpenLogic

106/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 11: OpenLogic

116/22/2005

Java Platform Strengths• Lots of reusable software, components, tools• VM and Binary Compatibility

– Build deployment units (class, jar, jnlp, war, ear, sar, etc.) and run them anywhere

– Easily reuse libraries and tools

• Allows for innovation at the source code level

Page 12: OpenLogic

126/22/2005

Components vs. Scripting• We reuse far more code than we write • We spend more time gluing components than writing them• We write more tests than real code• The web tier is a perfect example

– Render business objects as markup (templating / scripting)– Glue actions with requests and domain models (MVC)– Most of web tier is duct tape with pockets of business logic

• Scripting is a great way to glue components together

Page 13: OpenLogic

136/22/2005

Why Another Agile Language?• Want complete binary compatibility with Java

– No difference from Java at JVM / bytecode level– No wrappers or separate islands of APIs

• Java-friendly syntax– Don't want something totally foreign to Java developers

• Want a scripting language designed:– for the Java Platform– by Java developers– for Java developers

Page 14: OpenLogic

146/22/2005

Groovy

• Who/When– James Strachan, Bob McWhirter – August 2003

• What– Dynamic, object-oriented scripting language for JVM– Features of Ruby, Python, and Smalltalk

• Why– J/Python, J/Ruby, BeanShell, etc. all lacking

• How– Initially, hand-written compiler and bytecode generator– Now uses ANTLR and ASM

Page 15: OpenLogic

156/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 16: OpenLogic

166/22/2005

Groovy Features• Dynamic and Static Typing

def str = "Hello"int a = 2

• Native syntax for lists, maps, arrays, beans, etc.def list = ["Rod", 3, new Date()]def myMap = ["Neeta":31, "Eric":34]

• ClosuresmyMap.each(

{ name, age -> println "$name is $age years old" } )groovy> Eric is 34 years oldgroovy> Neeta is 31 years old

Page 17: OpenLogic

176/22/2005

Groovy Features (cont.)• Regex built-in

if ( "name" ==~ "na.*" ) { println "match!" }groovy> match!

• Operator overloadingdef list = [1, 2, 3] + [4, 5, 6]list.flatten().each { print it }

groovy> 123456

• Autoboxing and polymorphism across collection, array, map, bean, String, iterators, etc.String[] array = ['cat', 'dog', 'mouse']def str = 'hello'println "${array.size()},${str.size()},${list.size()}"

groovy> 3,5,6

Page 18: OpenLogic

186/22/2005

Groovy JDK• Groovy-er JDK: adds convenient methods to JDK• String

– contains(), count(), execute(), padLeft(), center(), padRight(), reverse(), tokenize(), each(), etc.

• Collection– count(), collect(), join(), each(), reverseEach(), find/All(), min(), max(), inject(), sort(), etc.

• File– eachFile(), eachLine(), withPrintWriter(), write(), getText(), etc.

• Lots there and growing all the time• You can add methods programmatically

Page 19: OpenLogic

196/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 20: OpenLogic

206/22/2005

Working with Java• Create Adder.java

package com.openlogic.test;public interface Adder{

public int add( int a, int b );}

• Create GAdder.groovypackage com.openlogic.testclass GAdder implements Adder{

public int add( int a, int b ){

return a + b}

}

Page 21: OpenLogic

216/22/2005

Working with Java (cont.)• Compile the Java code

javac -d target Adder.java

• Compile the Groovy codegroovyc --classpath target GAdder.groovy

• Use the Groovy code inside Java with the interfaceAdder adder = new com.openlogic.test.GAdder();int answer = adder.add( 1, 2 );System.out.println( "Answer = " + answer );groovy> Answer = 3

Page 22: OpenLogic

226/22/2005

Working with Ant

• BSF-compliant<script language="groovy">println 'hi' * 2</script>

• Groovy task<taskdef name="groovy"

classname="org.codehaus.groovy.ant.Groovy" classpath="groovy-all-1.0-jsr-2.jar"/>

<groovy>def x = 2for ( count in 1..x ) {

ant.echo( "hello world ($count)" )}ant.jar( destfile: "c:/stuff.jar", basedir: "." )

</groovy>

Page 23: OpenLogic

236/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 24: OpenLogic

246/22/2005

Groovy Markup• Native support for hierarchical structures in

code– XML– XHTML– Ant– Swing– SWT

• Relatively easy to add your own

Page 25: OpenLogic

256/22/2005

Groovy Markup: XML<people>

<person name='Rod'><pet name='Bowie' age='3' /><pet name='Misha' age='9' />

</person><person name='Eric'>

<pet name='Poe' age='5' /><pet name='Doc' age='4' />

</person></people>

Page 26: OpenLogic

266/22/2005

Groovy Markup: XML (cont.)

data = ['Rod': ['Misha':9, 'Bowie':3],'Eric': ['Poe':5, 'Doc':4] ]

xml = new groovy.xml.MarkupBuilder()

doc = xml.people() {for ( entry in data ) {person( name: entry.key ) {for ( dog in entry.value ) {pet( name:dog.key, age:dog.value )

}}

}}

Page 27: OpenLogic

276/22/2005

Groovy Markup: XML Parsingxml = """<people><person name="Rod">

<pet name="Misha" age="9"/><pet name="Bowie" age="3"/>

</person><person name="Eric">

<pet name="Poe" age="5"/><pet name="Doc" age="4"/>

</person></people>"""

people = new groovy.util.XmlParser().parseText( xml )println people.person.pet['@name']

groovy> ['Misha','Bowie','Poe','Doc']

Page 28: OpenLogic

286/22/2005

XML: Transformation• Advanced XML Generation

– StreamingMarkupBuilder in sandbox generates HTML and complex XML - used to generate GDK javadoc

• Groovy as Human-Readable XSLT– Use XML parsing and navigation (findAll, every, any, etc.) to

locate data– Use MarkupBuilder, StreamingMarkupBuilder, etc. to

render new format– Example in groovy.util.NavToWiki.groovy -

transforms XDoc to Wiki

Page 29: OpenLogic

296/22/2005

XML: Transformation Example• In navigation.xml:

<body><links><item name="Download" href="download.html"/><item name="JavaDoc" href="apidocs/index.html"/> ...

• Excerpt from groovy.util.NavToWiki.groovydoc = new XmlParser().parse("navigation.xml")

items = doc.body.links.itemprintln items.collect { item ->

"{link:${item['@name']}|${item['@href']}}"}.join(" | ")

-> {link:Download|download.html} | {link:JavaDoc|apidocs/index.html}

Page 30: OpenLogic

306/22/2005

Groovy Markup: Antant = new groovy.util.AntBuilder()

ant.echo( 'starting...' )ant.sequential {

def mydir = 'c:/backups'mkdir( dir: mydir )copy( todir: mydir ) {

fileset( dir: 'src/test' ) {includes( name:'**/*.groovy' )

}}echo( "done!" )

}

Page 31: OpenLogic

316/22/2005

Groovy Markup: Swingdef swing = new groovy.swing.SwingBuilder() frame = swing.frame(title: 'My Frame', size: [800,400]) {

menuBar {menu(text: 'File') {

menuItem() {action(name:'New', closure:{ println("New") })

}}

}panel(layout:new BorderLayout()) {

label(text: 'Name', constraints: BorderLayout.WEST,toolTipText: 'This is the name field')

button(text: 'Click me!',constraints: BorderLayout.SOUTH,actionPerformed: { println("Click!") } )

}} frame.show()

Page 32: OpenLogic

326/22/2005

Groovy SQLsql = new groovy.sql.Sql( dataSource )sql.execute( "create table person

( name varchar, age integer)" )

people = sql.dataSet( "person" )people.add( name: "Rod", age: 34 )people.add( name: "Neeta", age: 31 )

sql.eachRow( "select * from person" ) { p ->println "$p.name is $p.age years old"

}

groovy> Rod is 34 years oldgroovy> Neeta is 31 years old

Page 33: OpenLogic

336/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 34: OpenLogic

346/22/2005

Extras

• Processes: "cmd /c dir".execute().text• Threading: Thread.start { any code }• Testing: GroovyTestCase, GroovyMock• SWT: Full support for SWT building, like SwingBuilder• Groovy Pages/Template Engine: GSP, Groovlets, etc.• Thicky: Groovy-based fat client delivery via GSP• Unix Scripting: Groovy API for pipe, cat, grep, etc.• Eclipse, IntelliJ, JEdit: Groovy plug-ins available• Native Compiler for Linux/Intel: Very early – maybe

dead• JMX: Small sample available• ActiveX Proxy: Control over MS Windows (IE, Excel,

etc.)

Page 35: OpenLogic

356/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 36: OpenLogic

366/22/2005

Demo: XML-RPC

• XML-based Communication (like SOAP)• Server and Client side support• Separate Module in Groovy (not in core)

Page 37: OpenLogic

376/22/2005

XML-RPC– import groovy.net.xmlrpc.*

– Serverserver = new XMLRPCServer()server.testme = { | name | name + " is cool!" }server.multiply = { | number | number * 10 }serverSocket = new java.net.ServerSocket( 9047 )server.startServer( serverSocket )

– ClientserverProxy=new XMLRPCServerProxy("http://127.0.0.1:9047")println serverProxy.testme( "Groovy" ) -> "Groovy is cool!"println serverProxy.multiply( 7 ) -> 70server.stopServer()

Page 38: OpenLogic

386/22/2005

Demo: Groovy Automation

• ActiveXProxy• Easy native Windows access through Groovy• Uses Jacob Library (danadler.com/jacob)

Page 39: OpenLogic

396/22/2005

ActiveXProxy: Internet Explorerimport org.codehaus.groovy.scriptom.ActiveXProxyexplorer = new ActiveXProxy("InternetExplorer.Application")

explorer.Visible = trueexplorer.AddressBar = trueexplorer.Navigate("http://www.openlogic.com")explorer.StatusText = "OpenLogic home page"explorer.events.OnQuit = { println "Quit" }explorer.events.listen()Thread.sleep(3000)explorer.Quit()

Page 40: OpenLogic

406/22/2005

ActiveXProxy: Excelimport org.codehaus.groovy.scriptom.ActiveXProxyexcel = new ActiveXProxy("Excel.Application")excel.Visible = trueThread.sleep(1000)workbooks = excel.Workbooksworkbook = workbooks.Add()sheet = workbook.ActiveSheeta1 = sheet.Range('A1')a2 = sheet.Range('A2')a1.Value = 125.3a2.Formula = '=A1 * 2'println "a2: ${a2.Value.value}"

groovy> 250.6Workbook.close( false, null, false )excel.Quit()

Page 41: OpenLogic

416/22/2005

Agenda• Groovy Sample• Genesis of Groovy• Groovy Features• Working with Java• Groovy Markup• Extras• Demo• Conclusion

Page 42: OpenLogic

426/22/2005

Trouble in Paradise• Weak and Missing Features

– No support for inner classes– Tool support (Eclipse, IntelliJ, etc.) not great, getting better

• Debugging/Scripting Hell– Immature parser: hard to find "real" bugs– Lots of rope: easy to hang yourself with dynamic code

• Language Instability– Lots of syntactic sugar: nice to have, but may change– Java camp vs. non-Java camp: competing directions– "JSR Groovy" versus "Old Groovy"

Page 43: OpenLogic

436/22/2005

Conclusion• Status

• 1.0 release expected later this summer• Development Time

– Less than half that of Java• Performance

– 20-90% of Java, depending on usage– Very little tuning so far, waiting for 1.0 release

• Recommendations– Ready for small, non-mission-critical projects– Try it! Very easy to learn and lots of fun!

Page 44: OpenLogic

446/22/2005

For More Information• Groovy Home Page

– http://groovy.codehaus.org

• GDK Javadoc– http://groovy.codehaus.org/groovy-jdk.html

• JSR-241: The Groovy Programming Language– http://www.jcp.org/en/jsr/detail?id=241

• James Strachan's Blog– http://radio.weblogs.com/0112098/

Page 45: OpenLogic

456/22/2005

Q&A Period

Any questions?