cloudfoundry / java-buildpack

Cloud Foundry buildpack for running Java applications
Apache License 2.0
435 stars 2.58k forks source link

How to use this together with the apt-buildpack? #1023

Closed MasterEvarior closed 1 year ago

MasterEvarior commented 1 year ago

Hi there 😃

I'm trying to get a Spring Boot application running on my companies Cloud Foundry instance. The application also needs some things that need to be installed with apt. To install said things, I'm using the apt-buildpack.

When I push just the JAR for the application everything works as expected:

cf push my-spring-boot-app -f manifest.yml -p my-spring-boot-app.jar

The app then gets successfully built and deployed.

When I add the apt-buildpack to the manifest, the apt-buildpack is then successfully executed but the java-buildpack doesn't seem to find my jar. It throws the following error:

ERROR Compile failed with exception #<RuntimeError: No container can run this application. Please ensure that you’ve pushed a valid JVM artifact or artifacts using the -p command line argument or path manifest entry. Information about valid JVM artifacts can be found at https://github.com/cloudfoundry/java-buildpack#additional-documentation. >
No container can run this application. Please ensure that you’ve pushed a valid JVM artifact or artifacts using the -p command line argument or path manifest entry. Information about valid JVM artifacts can be found at https://github.com/cloudfoundry/java-buildpack#additional-documentation. 
Failed to compile droplet

My manifest.yml (which defines the buildpacks and the artifact(s) to upload) looks something like this:

caasp_version: 4
applications:
  - name: my-spring-boot-app
    path: ./target/app #Directory which includes the apt.yml and my-spring-boot-app.jar
    instances: 1
    memory: 2GB
    disk_quota: 2GB
    stack: cflinuxfs3
    buildpacks:
      - apt_buildpack
      - java_buildpack

I've already tried quite a few things to make it work:

Is there anything I can do so that the java_buildpack recognizes my JAR?

dmikusa commented 1 year ago

path: ./target/app #Directory which includes the apt.yml and my-spring-boot-app.jar

This would be convenient but it won't work. When you cf push, it'll push up the directory but the JBP expects the pushed artifacts to be the exploded JAR contents, not a directory with a JAR in it.

Off the top of my head, there are two ways you can make this work are:

  1. Pack the apt.yml into the root of your JAR file. Just modify Maven or Gradle to include it. It must be in the root of the jar, so if you run jar tf your-app.jar you should see apt.yml with no prefixed path.

  2. Explode your JAR locally, copy in apt.yml and then set the cf push path to the exploded JAR contents.

MasterEvarior commented 1 year ago

Thanks for the speedy help! I will try the two methods and report back tomorrow with some more Information on what I exactly did do and if it worked.

MasterEvarior commented 1 year ago

Method 2 is working flawlessly. To automated this with Maven I wrote a small shell script, that gets executed after the whole build process. This script gets called by a Maven plugin, copies and explodes the jar.

create-app-directory.sh

rm -rf "$1/target/app"
mkdir "$1/target/app"
cp $1/apt.yml $1/target/app/apt.yml
cp $1/target/my-spring-boot-app.jar $1/target/app/my-spring-boot-app.jar

cd $1/target/app
jar xfmy-spring-boot-app.jar

pom.xml

  <build>
        <plugins>
            <plugin>
                <artifactId>exec-maven-plugin</artifactId>
                <groupId>org.codehaus.mojo</groupId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <id>Create /app directory</id>
                        <phase>package</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <executable>/bin/bash</executable>
                            <arguments>
                                <argument>${basedir}/scripts/create-app-directory.sh</argument>
                                <argument>${basedir}</argument>
                            </arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Thanks again for your help, you can close the ticket if you want 😃