For those of you who are aware that ScriptRunner allows JIRA users to execute Groovy code in response to events and workflow transitions, it may come as a surprise that the ScriptRunner for JIRA Cloud team has been converting the majority of our Cloud service codebase from Groovy to Java.
In this blog post I'll talk a little bit about the reasons for that change and the things we miss from Groovy.
1. Static compilation finds bugs before runtime
Very early on in the development of ScriptRunner for JIRA Cloud we enabled static compilation of our Groovy code because we shipped some type-related bugs into production. The CompileStatic annotation tells the Groovy compiler to type-check our code at compile time, so as to avoid silly mistakes!
2. The Groovy compiler isn't as good at static compilation as the Java compiler
Having enable static compilation we started running into scenarios where the Groovy compiler didn't know what type a
def was even though it was extremely clear to us and our IDE. Our codebase was becoming littered with
as Map or
as String and using
def was becoming pointless. Given the amount of type-hinting we were doing, we felt like
switching to Java wouldn't add any additional type indication overhead.
3. We like our types, even if they're verbose
One of the appeals of Groovy is that you don't have to specify the type of a variable when the compiler can figure it out for you. Having said that, both Groovy and Java are strongly typed languages, and code is for humans, not for computers, so hiding the type of any given variable seems to be deliberately making things hard for ourselves. For this same reason we're considering a move to TypeScript from ES6.
4. IntelliJ IDEA didn't handle some of the generics in our Groovy code
Finally, our IDE just couldn't handle the generics in some of our Ratpack code and subsequently highlighted huge chunks of our source incorrectly as having the wrong return type. This obscured actual errors in those sections of code which made working in any promise based Groovy code a real PITA.
So, what do we miss from Groovy?
@Slf4jwhich injected a logger into each class for us, although we might introduce
@Log4jfrom Project Lombok
- Succinct map and list literals although this might change a little with Java 9
- Some of the collection based default methods required less code than Java 8s streams, but the map/reduce terminology
in Java is much more accessible than Groovys collect/inject
- String interpolation, although we do prefer only having one String type
We're still using Groovy for our tests though, in part because we like Spock and in part because static compilation isn't as necessary there :)
- 17 Jan 2018 » How to run Karma tests in browsers in Docker
- 30 Oct 2017 » Fun with React event handlers
- 17 Jul 2017 » Switching from Groovy to Java
- 24 May 2017 » Useful Git Aliases
- 27 Mar 2017 » Practical Ratpack Promises
- 03 Nov 2016 » Custom Content in Forms for Confluence Connect
- 04 Oct 2016 » Checking user permissions from REST calls
- 30 Sep 2016 » Using the reflection API in Confluence
- 28 Sep 2016 » Creating a custom Confluence Blueprint
- 06 Sep 2016 » ReactJS in Forms for Confluence Connect
- 25 Apr 2016 » Migrating to ES6 in Atlassian Add-ons
- 17 Mar 2016 » All kinds of things I learnt trying to performance test against Fisheye/Crucible
- 24 Dec 2015 » Adaptavist’s Holiday Gift of Atlassian Deployment Automation
- 17 Dec 2015 » Getting a Custom Field value safely
- 07 Dec 2015 » Putting Google Analytics to work with plugins for Confluence
- 02 Dec 2015 » Devoxx Voting, A retrospective
- 25 Nov 2015 » Some things I've learnt about SingleSelect
- 15 Oct 2015 » Using SOY for JIRA actions
- 26 Sep 2015 » Object Reflection in Groovy
- 22 Sep 2015 » Introducing Adaptavist Labs