Search code examples
spring-bootpaketo

How to specify an alternative main class in spring boot using bootBuildImage and packeto


When calling the spring boot plugin bootBuildImage task in gradle, a docker image is created using packeto. It starts the main class specified in the springBoot plugin. Below you can find an excerpt of the build.gradle file.

springBoot {
    mainClass = 'MyMainApp'
}


bootBuildImage {
    imageName = "$docker_repo/${project.name}"
}

When calling docker run, docker will run a container starting MyMainApp.

However, I want to run an alternative main class, using the same docker image. I tried the following:

  • specifying -Dloader.main=MyOtherApp as the cmd in docker run
  • specifying -Dloader.main=MyOtherApp in the JAVA_TOOL_OPTIONS environment variable
  • specifying LOADER_MAIN=MyOtherApp as an environment variable

None of those options start MyOtherApp.


Solution

  • An image created by Buildpacks provides some helpful tools for launching your application. While this is nice, overriding the default start command isn't as easy as just specifying a new command to docker run.

    All of the facilities provided by Buildpacks for starting up various processes in an image are described in the docs.

    I'm guessing here a bit, but it sounds like you want to run your own custom process (not the process detected by the buildpack), so try this one here.

    You can even override the buildpack-defined process types:

    docker run --rm --entrypoint launcher -it multi-process-app bash
    docker run --rm --entrypoint launcher -it multi-process-app echo hello "$WORLD" # $WORLD is evaluated on the host machine
    docker run --rm --entrypoint launcher -it multi-process-app echo hello '$WORLD' # $WORLD is evaluated in the container after profile scripts are sourced
    

    Java should be on the path, so you can run java -Dloader.main=MyOtherApp org.springframework.boot.loader.launch.PropertiesLauncher.

    https://www.baeldung.com/spring-boot-main-class#using-cli


    Alternatively, you could change your app to use PropetiesLoader by default & rebuild your image. The buildpack is just pulling the launcher for the start command out of the MANIFEST.MF file. You need to use PropertiesLauncher though as that is what supports loader.main. See https://stackoverflow.com/a/66367534/1585136.