I built a simple CodePipeline for a SpringBoot Java application with 3 steps:
1 and 2 steps successfully pass while Deploy step fails. The only error I see in Elastic Beanstalk logs:
01_configure_application.sh] : Activity execution failed, because: Executing: /usr/bin/unzip -o -d /var/app/staging /opt/elasticbeanstalk/deploy/appsource/source_bundle
FileMagic v0.7.1: compiled magic version [5.21] does not match with shared library magic version [5.37]
Archive: /opt/elasticbeanstalk/deploy/appsource/source_bundle
inflating: /var/app/staging/microservices/my-service/target/my-service.jar
Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile.
Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile. (ElasticBeanstalk::ExternalInvocationError)
caused by: Executing: /usr/bin/unzip -o -d /var/app/staging /opt/elasticbeanstalk/deploy/appsource/source_bundle
FileMagic v0.7.1: compiled magic version [5.21] does not match with shared library magic version [5.37]
Archive: /opt/elasticbeanstalk/deploy/appsource/source_bundle
inflating: /var/app/staging/microservices/my-service/target/my-service.jar
Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile.
Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile. (Executor::NonZeroExitStatus)
My Buildspec:
build:
commands:
- mvn -P ci --settings settings.xml install -DskipTests
artifacts:
files:
- microservices/my-service/target/my-service.jar
If I deploy this jar directly to AWS Elastic Beanstalk using AWS Web Interface, it works perfectly.
Please, help me. I'm ready to share any other config on demand.
while Denys answer is correct i dont think it clearly explains the issue.
the artifact must be top level or at most one directory in depth when it is output under the artifacts
directive.
for example the default for a spring project using gradle is to output to <project root>/build/libs/<artifact name>.jar
after executing the bootJar
task
intuitively you would define something like this:
version: 0.2
phases:
install:
runtime-versions:
java: corretto8
build:
commands:
# bootJar task outputs to build/libs/<name>.jar
- ./gradlew bootJar
artifacts:
files:
- build/libs/<name>.jar
this build will succeed and upload a zipped artifact to S3. when that is unzipped you will get:
build/libs/<name>.jar
. you can confirm this by downloading the artifact from s3 and unzipping it yourself (just as elastic beanstalk does within the vm).
so when elastic beanstalk tries to deploy this it fails because it looks either for a top level <name>.jar
or at most somedir/<name>.jar
and you get that rather cryptic error message
Unable to launch application as the source bundle does not contain either a file named application.jar or a Procfile.
its cryptic because it implies that the artifact must either be named application.jar
or a Procfile must be added. neither of these are true
so the solution revolves around making that jar file top level. you can:
define your output artifact from your build tool as placing it top level (not ideal)
add a second command to the build
phase that moves that jar file out to the top level such as:
version: 0.2
phases:
install:
runtime-versions:
java: corretto8
build:
commands:
# bootJar task outputs to build/libs/<name>.jar
- ./gradlew bootJar
# move the jar (by wildcard, agnostic to its name) to top level app.jar
- mv build/libs/*.jar app.jar
artifacts:
files:
# publish the now top level app.jar as the artifact
- app.jar
the most appropriate solution is to make use of the post_build
directive which is designed for cleanup / reorganizing steps like this:
version: 0.2
phases:
install:
runtime-versions:
java: corretto8
build:
commands:
# bootJar task outputs to build/libs/<name>.jar
- ./gradlew bootJar
post_build:
commands:
# move the jar (by wildcard, agnostic to its name) to top level app.jar
- mv build/libs/*.jar app.jar
artifacts:
files:
# publish the now top level app.jar as the artifact
- app.jar
as a result when unzipped you will get app.jar
top level and elastic beanstalk is happy! note that app.jar
and build/libs
are arbitrary, set them however makes sense to you and your project. all that matters is that the artifacts.files
is a top level jar file. elastic beanstalk will take care of the rest
if you are new to CP or have a simple project there is no need to override with a config.yml
or add a Procfile
as suggested in other similar questions.
hope this helps someone else.
The problem was in artifact's sub-folders, it's impossible to use an artifact location as in my Buildspec:
artifacts:
files:
- microservices/my-service/target/my-service.jar
the only correct way is folder/myapp.jar
, for example:
artifacts:
files:
- target/my-service.jar
so you should specify outputDirectory
in your maven config if it is different
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.