Issue with Grails4 & springloaded & Abstract classes
Hi guys, We found your springloaded implementation here https://github.com/grails/grails-core/pull/11441 and were so stoked, because we have one of those big 3-minute restart projects (not quite, more like 1 minute, but still too long for an efficient workflow).
But then we ran into an issue with abstract classes, see sample project (and readme) here: https://github.com/dularion/grails4_springloaded
Very simple class structure:
// the abstract class
abstract class BasexAssociation {
protected String name
BasexAssociation() {
}
}
// the subclass
class BasexEntityReference extends BasexAssociation {
String status
BasexEntityReference(String name, String status) {
this.name = name //this will break the application, because it sets the property of the abstract superclass
this.status = status
}
}
// a grails controller calling the constructor of BasexEntityReference
class TestController {
def test(){
def basexEntityReference = new BasexEntityReference("hello", "open") //this kills the application
render basexEntityReference.name
}
}
Start the application and then visit: http://localhost:8080/test/test
the application then dies, with this error.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x0000000000000000, pid=36877, tid=25603
#
# JRE version: Java(TM) SE Runtime Environment (8.0_40-b26) (build 1.8.0_40-b26)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.40-b25 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C 0x0000000000000000
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/antonia/dev/projects/Sandbox/grails4_springloaded/hs_err_pid36877.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
Further in the log, you can find this:
Exception <a 'java/lang/ClassNotFoundException': basex/BasexEntityReferenceBeanInfo> (0x00000007ba7bc9b8) thrown at ...
Exception <a 'java/lang/ClassNotFoundException': basex/BasexAssociationBeanInfo> (0x00000007ba7e4368) thrown at ...
Exception <a 'java/lang/ClassNotFoundException': basex/BasexAssociationCustomizer> (0x00000007ba80d758) thrown at ...
Exception <a 'java/lang/ClassNotFoundException': basex/BasexEntityReferenceCustomizer> (0x00000007ba841310) thrown at ...
⚠️ If we remove the "abstract" keyword, it works great. What might be going on here?
Environment Information
- happens on Linux/Windows & Mac alike (tested on all systems)
- JDK 8
- Grails 4.1.0.M2
- springloaded (as outlined here https://github.com/grails/grails-core/pull/11441)
Example Application
https://github.com/dularion/grails4_springloaded
This is actually because of a change in spring. I have a forked version of spring-loaded that works very well. We are working to get it merged back into main branch and released
Ill test it out soon! thanks
@davydotcom I tried building your fork, but am getting a build error. Is this a known issue?
> Could not HEAD 'http://maven.springframework.org/milestone/org/aspectj/aspectjtools/1.8.0.M1/aspectjtools-1.8.0.M1.pom'. Received status code 403 from server: Forbidden
Building the original repo seems to work fine
Nevermind, we now got it to build, but we have a different issue now - loading the jar file manually doesnt seem to have any effect on the application, as though it is not loaded at all. Here a screenshot for reference.

If you have any idea what might be causing this, a syntax error or similar, we'd welcome the tip. otherwise we'll just keep looking.
Another status-update @davydotcom: we got it running using
jvmArgs(
"-javaagent:/Users/xyz/dev/projects/test/spring-loaded/springloaded/build/libs/springloaded-1.2.9.BUILD-SNAPSHOT.jar",
'-Dspring.output.ansi.enabled=always',
'-noverify',
'-XX:TieredStopAtLevel=1',
'-Xmx1024m')
which is great news, but now we have the same artifact-class issue as we did the the original springloaded release. @davydotcom is the correct branch on your fork this one? https://github.com/davydotcom/spring-loaded/commits/patch-type-registry-correct
This is the correct branch yes. this clears the reflection utils cache on reloads and fixes things for the most part. what part are you stuck on now exactly?
strange - i just used your jar in this test project and it works fine there! https://github.com/dularion/grails4_springloaded
So now i have to investigate what might be the issue in the other project. Getting back to you asap
@davydotcom I now dug deeper into it, and your version of spring-loaded does solve the artifact-issue, but another issue then arises. it crashes shortly after on any controller request, even empty ones, with this error: https://gist.github.com/dularion/7b27ea800c6f28eae4ac7102056a5783
There isnt really anything in there that would point me in the right direction as far as I can see - or do you understand it better?
As I wrote in my email to you, I would be willing to get paid individual consultancy on this also if you are available
We spent many hours looking for a solution to the long development cycle after moving our Grails app from 2.5.6 to 4.0.13.
Now we use this solution in build.gradle:
bootRun {
jvmArgs(
// javaagent: see
// - https://github.com/grails/grails-core/issues/11649
// - https://github.com/spring-projects/spring-loaded
// - find the jar here: https://repo.spring.io/ui/repos/tree/General/libs-snapshot-local/org/springframework/springloaded
"-javaagent:libs/springloaded-1.3.0.BUILD-20210404.024037-2.jar",
// ...
}
and we don't use spring-boot-devtool
dependencies {
// developmentOnly("org.springframework.boot:spring-boot-devtools")
...
}
In application.groovy we have to set
spring.devtools.restart.enabled = false
although the devtools aren't referenced in the dependencies.
No we have the behaviour of grails 2.5.6 for the recompiling of the classes. This works with Grails 4.0.13.
Which version of Java do you use ? I've tried this solution with Java 11 and application doesn't start because classes error.
Has anyone had this work with Grails 5.1.7? jdk 1.8 with bootRun configured as above I get no effect when I save a change in a controller using OSX.
I ran into this problem with abstract class being used as a base class for exception handling. Creating the explicit getter/setters for the abstract class instead of leaning on groovy to auto create then appears to have mitigated the issue. still doing further testing.
@Dirk-27 @dularion what is the latest recomended version of springloaded for grails? Issue with transactional annotation https://github.com/grails/grails-core/issues/12630#issuecomment-1196611476 annoing me =(
I see the same error but with another reason
# Problematic frame:
# C 0x0000000000000000
Compilation events (10 events):
Event: 84.853 Thread 0x00007f8a414a4800 13693 1 org.grails.datastore.gorm.GormEnhancer::$getCallSiteArray (40 bytes)
Event: 84.853 Thread 0x00007f8a414a4800 nmethod 13693 0x00007f8a32ad3f90 code [0x00007f8a32ad4120, 0x00007f8a32ad44b8]
Event: 84.853 Thread 0x00007f8a414a4800 13694 1 org.grails.datastore.gorm.GormEnhancer::findTenantId (164 bytes)
Event: 84.854 Thread 0x00007f8a414a4800 nmethod 13694 0x00007f8a32ad4690 code [0x00007f8a32ad48e0, 0x00007f8a32ad5118]
Event: 84.855 Thread 0x00007f8a414a4800 13695 1 org.springsource.loaded.ri.ReflectiveInterceptor::jlrFieldGetBoolean (68 bytes)
Event: 84.855 Thread 0x00007f8a414a4800 nmethod 13695 0x00007f8a32ad5790 code [0x00007f8a32ad5960, 0x00007f8a32ad5c48]
Event: 84.856 Thread 0x00007f8a414a4800 13696 1 io.micronaut.core.annotation.AnnotationMetadata$$Lambda$614/802270602::apply (16 bytes)
Event: 84.856 Thread 0x00007f8a414a4800 nmethod 13696 0x00007f8a32ad5f90 code [0x00007f8a32ad6100, 0x00007f8a32ad62d8]
Event: 84.856 Thread 0x00007f8a414a4800 13697 1 io.micronaut.core.annotation.AnnotationMetadata::lambda$getValue$1 (7 bytes)
Event: 84.856 Thread 0x00007f8a414a4800 nmethod 13697 0x00007f8a32ad6450 code [0x00007f8a32ad65c0, 0x00007f8a32ad6738]
Internal exceptions (10 events):
Event: 67.734 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassNotFoundException': grails/artefact/DomainClassCustomizer> (0x00000000f2f44280) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal/tar/corretto-build/buildRoot/hot
Event: 67.734 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassNotFoundException': grails/gorm/EntityCustomizer> (0x00000000f2f827c8) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal/tar/corretto-build/buildRoot/hotspot/src/
Event: 67.735 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassNotFoundException': org/grails/datastore/mapping/dirty/checking/DirtyCheckable$Trait$FieldHelperCustomizer> (0x00000000f3006290) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers
Event: 67.735 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassNotFoundException': org/grails/datastore/gorm/GormValidateable$Trait$FieldHelperCustomizer> (0x00000000f3078ad8) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal
Event: 67.738 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassNotFoundException': org/grails/datastore/gorm/validation/constraints/MatchesConstraintBeanInfo> (0x00000000f3175a50) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/unive
Event: 67.739 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassNotFoundException': org/grails/datastore/gorm/validation/constraints/MatchesConstraintCustomizer> (0x00000000f31eef98) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/uni
Event: 67.747 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassCastException'> (0x00000000f33fb1a8) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal/tar/corretto-build/buildRoot/hotspot/src/share/vm/runtime/sharedRuntime.cpp
Event: 67.747 Thread 0x00007f5f78016800 Exception <a 'java/lang/reflect/InvocationTargetException'> (0x00000000f33fb968) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal/tar/corretto-build/buildRoot/hotspot/src/share/vm/runtime/re
Event: 67.747 Thread 0x00007f5f78016800 Exception <a 'java/lang/ClassCastException'> (0x00000000f33fc1d8) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal/tar/corretto-build/buildRoot/hotspot/src/share/vm/runtime/sharedRuntime.cpp
Event: 67.747 Thread 0x00007f5f78016800 Exception <a 'java/lang/reflect/InvocationTargetException'> (0x00000000f33fc998) thrown at [/home/jenkins/node/workspace/Corretto8/generic_linux/x64/build/Corretto8Src/installers/linux/universal/tar/corretto-build/buildRoot/hotspot/src/share/vm/runtime/re
springloaded-1.3.0
We still use it with grails 4.0.13 after downloading the jar from here : https://repo.spring.io/artifactory/libs-snapshot-local/org/springframework/springloaded/1.3.0.BUILD-SNAPSHOT/springloaded-1.3.0.BUILD-20210404.024037-2.jar
I'm very interested in a solution for grails 5. When you find one please inform me.
The only suggestion I found for grails 5 was to disable the dev-tools so that there is no automaticaly boot start on file changes and to use the ide to compile the classes on the fly -> normal hotspot deployment. But this works only, when you don't change the classes api (which is mostly the case).
@Dirk-27 I don't know why, but with 1.3.0 version, and with provided snapshot hot reload not working at all. I see recompilation in the log, but changes not applied. For example I have added to a controller action logs, but don't see it during action execution
log.error "!!!!!!!!!!!!!!!!!!!!"
I have seen same problem with grails 4x, and now reproduce it with 5.3.2
Any ideas?
with new spring loaded I have the same JVM crash for my main and most complex application
# SIGSEGV (0xb) at pc=0x0000000000000000, pid=154837, tid=0x00007efe6e1ff640
#
# JRE version: OpenJDK Runtime Environment (8.0_362-b08) (build 1.8.0_362-b08)
# Java VM: OpenJDK 64-Bit Server VM (25.362-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C 0x0000000000000000
#
RAX=0x0000000000000000 is an unknown value
RBX={method} {0x00007efe2d0483d8} '<init>' '()V' in 'java/lang/AbstractMethodError'
RCX=0x00000000eb578118 is an oop
java.lang.IllegalStateException
- klass: 'java/lang/IllegalStateException'
RDX=0x00007efe5700809d is at code_begin+2301 in an Interpreter codelet
invoke return entry points [0x00007efe570077a0, 0x00007efe57008180] 2528 bytes
RSP=0x00007efe6e1f8058 is pointing into the stack for thread: 0x00007efe68016000
RBP=0x00007efe6e1f80b0 is pointing into the stack for thread: 0x00007efe68016000
RSI=0x0000000000000000 is an unknown value
RDI=0x0000000000000000 is an unknown value
R8 ={method} {0x00007efe2d0483d8} '<init>' '()V' in 'java/lang/AbstractMethodError'
R9 =0x0000000000000000 is an unknown value
R10=0x00007efe6dc48e00: <offset 0x1048e00> in /home/xxxx/.jdks/corretto-1.8.0_362/jre/lib/amd64/server/libjvm.so at 0x00007efe6cc00000
R11=0x00007efe6e1f7e80 is pointing into the stack for thread: 0x00007efe68016000
R12=0x0000000000000000 is an unknown value
R13=0x00007efe6e1f8060 is pointing into the stack for thread: 0x00007efe68016000
R14=0x00007efe6e1f80d0 is pointing into the stack for thread: 0x00007efe68016000
R15=0x00007efe68016000 is a thread
Compilation events (10 events):
Event: 68.798 Thread 0x00007efe694a2800 13679 1 org.grails.datastore.mapping.dirty.checking.DirtyCheckable$Trait$Helper$markDirty::<init> (15 bytes)
Event: 68.798 Thread 0x00007efe694a2800 nmethod 13679 0x00007efe58ae6010 code [0x00007efe58ae6180, 0x00007efe58ae6388]
Event: 68.798 Thread 0x00007efe694a2800 13680 ! 1 org.grails.datastore.mapping.dirty.checking.DirtyCheckable$Trait$Helper$markDirty::call (40 bytes)
Event: 68.798 Thread 0x00007efe694a2800 nmethod 13680 0x00007efe58ae6610 code [0x00007efe58ae67c0, 0x00007efe58ae6ac8]
Event: 68.798 Thread 0x00007efe694a2800 13681 1 org.grails.datastore.gorm.GormEnhancer::$getCallSiteArray (40 bytes)
Event: 68.799 Thread 0x00007efe694a2800 nmethod 13681 0x00007efe58ae6e50 code [0x00007efe58ae6fe0, 0x00007efe58ae7378]
Event: 68.799 Thread 0x00007efe694a2800 13682 1 org.grails.datastore.gorm.GormEnhancer::findTenantId (164 bytes)
Event: 68.799 Thread 0x00007efe694a2800 nmethod 13682 0x00007efe58ae7550 code [0x00007efe58ae77a0, 0x00007efe58ae7fd8]
Event: 68.800 Thread 0x00007efe694a2800 13683 1 org.springsource.loaded.ri.ReflectiveInterceptor::jlrFieldGetBoolean (68 bytes)
Event: 68.801 Thread 0x00007efe694a2800 nmethod 13683 0x00007efe58ae8650 code [0x00007efe58ae8820, 0x00007efe58ae8b08]
Any idea how to localise the problem?
When exactly the same code works for me, there is not a problem in the code. Give it a try using another jdk: search for openJDK 8 or use this: https://adoptium.net/de/temurin/releases/?version=8.
BTW; I don't know corretto: Is it ok, that you see OpenJDK with corretto libs in the path? I expect something like /home/xxxx/.jdks/openjdk-1.8.0_362/jre/... in the heap dump?
@Dirk-27 i have the problem only on huge 15 years old project with many plugins
For another 4 simpler projects everithing works well. I have tested with 2 different JVMs, correto and zolo
Will test on open jdk.
For me more important to know, how I can localize the problem. More logs? Debugging? I have never debug an agents and have no idea where to go
I think debbuging this needs too much time even if you have the knowledge. I would add dependencies to one working project (always start from a working example) until you get the problem. The agent seems not to be the problem, one dependency causes it.
@Dirk-27 I have found the reason. Again abstract, but in Domains inheritance. I have had an abstract parent of a domain. Now I just commented the abstract key word and continue testing. But aplication already started and hot swap working well with grails 5 ! (except I need to find a replacement for abstract class)
As I can see, Grails 5 again has problem with abstract controllers and domains classes. Could somebody guide me, how the problem was solved for grails 4 in spring loaded. I simply can't find a patch in the https://github.com/spring-projects/spring-loaded/commits/master