jib packages spring boot devtools

Created on 17 Mar 2020  路  7Comments  路  Source: GoogleContainerTools/jib

Environment:

  • Jib version: 2.1.0
  • Build tool: maven
  • OS: macos

Description of the issue:
I created a Spring Boot app w/ devtools dependency:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
  <scope>runtime</scope>
  <optional>true</optional>
</dependency>

In the resulting image, devtool is actually activated. The dependency is in the image's /app/libs directory.

Expected behavior:
Optional dependency ignored? Spring Boot's plugin excludes devtool by default.
https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/maven-plugin/repackage-mojo.html

Steps to reproduce:

  1. Create a new spring boot app w/ devtool
  2. Package w/ Jib
  3. See that Jib includes Devtool

jib-maven-plugin Configuration:

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>jib-maven-plugin</artifactId>
  <version>2.1.0</version>
  <configuration>
    <from><image>openjdk:8u222-slim</image></from>
    <to><image>gcr.io/wise-coyote-827/jib-demo</image></to>
    <container><user>nobody:nogroup</user></container></configuration>
</plugin>

Log output:

Additional Information:

All 7 comments

Yeah that makes sense, our logic considers it a runtime dependency. We're not checking for optional. How would this work in a container environment? Someone would inject the dependency at runtime?

Someone asked this before: https://github.com/GoogleContainerTools/jib/issues/1254#issuecomment-439478139

Before we start, let's get clear about an optional dependency.

I've seen people mistakenly assume that the <optional>true in Maven implies the dependency should not be included, e.g., at compile-time or runtime. That is not true; with <scope>runtime, it still tells Maven that the dependency is _required at runtime_ when it is a direct dependency.

How do optional dependencies work?

Project-A -> Project-B

The diagram above says that Project-A depends on Project-B. When A declares B as an optional dependency in its POM, this relationship remains unchanged. It's just like a normal build where Project-B will be added in Project-A's classpath.

Therefore, it is correct for Maven and Jib to include spring-boot-devtools as a runtime dependency. It is just that Spring Boot runs a proprietary logic to exclude spring-boot-devtools by default _only for their repackaged fat JAR_.

To properly resolve this issue, the user should correctly set up the spring-boot-devtools dependency to tell Maven whether they want it at runtime or not, e.g., by setting up two Maven profiles (e.g., dev and prod).


(UPDATE) X-ref: https://github.com/GoogleContainerTools/jib-extensions/pull/31#issuecomment-655553254

Oh this is more about development vs deployment.
I feel like the springboot team should've used profiles in their example, not optional.

Anyway, it still seems within the scope of optional use as an exclusionary mechanism for packaging.
See: Why use optional dependencies? at https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html

how can we resolve this? thinking of..

  • explicit exclusions by groupId:artifactId
  • or, simply ignore optionals
  • or, simply jib the produced JAR, which is something i've been advocating :) since the JAR is what user expects to turn into container.

Yeah, profiles should be the way to go.

We have published a Jib extension for Spring Boot (Maven and Gradle) that covers this issue. You can apply the extension on recent Jib versions.

Details

As discussed in this thread and #1254, Jib is working as intended to package spring-boot-devtools in the image, and the user should properly configure the dependency if they do not want it at runtime. However, we decided to create the extension to help people avoid the chore of manually setting up profiles in their projects.

Was this page helpful?
0 / 5 - 0 ratings