I want to put some tasks in Procfile file with Spring Boot application, the spring-boot-maven-plugin configuration as following:

          <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
               <version>2.5.0-RC1</version>
                <configuration>
                    <image>
                        <builder>paketobuildpacks/builder:full</builder>
                        <env>
                            <SERVICE_BINDING_ROOT>/bindings</SERVICE_BINDING_ROOT>
                        </env>
                    </image>
                </configuration>
            </plugin>

Then I create a Procfile with following code:

health: curl http://localhost:8080/actuator/health

Then I use mvn -DskipTests clean package spring-boot:build-image to build the docker image with following output:

[INFO]  > Running creator
[INFO]     [creator]     ===> DETECTING
[INFO]     [creator]     5 of 18 buildpacks participating
[INFO]     [creator]     paketo-buildpacks/ca-certificates   2.1.0
[INFO]     [creator]     paketo-buildpacks/bellsoft-liberica 7.1.0
[INFO]     [creator]     paketo-buildpacks/executable-jar    5.0.0
[INFO]     [creator]     paketo-buildpacks/dist-zip          4.0.0
[INFO]     [creator]     paketo-buildpacks/spring-boot       4.2.0

Procfile buildpack not detected by the builder.

Then I use command line pack build spring-boot25-demo:0.0.1-SNAPSHOT to build the app, and I get following output:

===> DETECTING
8 of 18 buildpacks participating
paketo-buildpacks/ca-certificates   2.1.0
paketo-buildpacks/bellsoft-liberica 7.1.0
paketo-buildpacks/maven             5.0.0
paketo-buildpacks/executable-jar    5.0.0
paketo-buildpacks/apache-tomcat     5.1.0
paketo-buildpacks/dist-zip          4.0.0
paketo-buildpacks/spring-boot       4.2.0
paketo-buildpacks/procfile          4.1.0

And procfile buildpack included by pack CLI.

Any special with spring-boot:build-image?

Comment From: scottfrederick

It appears that you are running the pack command from the root directory of the project, because the paketo-buildpacks/maven buildpack is being detected. This means that the entire contents of the project are being sent to the builder and the maven buildpack is building the project from source. If the Procfile is at the root of the project tree then the builder will detect it.

The Spring Boot Maven plugin always builds a jar or war file and then sends only the contents of the built archive to the builder. If Procfile is outside of the source tree (for example, /src/main/resources) then it will not be included in the built archive and will not be sent to the builder. You would see the same behavior from pack if you used a command like pack build spring-boot25-demo:0.0.1-SNAPSHOT --path target/spring-boot25-demo-0.0.1-SNAPSHOT.jar.

Can you verify that your Procfile is not in the built jar or war?

Comment From: linux-china

@scottfrederick no luck to put Procfile in src/main/resources. Any hack way to include Procfile support with spring-boot:build-image? 😃

If I add Procfile into spring-boot25-demo-0.0.1-SNAPSHOT.jar with jar -uf spring-boot25-demo-0.0.1-SNAPSHOT.jar Procfile, then execute pack build spring-boot25-demo:0.0.1-SNAPSHOT --path target/spring-boot25-demo-0.0.1-SNAPSHOT.jar, and procfile buidpack will work. How to add Procfile into the jar file during repackage?

❯ pack build spring-boot25-demo:0.0.1-SNAPSHOT --path target/spring-boot25-demo-0.0.1-SNAPSHOT.jar
full: Pulling from paketobuildpacks/builder
Digest: sha256:47a1fafe5bdba85b20598150a281906a3c95f9d6055c26e584d52fe99843f7fc
Status: Image is up to date for paketobuildpacks/builder:full
full-cnb: Pulling from paketobuildpacks/run
Digest: sha256:2abec8028ac376bffa424a0f791bf979277ac1834324961157138fec0276fa09
Status: Image is up to date for paketobuildpacks/run:full-cnb
===> DETECTING
6 of 18 buildpacks participating
paketo-buildpacks/ca-certificates   2.1.0
paketo-buildpacks/bellsoft-liberica 7.1.0
paketo-buildpacks/executable-jar    5.0.0
paketo-buildpacks/dist-zip          4.0.0
paketo-buildpacks/spring-boot       4.2.0
paketo-buildpacks/procfile          4.1.0

I added exec-maven-plugin to add Procfile into repackaged jar, but procfile can not been detected.

<plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>jar</executable>
                    <!-- optional -->
                    <workingDirectory>${project.build.directory}</workingDirectory>
                    <arguments>
                        <argument>-uf</argument>
                        <argument>${project.build.finalName}.jar</argument>
                        <argument>../Procfile</argument>
                    </arguments>
                </configuration>
            </plugin>

Comment From: scottfrederick

@linux-china I've been looking into some ways to make this work, but I have not come up with a hack using the Spring Boot Maven plugin. The paketo-buildpacks/procfile buildpack requires that the Procfile be at the root of the directory structure that is sent to the builder, but there's not a way to add a file to the root with the Maven plugin.

The Maven plugin does not unpack the archive generated by Boot's repackage goal and send the unpacked contents to the builder. Instead it sends the class files, resources, and dependent jars in the same layout as repackage uses to build the jar file by generating the proper layout during the upload processing. This is why the exec-maven-plugin trick doesn't work, and there's not a way to configure the plugin to copy a file to a location outside of the layout's defined structure.

This is possible with the Spring Boot Gradle plugin, as the Gradle plugin has more flexibility to include files outside of the defined layout. With a typical Gradle project and a Procfile in the root of the project, this configuration in build.gradle will work:

bootJar {
    from(project.rootDir) {
        include 'Procfile'
    }
}

I'm tagging this issue for team attention so we can discuss whether we can do anything to improve the situation with the Maven plugin.

Comment From: wilkinsona

https://github.com/spring-projects/spring-boot/issues/6626 Is related to this. As summarised in this issue by @nebhale, placing things in the root of the jar is problematic as it pollutes the application’s classpath:

My main problem with this whole thing is that the design of the .profile and .profile.d feature in Cloud Foundry doesn't take into account how Java classpaths work. As you say, putting anything in the root of the application (which is what is required by this feature) means that it will be exposed on the class path of the application, which can lead to unanticipated behavior.

Comment From: scottfrederick

After some discussion, we've decided to close this issue as a duplicate of #6626.

I've also created an issue in the Paketo procfile buildpack repository to see if there's a better way to support this specific use case without polluting a jar or war file with a Procfile.