grails-core
grails-core copied to clipboard
5.0.0.RC2: HSQLDB or H2 should not be part of built artifact, when not defined in build.gradle
I created a fresh Grails 4.0.8 application and tried to exclude h2 from the resulting build artifact. Is tried to simply remove the h2 dependency from build.gradle. But h2 is still somehow referenced and can be found in the .war file. Also I found that HSQLDB is included as well.
I remember from Grails 3.x applications that it should be to possible to exclude h2 by this, but this doesn't seem to work anymore:
compile "org.grails:grails-dependencies", {
exclude group:'com.h2database', module:'h2'
}
From ./gradlew dependencies it seems h2/hsqldb gets included from grails-plugin-datasource, so I tried it this way:
compile "org.grails:grails-plugin-datasource", {
exclude group:'com.h2database', module:'h2'
}
This doesn't work either. But even if it would work, I don't think this is a reasonable default behavior, as no one really uses h2/hsqldb in production.
Task List
- [x] Steps to reproduce provided
- [ ] Stacktrace (if present) provided
- [ ] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
Steps to Reproduce
- grails create-app mytest
- cd mytest
- remove "h2" from build.gradle
- ./gradlew assemble
Expected Behaviour
HSQLDB and h2 should not be included in the resulting artifact.
Actual Behaviour
Both HSQLDB and h2 are found.
$ unzip -t ./build/libs/mytest-0.1.war | grep h2
testing: WEB-INF/lib/h2-1.4.199.jar OK
$ unzip -t ./build/libs/mytest-0.1.war | grep hsqldb
testing: WEB-INF/lib/hsqldb-1.8.1.1.jar OK
Environment Information
- Operating System: Windows 10
- Grails Version: 4.0.8
- JDK Version: 11
Haven't checked this specifically with h2 or hsqldb, but you can try to move the dependency to provided scope (explicitly adding the library in provided scope).
provided group: 'com.h2database', name: 'h2', version: '1.4.200'
In this case gradle should not pack specified library in resulting jar/war file.
@yuri1969 I did test with the new Grails version 5.1.4 today and the hsqldb dependency is now gone from the build artifact.
But it seems that H2 is still included:
$ ./gradlew -q dependencyInsight --singlepath --dependency "com.h2database:h2" --configuration productionRuntimeClasspath
com.h2database:h2:1.4.200
variant "runtime" [
org.gradle.status = release (not requested)
org.gradle.usage = java-runtime
org.gradle.libraryelements = jar
org.gradle.category = library (not requested)
Requested attributes not found in the selected variant:
org.gradle.dependency.bundling = external
]
Selection reasons:
- Selected by rule
- By constraint
com.h2database:h2:1.4.200
\--- io.micronaut:micronaut-bom:3.3.4
\--- io.micronaut.spring:micronaut-spring-context:4.1.0
\--- org.grails:grails-core:5.1.4
\--- productionRuntimeClasspath (requested org.grails:grails-core)
H2 seems to be coming from micronaut-bom, which I don't understand. Shouldn't the BOM just define versions and not actually include anything?
@davidkron You are right, the H2 somehow slipped and is still a part of the 5.1.4 build artifact regardless of the build.gradle declaration.
$ ./gradlew dependencies --configuration productionRuntimeClasspath suggests it's defined in core's grails-dependencies:
...
| | +--- org.grails:grails-dependencies -> 5.1.4
| | | +--- org.grails:grails-bootstrap:5.1.4 (*)
| | | +--- org.grails:grails-plugin-rest:5.1.4 (*)
| | | +--- org.grails:grails-plugin-databinding:5.1.4 (*)
...
| | | \--- com.h2database:h2:1.4.200
...
I'll try to look into that.
@davidkron Update: The default Grails web profile pulls a newish asset-pipeline-grails version which seems to employ strange dependency configurations - attempting to solve that via a PR.
The rest-api Grails profile is unaffected by that as revealed during testing of #12391.
I created a fresh Grails 4.0.8 application and tried to exclude h2 from the resulting build artifact. Is tried to simply remove the h2 dependency from build.gradle. But h2 is still somehow referenced and can be found in the .war file. Also I found that HSQLDB is included as well.
Can you do this?
configurations.all {
exclude module: 'h2'
exclude module: 'hsqldb'
}
H2 seems to be coming from micronaut-bom
@davidkron That is true, but that is only 1 of the places. By default, there are multiple dependencies in newly created 5.1.4 app which have transitive dependencies on h2.
H2 seems to be coming from micronaut-bom
@davidkron That is true, but that is only 1 of the places. By default, there are multiple dependencies in newly created 5.1.4 app which have transitive dependencies on h2.
That micronaut-bom-related one is marked as dependency constraint. Thus it should not pull the H2 itself, right?
@yuri1969 You are right about the asset-pipeline-grails. I created a new grails project and removed the h2 and asset-pipeline-grails dependencies and with this h2 doesn't appear anymore in the built artifact. And it really seems that the problem is actually grails-dependencies and I am wondering what this dependency is even for: neither a newly created grails application or plugin includes this dependency. Also when I look at the pom at Maven Central https://search.maven.org/artifact/org.grails/grails-dependencies/5.2.2/pom it doesn't look valid to me: as far as I understand there are no api and runtimeOnly scopes in the Maven World (maybe unknown scopes simply resolve to compile as it is the default scope?).
Has there been any way to exclude h2 from the built war file? The 1.4.200 version of H2 now has security vulnerabilities hence having it the production war file is problematic.
- CVE-2022-23221
- CVE-2021-42392
- CVE-2021-23463
@davidkron Recently, Grails 5.2.5 has updated the base profile to 5.1.1. That one includes updated asset-pipeline to 3.4.7 which includes the PR fixing ~~it~~ the problem of exposed H2 dependency.
This means any app using the default profile based on the newest release of Grails 5.2.5 should be free of any implicit H2 dependency. The only remaining one should be the explicit one located in build.gradle.
After removing that one, $ ./gradlew dependencies --configuration productionRuntimeClasspath | grep h2 lists no H2. The same goes for grep on a production WAR file.
@jchharris Did you try the latest Grails 5.2.5? Can you confirm H2 is still included in a production WAR file?
@yuri1969 I haven't yet. I am on Grails 5.2.4 and I had upgraded asset-pipeline to 4.0.0 but H2 was still appearing in the WAR. I will try upgrading Grails and report back.
@yuri1969 That solved it coming in through Grails itself, however some Grails plugins drag it in as well:
+--- org.grails.plugins:spring-security-ui:4.0.0-RC1
| +--- org.grails.plugins:spring-security-core:4.0.4 -> 5.1.1
| | +--- org.grails:grails-dependencies -> 5.2.5
| | | \--- com.h2database:h2:1.4.200
+--- org.grails.plugins:database-migration:4.1.0
| +--- org.liquibase.ext:liquibase-hibernate5:4.8.0 -> 4.16.1
| | \--- com.h2database:h2:2.1.214 -> 1.4.200
I'll see if I can get Gradle to exclude them
@jchharris You are right, I haven't checked the plugins... I'll see if I can go through at least some of them.
Thanks @yuri1969. I think "io.github.gpc:jms" may also have a similar problem. grails-dependencies is set as a runtime dependency.
The liquibase-hibernate-related H2 leak can be tracked under https://github.com/liquibase/liquibase-hibernate/pull/444.
@yuri1969 I've created PRs to fix the dependency leakage issue in the Grails Database Migration plugin as well as the Spring Security Core plugin.
@jchharris I don't fully understand the reasoning behind grails-dependencies, but it seems grails-dependencies provides an odd set of test and non-test dependencies. Correct me if I'm wrong, but H2 should be a test dependency unlike org.grails.plugins.gsp and the others.
@yuri1969 I'm not sure, but if you create a new Grails plugin or app off of 5.2.5, grails-dependencies is not in the Gradle build file. Seems like something has changed along the line and it should no longer be a dependency. Would need some clarification on this from @puneetbehl
And another one: https://github.com/sbglasius/external-config/issues/64