Open cmoulliard opened 2 years ago
I don't know what the custom builder you're using is doing, but the problem is that when you do a pack build
, the Maven buildpack picks out the JAR to run and it's picking a JAR that's not executable. Thus no start command is set.
It matches target/*.jar
by default.
dmikusa@dmikusa-a01 ~/C/S/q/getting-started (main)> ls target/*.jar
target/getting-started-1.0.0-SNAPSHOT.jar
dmikusa@dmikusa-a01 ~/C/S/q/getting-started (main)> unzip -p target/getting-started-1.0.0-SNAPSHOT.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven 3.8.4
Built-By: dmikusa
Build-Jdk: 11.0.14
There's no Main-Class
entry.
You need to set $BP_MAVEN_BUILT_ARTIFACT
and point it to an executable JAR.
Hmm, it looks messier than that. I see ./target/quarkus-app/quarkus-run.jar
which is executable, but it has class-path settings that depend on other files in the ./target/quarkus-app/lib
directory.
You can make the Maven buildpack keep all of those files in /workspace
, but you will have multiple files in /workspace
and the paketo-buildpacks/executable-jar buildpack doesn't presently know how to find which one of the JAR files it should run. Is there a way to have Quarkus package up a fat JAR that contains all the dependency JAR files?
For what it's worth, we recently added support for Maven to persist multiple files into /workspace
but only paketo-buildpacks/native-image has been updated to work with multiple files. This was primarily added for Quarkus and Native Image builds, which is a scenario that does presently work.
pack build getting-started -e BP_NATIVE_IMAGE=true -e BP_MAVEN_BUILD_ARGUMENTS="-Dquarkus.package.type=native-sources -Dmaven.test.skip=true package" -e BP_MAVEN_BUILT_ARTIFACT="target/native-sources" -e BP_NATIVE_IMAGE_BUILD_ARGUMENTS_FILE="native-sources/native-image.args" -e BP_NATIVE_IMAGE_BUILT_ARTIFACT="native-sources/getting-started-1.0.0-SNAPSHOT-runner.jar"
I'd like to add support for this but just haven't gotten to it yet. paketo-buildpacks/executable-jar needs some changes so it can find the right JAR.
@cmoulliard I recall it worked for me with uber-jar packaging, but I am not sure.
We really would prefer not having to use fat jar packaging as it comes with an overhead at runtime startup.
Any way to guide the build pack to that?
I don't think this buildpack will ever be part of paketo, it would have to be rewritten from the ground up.
Right now any work to support Quarkus in paketo would have to be done upstream AFAIK. The simplest way would be for their basic Java buildpack to at least support Quarkus' packaging format (like ours/this one does). If we want better support it would have to be a Quarkus specific buildpack, just like they have one for Spring Boot. But I've looked at that one and it's not something simple, it seems like a serious amount of work.
In the last buildpack meeting in RH I think it was mentioned that there was already some intention in upstream to support Quarkus, but I don't know the status of that.
@maxandersen I think @dmikusa-pivotal is already looking into fix to support [fast|legacy].jar.
@quintesse just recently there was added support for Quarkus native build. I tried it on simple project and it worked. But one must specify many envvars by hand.
pack build test-bp --builder gcr.io/paketo-buildpacks/builder:base \
-b paketo-buildpacks/graalvm -b paketo-buildpacks/java-native-image \
--trust-builder=true --pull-policy=always -v \
--env BP_MAVEN_BUILT_ARTIFACT="target/native-sources" \
--env BP_NATIVE_IMAGE_BUILD_ARGUMENTS_FILE="native-sources/native-image.args" \
--env BP_MAVEN_BUILD_ARGUMENTS="package -DskipTests=true -Dmaven.javadoc.skip=true -Dquarkus.package.type=native-sources" \
--env BP_NATIVE_IMAGE=1 \
--env BP_JVM_VERSION="11" \
--env BP_NATIVE_IMAGE_BUILT_ARTIFACT="native-sources/function-1.0.0-SNAPSHOT-runner.jar" \
--env BP_JVM_TYPE=JDK
@matejvasek aha ok, thanks for the update!
Btw, AFAIK it was always possible to run Quarkus (non-native) anyway, as long as you were okay with building your app in certain ways (eg using uber jars as you mentioned). I was more looking towards something that would be able to run a Quarkus app as-is, without any changes necessary. It seems that wouldn't be too hard to add (the changes for jboss' run-java.sh
weren't: https://github.com/quintesse/openjdk/commit/0864b463e79ddfe5b06b33386f9255a0d3923a82). But on the other hand perhaps upstream would see that as adding Quarkus-specific behaviour to an otherwise generic Java builder.
I was more looking towards something that would be able to run a Quarkus app as-is
Maybe there could be some slim Quarkus buildpack that would just prepare the envvars for the other participating buildpack (e.g. maven/native-image). But I don't know if that possible.
I'd like to add support for this but just haven't gotten to it yet. paketo-buildpacks/executable-jar needs some changes so it can find the right JAR.
Is there a ticket opened to support such a feature ? @dmikusa-pivotal
I tried it on simple project and it worked.
Is there a way to enable
the native build stack instead of passing as parameter the stacks to be used -b ....
to pack ? @matejvasek
Not yet. You need to pass right envvars so native-image BP knows what to compile. We might create some thin Quarkus BP that would populate those envvars automatically.
@quintesse what is best the way to determine what kind of build is used (fast,legacy,uber)?
also issue for non-native build https://github.com/paketo-buildpacks/executable-jar/issues/112 I'll try to fix it
what kind of build is used (fast,legacy,uber)?
I think that we should expose using an ENV var the type of java archive we would like to have as it will impact how the run image will start.
what is best the way to determine what kind of build is used (fast,legacy,uber)?
I'm not sure I understand correctly: "determine" by whom? Two options I see are: first, the builder could just set the required -D option to force it to use a specific kind of build. And secondly, if the first is not an option, because a generic builder is being used for example, then I think we can only look at the files being output. Just like I did for the Jboss script (https://github.com/quintesse/openjdk/commit/0864b463e79ddfe5b06b33386f9255a0d3923a82)
Two options I see are: first, the builder could just set the required -D option to force it to use a specific kind of build.
@quintesse Actually we might use this.
Originally I meant if we can detect how was the app build just by looking at target
content.
Determine might be incorrect word, what I meant is more like detect.
what I meant is more like detect.
Sure, like I mentioned, you might detect it by looking at the target
content as I did in the script I linked to.
It's very easy and supports all 3 formats supported by Quarkus.
For generic builders the problem might indeed be that they assume that there is only a single artifact needed to run the code, while Quarkus, depending on the build type chosen, can use several (as was mentioned by @dmikusa-pivotal).
Now for paketo we could perhaps simple say that we only support the uber-jar format for simplicity's sake, but the fast-jar format is actually preferred if we want to show off Quarkus' best side. Btw, that format is not only preferred because it's faster but also because all dependencies are separate files, which means they can be put in a different layer which makes (re)building the code faster as well.
I'll try to write a prototype of Quarkus buildpack.
@matejvasek for paketo you mean?
@quintesse yes paketo
Out of curiosity, is there a buildpack with Quarkus support in Paketo ? Or what is currently the recommended way to build Quarkus apps with CNB ?
Can you reply to Roland @BarDweller please ?
@rhuss as with s2i
you just need to set some envvars.
- name: BP_MAVEN_BUILT_ARTIFACT
value: func.yaml target/quarkus-app/lib/ target/quarkus-app/*.jar target/quarkus-app/app/
target/quarkus-app/quarkus/
- name: BP_MAVEN_BUILD_ARGUMENTS
value: package -DskipTests=true -Dmaven.javadoc.skip=true -Dquarkus.package.type=fast-jar
or use uber-jar (set it in application.properties)
I'll add bp for it in near future.
Thanks @matejvasek, for the great workaround.
From a user's point of view it would be awesome though if a Quarkus build could be auto-detected as I suspect that Quarkus apps are not an uncommon use case and cnb is all about opinionated auto-detection, isn't it ?
Question/Issue
Will the paketo-buildpacks/java builder support the quarkus stacks of this project or be adapted to support to build a quarkus app as OOTB the container fails to start ?
Steps to reproduce
pack build quarkus_app -p ./ -B paketobuildpacks/builder:base
ERROR: failed to launch: determine start command: when there is no default process a command is required
If now, I build the quarkus app image using the image builder of this project, the container is well started and I can access the service
localhost:8080
FYI: @quintesse