I am upgrading a groovy app from JDK11 to JDK17. One error I had to debug was with the following code:
public static def getDayFromDate (Date date) {
return date[Calendar.DAY_OF_MONTH]
}
For those unfamiliar, in groovy, you can use the [] accessor as a stand-in for the groovy getAt(int)
function, so the above line is synonymous with return date.getAt(Calendar.DAY_OF_MONTH)
. I mention this just so I can refer to the getAt
function without introducing a name out of nowhere.
getAt()
, in the context of java.util.Date, saves you from having to write the below:
public static def getDayFromDate (Date date) {
Calendar calendar = Calendar.getInstance()
calendar.setTime(date)
return calendar.get(Calendar.DAY_OF_MONTH)
}
And Calendar.DAY_OF_MONTH
is just a built-in java.util.Calendar enumerator that equates to the int 5
.
Nothing complicated so far.
Well after upgrading to Java 17 and Groovy 4.0, my line of code started complaining.
groovy.lang.MissingMethodException: No signature of method: java.util.Date.getAt() is applicable for argument types: (Integer) values: [5]
So I checked it out, and sure enough, I found that getAt
is now expecting a String parameter instead of an int.
Ultimately, the working code is now
public static def getDayFromDate (Date date) {
return date["date"]
}
So now it seems it's using the Object class's getAt(String)
to retrieve the property via mapping, instead of java.util.Date's getAt(int)
which short circuits the Calendar
code.
(For reference, using the 3-line Calendar code above works perfectly, but I kept digging because I wanted to understand why getAt wasn't working).
I suspected this might also be an IntelliJ problem, so I ran my tests via the terminal too. getAt(Calendar.DAY_OF_MONTH)
fails. getAt("date")
works. IntelliJ doesn't seem to have anything to do with it.
I'm glad to have working code, but it's really bothering me that I don't understand why or how it's changed. I'd much prefer to stick with the enumerated value if possible.
My gradle groovy import has changed from
implementation 'org.codehaus.groovy:groovy-all:2.4.15'
to
implementation 'org.apache.groovy:groovy-all:4.0.20'
Per this groovy changelog, Seems like the java.util.Date extensions were moved to a separate groovy-dateutil module after groovy 2.5. I was jumping from 2.4.15 to 4.0.20.
Adding implementation "org.apache.groovy:groovy-dateutil:4.0.20"
to my build.gradle restored the missing functionality!