The Road from Java to Groovy

About Me










1st Career


About Me
2nd Career


















OCI Grails Team
Legend

Cruisin' to easy migration and interop

Caution for potholes & speed bumps

Stopping for rework or collisions
Legend

Anywhere you see a parrot means this inconsistency with Java will be changing when the new "parrot" grammar changes are available in Groovy 3.0 and maybe as options in 2.5.x




- Generally, migration is very easy
- Often, just renaming the file works
- There are a few roadblocks and detours
Java to Groovy Migration

- Classes
- Interfaces
- Inheritance
- Enums
Groovy OOP like Java

- Kind of like Java 8 interfaces
- Kind of like classes
- Can have state and behavior
Groovy also has traits
trait Singer {
int songLength
void sing() {
println "Oh say can you see..."
}
}
class Teacher implements Singer { }
class Student implements Singer {
void sing() {
println "Twinkle twinkle little star..."
}
}


Example: An Order class (Java)


Example: An Order class (Java)


Example: An Order class (Java)

Example: AN Order class (Groovy)
The leftShift method implements << operator overload

AST transformations are compile time
@Canonical
- Uber AST that wraps three other ASTs
- @TupleConstructor
- @EqualsAndHashCode
- @ToString
- If you also include one of those, it takes precedence


Example: A Line Item class (JAVA)


Example: A Line Item class (JAVA)


Example: A Line Item class (JAVA)


Example: A Line Item class (Groovy)
return is optional
result of last statement is returned


Example: Taxable Interface (Java)
Note: Groovy Taxable interface is nearly identical


Example: Order App (Java)


Example: Order App (Java)


Example: Order App (Java)


Example: Order App (Groovy)


Example: Order App (Groovy)
The Order's leftShift method receives the LineItem


Example: Order App (Groovy)
Triple quotes allow us to easily create formatted, multiline strings

Example: Order Service (Java)
Java 8 introduced streams, method references and lambdas

Groovy doesn't support lambdas and Java method references


Example: Order Service (Java)



Java 8 Gaps in Groovy


- Java 8 introduced major language changes around functional programming
- Functional interfaces with default methods
- Lambda expressions: (a,b) -> a + b
- Method references: BigDecimal::add
- Groovy already had functional idioms
- Does not support lambdas and method references directly

Detouring Around The Java 8 Gaps


- Java 8 method references are a kind of shorthand for lambdas
- Lambdas implement functional interfaces
- Groovy closures can be coerced into meeting contract of the functional interface
- Wherever you find a Java 8 method reference or lambda, you can replace it with a closure

Example: Order Service (Groovy)


Example: Results




Mostly Smooth running in Regards
to Migration and Interoperability



- Often can simply rename file to .groovy
- Use closures to work around Java 8 gaps
- AST transformations are at compile time, so support interop with Java
Method Dispatching Differences (JAVA)



Method Dispatching Differences (Groovy)



Groovy Equality

== uses compareTo if Comparable, else equals()
<=> 'spaceship' operator
How are two Codes equal?

Groovy Equality


AST transformations happen at compile-time
"spaceship" operator is compareTo
Groovy Equality

Codes equal via compareTo == 0

Groovy Equality


a.is(b)
a === b
Groovy Strings


Can be written as map['Jack']
Groovy Strings


Groovy Strings


Map map = ["${name}" : 57]; println map; println map.Jack
Groovy Truth


Groovy Truth


Groovy Truth


asBoolean defines Groovy truth for the object
Groovy Truth


Groovy Truth


Performance (JAVA)



Groovy Dynamic Method Dispatch




Cruising Performance (Groovy)


@CompileStatic bypasses Groovy MOP



Note Groovy method pointers
Missing Pavement




Do / While (Java)





Do While (Java)




Do / While (Groovy)



Groovy has never supported do/while

To Groovy, do { } looks like do(Closure)
until then...
Do While (Groovy)




Note @CompileStatic
Do While (Groovy)





Types (Java)



Types (Java)


Types (Groovy)



All types in Groovy are Objects
Keyword Collisons



Automatic Resource
Management (ARM) Blocks
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
- ARM blocks introduced in Java 7
- Goal was to make it easier to ensure resources cleaned up


code from http://groovy-lang.org/differences.html
Groovy Doesn't support Automatic Resource Management (ARM) Blocks
new File('/path/to/file').eachLine('UTF-8') {
println it
}
// or this
new File('/path/to/file').withReader('UTF-8') { reader ->
reader.eachLine {
println it
}
}
- Groovy idioms for doing the same thing are even easier
- Meets goal of making it easy to clean up resources


code from http://groovy-lang.org/differences.html

Summary

Migration from Java and interop with Java is almost trivial

There are a few issues arising from the differences between Groovy and Java, but these are easy to remedy

Very few issues are irreconcilable, such as keyword conflicts.
Resources
- What you saw today
- http://groovy-lang.org/differences.html
-
Connect with me
- LinkedIn: jackfrosch
- Twitter: @jackfrosch
- Email: jackfrosch@gmail.com

Thank you!

NFJS - Road from Java to Groovy
By Jack Frosch
NFJS - Road from Java to Groovy
- 4,589