Hi there!
We build our SpringBoot application with a BootJar task (which inherits from Jar) in Graddle, and the new containerizingMode = 'packaged' feature hard-codes the task name to jar:
Would it possible to have this name configurable?
Like:
jib {
jarTaskName = 'bootJar'
}
(or pass the task object directly, or even explicitly the path to the jar file)
I have currently worked around that by pointing the attributes of jar to bootjar:
jar {
enabled = false
destinationDir = tasks.bootJar.getDestinationDir()
archiveName = tasks.bootJar.getArchiveName()
}
I guess another alternative could be (not tested and I'd like not to have to rename my bootJar task):
task jar(type: BootJar) {
...
}
The one issue, and I think @chanseokoh can confirm, is that this isn't support for fatJar types. It's just Jars with dependencies still added into the container separately.
Hmm... this sounds familiar. I wonder if we should do the same for bootJar as in #1786. But I'm not entirely sure if the interaction between jar and bootJar is same as war and bootWar.
But as @loosebazooka mentioned, you should avoid containerizing a fat JAR, as it results in duplicating dependencies.
So, I think this issue is basically a feature request to support containerizing a fat JAR.
Hi @loosebazooka, thank you for quick reply, I actually just opened another issue about that #1852, though it would be separate problems (If it's by design, both will be quickly closed I guess). I'm pretty new to building Java apps/Gradle, I'm probably missing some pieces.
@maxbrunet I am trying this now. But I just realized that even though your workaround makes Jib pick up the fat JAR that Spring Boot generates, the image doesn't actually work. The entrypoint Jib generates is java -cp /app/classpath/*:... your.MainClass, and because the Spring Boot fat JAR doesn't put classes under the standard /classes/your/MainClass inside the JAR, the java -cp ... command doesn't work. Did you manually override Jib's entrypoint to something else? Or, is your fat JAR created in a different way somehow?
Yes, I had overwritten the entrypoint with jib.container.entrypoint.
Are you doing java -jar <fat.jar>? What's the main reason to do java -jar (if it is not because it's the only way to make it work with the "packaged" mode)? And is there a reason that you must use a fat JAR instead of the original thin JAR (if Jib worked with the original JAR and did not require changing the entrypoint)?
I'm asking these questions because my plan to support the "package" mode for Spring Boot is to make Jib pick up the original JAR instead of the Spring Boot-generated fat JAR. This will jsut automatically work without requiring changing an entrypoint or anything; it will just use the original thin JAR and do java -cp.
Yes, I did java -jar only to make it work. But as you said, there's not point of using Jib to build a fat jar. So your plan sounds good. Thank you for your work.
@maxbrunet so the best workaround for you should be to enable the jar task to generate a normal (non-fat) JAR. The Spring Boot reference says
By default, when the
bootJarorbootWartasks are configured, thejarorwartasks are disabled. A project can be configured to build both an executable archive and a normal archive at the same time by enabling thejarorwartask.
so enabling the jar task is clearly supported by Spring Boot.
jar {
enabled = true
}
But then jar and bootJar will write their respective JAR to the same location, so you'll need to give a classifier to either one. For example,
jar {
enabled = true
classifier = 'original'
}
or
jar {
enabled = true
}
bootJar {
classifier = 'boot'
}
Then Jib will make use of the normal JAR instead of the fat JAR. This will let you avoid duplicating dependencies packaged in the fat JAR. Also this does not require you to manually override the entrypoint to something like java -jar.
jar task, setting classifier = 'original', and use the normal thin JAR).The issue title (which I renamed so at some past point) talks about a potential feature to allow specifying a custom JAR task or path. But re-evaluating the current state, I think the feature is unnecessary (even for other app frameworks). The real issue was that <containerizingMode>packaged didn't work with Spring Boot projects. I'll rename the title and close the issue.
We'll let you know once we have a new release out.
@maxbrunet We've released 2.0.0, which contains this fix!
Hi, I am getting this error in maven:
Execution default-cli of goal com.google.cloud.tools:jib-maven-plugin:2.7.0:dockerBuild failed:
packaged containerizing mode for WAR is not yet supported
Are you going to support WAR in package mode?
I am struggling to build an image that uses the spring-boot tomcat embedded container in a WAR package.
Are you going to support WAR in package mode?
We don't have a plan. Given https://github.com/GoogleContainerTools/jib/issues/1802#issuecomment-744690472 and the priority, unfortunately I don't think we will work on it anytime soon. Also particularly for WAR, we don't want to promote the packaged mode, as a WAR embeds all the app dependency JARs and leads to a very inefficient image layering.
At the moment, you can remove <containerizingMode>packaged, which should normally work.
I am struggling to build an image that uses the spring-boot tomcat embedded container in a WAR package.
By the design of Jib, if your project has type <packaging>war, Jib will assume you want to deploy a WAR file to some external Servlet engine process; it will not start the spring-boot tomcat embedded Servlet engine. The only way use the embedded server is to change the type to <packaging>jar.
Most helpful comment
@maxbrunet We've released 2.0.0, which contains this fix!