Johan Vergeer
Johan Vergeer

Reputation: 5578

Spring Boot Resources in Docker container

I'm using Docker for a Spring Boot application and so far everything is working.

I have a resource file in src/main/resources/db/data/dummydata.csv

In a bootstrap class this file is used to import the dummy data into the database.

private fun getDummyData(): List { var fileReader: BufferedReader? = null

val dummyData = ArrayList<DummyDataEntity>()

try {
    var line: String?

    val res = ResourceUtils.getFile("classpath:db/data/dummydata.csv")
    fileReader = BufferedReader(FileReader(res.path))

    // Read CSV header
    fileReader.readLine()

   ... Processing the data ...

} catch (e: Exception) {
    e.printStackTrace()
} finally {
    try {
        fileReader!!.close()
    } catch (e: Exception) {
        e.printStackTrace()
    }

    return dummyData
}

}

When I run the application in IntelliJ, everything works just fine, but when I'm running it in Docker it cannot be found.

The Jar and the Docker image are created using Kotlin DSL Gradle.

import com.palantir.gradle.docker.DockerExtension
import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension
import org.gradle.tooling.model.GradleTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.springframework.boot.gradle.tasks.bundling.BootJar

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath(Libs.springBootGradlePlugin)
        classpath(Libs.kotlinGradlePlugin)
        classpath(Libs.kotlinAllOpen)
        classpath(Libs.gradleDocker)
    }
}

plugins {
    // Apply the java-library plugin to add support for Java Library
    `java-library`
}

apply {
    plugin("kotlin")
    plugin("kotlin-spring")
    plugin("org.springframework.boot")
    plugin("io.spring.dependency-management")
    plugin("com.palantir.docker")
}

repositories {
    mavenCentral()
}

dependencies {
    compile(Libs.kotlinReflect)

    // Spring Boot
    compile(Libs.springBootStarterDataJpa)
}

configure<DependencyManagementExtension> {
    imports {
        mavenBom(Libs.vaadinBom)
    }
}

val bootJar: BootJar by tasks
bootJar.baseName = "reporting-app-site"
bootJar.version = "0.0.1"

configure<DockerExtension> {
    name = "brabantia/${bootJar.baseName}"
    files(bootJar.archivePath)
    buildArgs(mapOf("JAR_FILE" to bootJar.archiveName))
    dependsOn(tasks["build"])
}

val compileKotlin: KotlinCompile by tasks
compileKotlin.kotlinOptions.jvmTarget = "1.8"

The Jar does contain BOOT-INF/classes/db/data/dummyData.csv but when the application is run the error that is thrown is

java.io.FileNotFoundException: class path resource [db/data/dummydata.csv] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/db/data/dummydata.csv

What am I missing here?

Upvotes: 5

Views: 13391

Answers (1)

Jeryl Cook
Jeryl Cook

Reputation: 1038

The below worked for me.., you need to use an InputStream and not a File.

...

@Autowired
private ResourceLoader resourceLoader;

...

  Resource resource= resourceLoader.getResource("classpath:/account_info.html");

    InputStream inputStream= resource.getInputStream();

    Assert.notNull(inputStream,"Could not load template resource!");

    String email = null;

    try {
        byte[] bdata = FileCopyUtils.copyToByteArray(inputStream);
        email = new String(bdata, StandardCharsets.UTF_8);
    } catch (IOException e) {
        logger.warn("IOException", e);
    }finally {
        if ( inputStream != null) {
            IOUtils.closeQuietly(inputStream);
        }
    }

Upvotes: 10

Related Questions