grails-core icon indicating copy to clipboard operation
grails-core copied to clipboard

Issue with Grails4 & springloaded & Abstract classes

Open dularion opened this issue 5 years ago • 22 comments

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

dularion avatar Nov 06 '20 12:11 dularion

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

davydotcom avatar Nov 06 '20 15:11 davydotcom

Ill test it out soon! thanks

dularion avatar Nov 06 '20 15:11 dularion

@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

dularion avatar Nov 06 '20 21:11 dularion

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.

image

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.

dularion avatar Nov 16 '20 13:11 dularion

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

dularion avatar Nov 16 '20 18:11 dularion

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?

davydotcom avatar Nov 19 '20 14:11 davydotcom

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

dularion avatar Nov 19 '20 16:11 dularion

@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

dularion avatar Nov 19 '20 19:11 dularion

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.

Dirk-27 avatar Apr 01 '22 13:04 Dirk-27

Which version of Java do you use ? I've tried this solution with Java 11 and application doesn't start because classes error.

gelleouet avatar Apr 01 '22 15:04 gelleouet

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.

joelbard avatar May 13 '22 21:05 joelbard

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.

jaGarcia avatar Jul 26 '22 21:07 jaGarcia

@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 =(

purpleraven avatar Mar 16 '23 20:03 purpleraven

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

purpleraven avatar Mar 16 '23 20:03 purpleraven

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 avatar Mar 17 '23 07:03 Dirk-27

@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?

purpleraven avatar Mar 17 '23 15:03 purpleraven

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?

purpleraven avatar Mar 20 '23 15:03 purpleraven

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 avatar Mar 21 '23 07:03 Dirk-27

@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

purpleraven avatar Mar 21 '23 09:03 purpleraven

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 avatar Mar 21 '23 09:03 Dirk-27

@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)

purpleraven avatar Mar 24 '23 09:03 purpleraven

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

purpleraven avatar Mar 25 '23 07:03 purpleraven