gorm-hibernate5
gorm-hibernate5 copied to clipboard
GORM Data Services are not injected when deployed to Tomcat
When using GORM Data Services in a Grail app, everything works fine if the app uses the embedded tomcat, e.g. during testing and bootRun, and even started as a runnable jar.
But when the app is deployed to Tomcat all data services are null.
They are not added to the applicationContext at all, e.g. Holders.applicationContext.getBean('beerService')
results in a NoSuchBeanDefinitionException
.
Originally from this SO question.
Sample project
You can find a sample project showing the problem here: https://github.com/brianjohnsen/gorm-data-service-issue
Sanity check
- Run
./gradlew bootRun
- Verify that calling
curl http://localhost:8080/beer
returns an empty list[]
Steps to reproduce
- Checkout the sample project
- Run
./gradlew bootWar
- Copy the WAR to a Tomcat server, e.g.
cp build/libs/notworking.war ~/PATH/TO/LOCAL/TOMCAT/webapps/
- Start the Tomcat server, e.g.
./PATH/TO/LOCAL/TOMCAT/bin/startup.sh
- Calling the
/beer
endpoint now returns an Internal server error, e.g.curl http://localhost:8080/notworking/beer
returns{"message":"Internal server error","error":500}
. - Checking the log reveals that a
NullPointerException
is thrown because thebeerService
is not injected (ie.null
).
Stacktrace excerpt:
ERROR --- [nio-8080-exec-2] o.g.web.errors.GrailsExceptionResolver : NullPointerException occurred when processing request: [GET] /notworking/beer
Cannot invoke method count() on null object. Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method count() on null object
at gorm.data.service.issue.BeerController.index(BeerController.groovy:23)
at grails.gorm.transactions.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:94)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
at grails.gorm.transactions.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:91)...
I forked the project and it worked.
https://github.com/fernando88to/gorm-data-service-issue
@fernando88to when you say "worked" what du you mean exactly?
Have you deployed it to a Tomcat and confirmed that the data services are injected? If so, which version of Tomcat/Java/OS are you using?
I've tried combinations of following:
Java: 8.0.322-tem
and 8.0.302-open
Tomcat: 9.0.31
and 8.5.78
OS: Ubuntu 20.04
Hi @brianjohnsen, the version is in the file https://github.com/fernando88to/gorm-data-service-issue/blob/master/Dockerfile
tomcat:9.0.63-jdk11-temurin
In the file https://github.com/fernando88to/gorm-data-service-issue/blob/master/grails-app/init/gorm/data/service/issue/BootStrap.groovy I made an initial load.
Then I applied the following commands:
./gradlew build. docker build -t gormdataservice:0.1 .. docker run -it --rm -p 8080:8080 gormdataservice:0.1. Call curl http://localhost:8080/beer (return one register)
I will create a new dockerfile with the versions you mentioned.
@fernando88to Yeah, that's not exactly what I described.
I’m using bootWar
as the target and I think your version uses war
as the target.
Anyways, if I switch to using the war
target everything works and the data services are injected again.
It seems that the Spring Boot runnable jar stuff ruins the DI of data services.
Change the dockerfile to run with war runnable.
steps:
git clone https://github.com/fernando88to/gorm-data-service-issue.git cd gorm-data-service-issue ./gradlew build (with jdk 8) docker build -f Dockerfile_java_8_tem -t java_8_tem:0.1 . docker run -it --rm -p 8080:8080 java_8_tem:0.1 http://localhost:8080/beer return one register
The version of the jdk is eclipse-temurin:8u322-b06-jdk