In a Gradle Spring Boot project, how do I declare dependencies that are used only at the local runtime?… here is a solution to the problem.
In a Gradle Spring Boot project, how do I declare dependencies that are used only at the local runtime?
I have a Spring Boot application built with Gradle that connects to a database. When running locally, it is usually more convenient to run in an in-memory database (in this case, h2) than to connect to a real instance of the database. To do this, the application declares a custom BootRun
task to run the application locally. How do I ensure that h2 dependencies are available when running locally, but not included in the generated Spring Boot jar?
File:
build.gradle
import org.springframework.boot.gradle.tasks.run.BootRun
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.5.RELEASE")
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '2.1.1.RELEASE'
id "io.spring.dependency-management" version "1.0.6.RELEASE"
}
group 'test'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-jdbc"
compile "..." // Dependency for the real, non-in memory, database goes here
compile "com.h2database:h2" // How can I make sure this isn't included in the resulting jar?
}
task bootRunLocal(type: BootRun, group: ApplicationPlugin.APPLICATION_GROUP, dependsOn: classes) {
main = 'test. BootApplication'
classpath = sourceSets.main.runtimeClasspath
systemProperty "spring.profiles.active", "local-db-h2"
}
Application.yml
spring:
datasource:
# Default and non-in-memory datasource configuration goes here
---
spring:
profiles: local-db-h2
datasource.url: jdbc:h2:mem:testdb; MODE=Oracle
datasource.platform: h2_local
Test/BootApplication.java
package test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;
@SpringBootApplication
public class BootApplication implements CommandLineRunner {
@Autowired
private JdbcTemplate jdbcTemplate;
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
@Override
public void run(String... args) {
jdbcTemplate.query("SELECT 1", row -> {});
}
}
Solution
The solution I currently implement uses custom Gradle configuration for h2 dependencies.
build.gradle
configurations {
localDatabase
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-jdbc"
compile "..." // Dependency for the real, non-in memory, database
localDatabase 'com.h2database:h2'
}
task bootRunLocal(type: BootRun, group: ApplicationPlugin.APPLICATION_GROUP, dependsOn: classes) {
main = 'test. BootApplication'
classpath = sourceSets.main.runtimeClasspath + configurations.localDatabase
systemProperty "spring.profiles.active", "local-db-h2"
}