While working on having the latest version of glu compile with jdk1.6 and run with either jdk1.6 or jdk1.7 I ran into the following error raised by groovy:
The issue
The issue gets triggered when running any groovy code compiled with jdk1.6 and running with jdk1.7 whenever you are throwing an exception that has been written in groovy (meaning your exception is defined in a .groovy
file).
The source of the problem
This exception is triggered by the following section in the groovy source code
This is pretty frustrating as the comment seems to indicate that this was added as a quick prototype. Also the numberOfConstructors
variable is not used in the remainder of the method!
In java 1.7, there is one more constructor that has been added to the java.lang.Exception
class (a first in many years!). So at runtime, the previous code simply fails and throws IncompatibleClassChangeError
.
The solution(s)
Compile and run under jdk1.7
If you don’t need the backward compatibility, you can always (re)compile your code with jdk1.7 and run with jdk1.7.
The problem here is that if you use any groovy library compiled with jdk1.6 (or earlier), then you will have the same problem.
Changing your groovy exceptions into java exceptions
Doing a quick search on the Internet, I realized I was not the only one and found this solution.
This solution does indeed work and if you can change all your exceptions that were groovy exceptions into java exceptions then the problem does go away.
The problem is that in my case, it was a lot of changes in several different projects.
Also you have the same issue as in the previous section: if you use any groovy library compiled with jdk1.6 (or earlier), then you will have the same problem.
Removing the “extra” constructor at runtime
I came up with a different approach which simply removes the extra constructor added by jdk1.7 at runtime. The reasoning behind this is, since I am compiling with jdk1.6 there is no way I can use this extra constructor in my code since it did not exist!
So here is what I did:
This code modifies the metaclass of the java.lang.Exception
class to remove the constructor added by jdk1.7. Note that this code is pretty safe to call many times but is recommended to be called as early as possible when you start your groovy application.
From my own testing this works very well and the original IncompatibleClassChangeError
is no longer thrown. I have asked for feedback on the groovy forum in regards to this solution but have not received any as of this writing.
Note that I am using groovy version 2.0.7 (and this problem remains on the (groovy) trunk as of this writing). I have not tried this solution with any other version of groovy.
Reference
ExceptionJdk17Workaround
full source code from github.