Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NullpointerException with multistage Dockerfile #2100

Closed
rhierlmeier opened this issue Mar 27, 2023 · 5 comments · Fixed by #2114
Closed

NullpointerException with multistage Dockerfile #2100

rhierlmeier opened this issue Mar 27, 2023 · 5 comments · Fixed by #2114
Assignees
Labels
bug Something isn't working
Milestone

Comments

@rhierlmeier
Copy link

Describe the bug

When a Multistage-Dockerfile contains a COPY --from... statement then the kubernetes-maven-plugin:build goal produces this exception:

ERROR] Failed to execute goal org.eclipse.jkube:kubernetes-maven-plugin:1.11.0:build (default) on project foo: Failed to execute the build: NullPointerException -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.eclipse.jkube:kubernetes-maven-plugin:1.11.0:build (default) on project foo: Failed to execute the build
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:375)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: org.apache.maven.plugin.MojoExecutionException: Failed to execute the build
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.buildAndTag (AbstractDockerMojo.java:581)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.executeBuildGoal (AbstractDockerMojo.java:548)
    at org.eclipse.jkube.maven.plugin.mojo.build.BuildMojo.executeInternal (BuildMojo.java:49)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.doExecute (AbstractDockerMojo.java:451)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.execute (AbstractDockerMojo.java:413)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
Caused by: java.lang.NullPointerException
    at java.lang.String.contains (String.java:2133)
    at org.eclipse.jkube.kit.build.api.assembly.AssemblyManager.lambda$verifyAssemblyReferencedInDockerfile$2 (AssemblyManager.java:176)
    at java.util.Optional.filter (Optional.java:178)
    at org.eclipse.jkube.kit.build.api.assembly.AssemblyManager.verifyAssemblyReferencedInDockerfile (AssemblyManager.java:176)
    at org.eclipse.jkube.kit.build.api.assembly.AssemblyManager.createDockerTarArchiveForDockerFile (AssemblyManager.java:384)
    at org.eclipse.jkube.kit.build.api.assembly.AssemblyManager.createDockerTarArchive (AssemblyManager.java:112)
    at org.eclipse.jkube.kit.build.service.docker.ArchiveService.createArchive (ArchiveService.java:118)
    at org.eclipse.jkube.kit.build.service.docker.ArchiveService.createArchive (ArchiveService.java:113)
    at org.eclipse.jkube.kit.build.service.docker.BuildService.buildImage (BuildService.java:131)
    at org.eclipse.jkube.kit.build.service.docker.BuildService.buildImage (BuildService.java:78)
    at org.eclipse.jkube.kit.config.service.kubernetes.DockerBuildService.buildSingleImage (DockerBuildService.java:59)
    at org.eclipse.jkube.kit.config.service.AbstractImageBuildService.processImage (AbstractImageBuildService.java:57)
    at org.eclipse.jkube.kit.config.service.AbstractImageBuildService.build (AbstractImageBuildService.java:36)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.buildAndTag (AbstractDockerMojo.java:578)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.executeBuildGoal (AbstractDockerMojo.java:548)
    at org.eclipse.jkube.maven.plugin.mojo.build.BuildMojo.executeInternal (BuildMojo.java:49)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.doExecute (AbstractDockerMojo.java:451)
    at org.eclipse.jkube.maven.plugin.mojo.build.AbstractDockerMojo.execute (AbstractDockerMojo.java:413)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
    at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
    at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
    at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
    at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
    at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
    at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
    at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
    at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:498)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

Eclipse JKube version

1.11.0

Component

Kubernetes Maven Plugin

Apache Maven version

3.8.5

Gradle version

None

Steps to reproduce

Configuration of the kubernetes-maven-plugin-Plugin:

<plugin>
                <groupId>org.eclipse.jkube</groupId>
                <artifactId>kubernetes-maven-plugin</artifactId>
                <configuration>
                    <images>
                        <image>
                            <name>reproduceNPE</name>
                            <build>
                                <dockerFile>Dockerfile</dockerFile>
                                <assembly>
                                    <mode>dir</mode>
                                    <inline>
                                        <id>copy-jar</id>
                                        <files>
                                            <file>
                                                <source>
                                                    target/${project.artifactId}-${project.version}.jar
                                                </source>
                                                <destName>app.jar</destName>
                                                <outputDirectory>.</outputDirectory>
                                            </file>
                                        </files>
                                    </inline>
                                </assembly>
                            </build>
                        </image>
                    </images>
                </configuration>

Here is the Dockerfile:

FROM amazoncorretto:8-alpine as builder
WORKDIR /maven
RUN java -Djarmode=layertools -jar app.jar extract

FROM amazoncorretto:8-alpine
WORKDIR /opt/app
COPY --from=builder /maven/dependencies/ ./
COPY --from=builder /maven/spring-boot-loader/ ./
COPY --from=builder /maven/snapshot-dependencies/ ./
COPY --from=builder /maven/application/ ./
EXPOSE 8080
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

Expected behavior

The kubernetes-maven-plugin must not produce an NPE because the Dockerfile is valid.

Runtime

Kubernetes (vanilla)

Kubernetes API Server version

1.25.3

Environment

Windows

Eclipse JKube Logs

No response

Sample Reproducer Project

No response

Additional context

No response

@rhierlmeier rhierlmeier added the bug Something isn't working label Mar 27, 2023
@manusa manusa moved this to Planned in Eclipse JKube Mar 28, 2023
@rohanKanojia rohanKanojia self-assigned this Mar 30, 2023
@rohanKanojia rohanKanojia moved this from Planned to In Progress in Eclipse JKube Mar 30, 2023
@rohanKanojia
Copy link
Member

@rhierlmeier : I think you're getting NPE because you haven't provided any assembly name. Does the error go away when you add assembly name like this?

                                            <assembly>
                                                <name>maven</name>
                                                <mode>dir</mode>

Maybe we can assume assembly name as default assembly name if it's not provided.

@rohanKanojia
Copy link
Member

@rhierlmeier : Is it possible to provide more information about the project you're using? Which version of spring boot? What packaging strategy are you using etc? I'm able to get over NPE by adding assembly name but I run into a different error (seems related to my reproducer project setup):

[ERROR] k8s: Failed to execute the build [Error while trying to build the image: Unable to build image [demos/jkube-multistage-dockerfile:latest] : "The command '/bin/sh -c java -Djarmode=layertools -jar app.jar extract' returned a non-zero code: 1" ]

@rohanKanojia
Copy link
Member

Looking at the code we're already handling empty/null fields in assembly by providing defaults here:

https://github.com/eclipse/jkube/blob/24af2f726ab5212825d118b1e4ac7e14ccc9e881/jkube-kit/build/api/src/main/java/org/eclipse/jkube/kit/build/api/assembly/AssemblyConfigurationUtils.java#L43

We invoke this method here to create AssemblyConfiguration:
https://github.com/eclipse/jkube/blob/24af2f726ab5212825d118b1e4ac7e14ccc9e881/jkube-kit/build/api/src/main/java/org/eclipse/jkube/kit/build/api/assembly/AssemblyManager.java#L429

However, while checking whether Dockerfile uses assembly we're using wrong object (we're checking assembly inside buildConfig.getAssembly() rather than already processed assemblyConfig that is created in abovementioned locations.

https://github.com/eclipse/jkube/blob/24af2f726ab5212825d118b1e4ac7e14ccc9e881/jkube-kit/build/api/src/main/java/org/eclipse/jkube/kit/build/api/assembly/AssemblyManager.java#L173

I'm able to no longer see NPE after passing assemblyConfig here.

rohanKanojia added a commit to rohanKanojia/jkube that referenced this issue Mar 30, 2023
… references in Dockerfile (eclipse-jkube#2100)

We're already seem to process AssemblyConfiguration before creating
docker tar archives. However, we're passing wrong object as
AssemblyConfiguration while verifying Dockerfile actually contains
ADD/COPY references to specified assembly.

Add a new parameter to AssemblyManager.verifyAssemblyReferencedInDockerfile
method to provide already processed AssemblyConfiguration object rather
than using AssemblyConfiguration from BuildConfiguration.

Signed-off-by: Rohan Kumar <[email protected]>
@rohanKanojia rohanKanojia moved this from In Progress to Review in Eclipse JKube Mar 31, 2023
@rhierlmeier
Copy link
Author

Ok, I the problem was that the assembly in the pom.xml has not name element.
The assembly has now the name copy-jar. I get the following warning:

[INFO] --- kubernetes-maven-plugin:1.11.0:build (default) @ jkube-test ---
[INFO] k8s: Building Docker image in Kubernetes mode
[INFO] k8s: Using Dockerfile: C:\Users\rh\Documents\Projekte\jkube-test\src\main\docker\Dockerfile
[INFO] k8s: Using Docker Context Directory: C:\Users\rh\Documents\jkube-test\DE_DevDbManagerBackend\src\main\docker
[WARNING] k8s: Dockerfile C:\Users\rh\Documents\jkube-test\src\main\docker\Dockerfile does not contain an ADD or COPY directive to include assembly created at copy-jar. Ignoring assembly.
[INFO] k8s: [jkube-test:latest]: Created docker-build.tar in 776 milliseconds

I had to add the following line to the Dockerfile:

COPY copy-jar/app.jar /maven/app.jar

Can you please improve the documentation at https://www.eclipse.org/jkube/docs/kubernetes-maven-plugin/#build-assembly-layer? I think the relationship between the assembly in the pom.xml and the COPY statement in the Dockerfile is missing
Please provide a clearer error message for this error case?

@rhierlmeier
Copy link
Author

rhierlmeier commented Mar 31, 2023

I found also out that the assembly in pom.xml is not necessary at all. Because the build process provides already the application jar in the maven directory. The following setup is enough:

<groupId>org.eclipse.jkube</groupId>
<artifactId>kubernetes-maven-plugin</artifactId>
<configuration>
	<images>
		<image>
			<build>
				<dockerFile>${project.basedir}/src/main/docker/Dockerfile</dockerFile>
			</build>
		</image>
	</images>
</configuration>

And the Dockerfile:

FROM amazoncorretto:8-alpine as builder

WORKDIR /maven
COPY maven/jkube-test-*.jar /maven/app.jar
RUN java -Djarmode=layertools -jar app.jar extract

FROM amazoncorretto:8-alpine
WORKDIR /opt/desoft/DE_DevDbManager
COPY --from=builder /maven/dependencies/ ./
COPY --from=builder /maven/spring-boot-loader/ ./
COPY --from=builder /maven/snapshot-dependencies/ ./
COPY --from=builder /maven/application/ ./
RUN addgroup --system javauser && adduser -S -s /usr/sbin/nologin -G javauser javauser \
    && chown -R javauser:javauser .
EXPOSE 8080
USER javauser
HEALTHCHECK --interval=30s --timeout=3s --retries=1 CMD wget -qO- http://localhost:8080/actuator/health/ | grep UP || exit 1

ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

rohanKanojia added a commit to rohanKanojia/jkube that referenced this issue Mar 31, 2023
… references in Dockerfile (eclipse-jkube#2100)

We're already seem to process AssemblyConfiguration before creating
docker tar archives. However, we're passing wrong object as
AssemblyConfiguration while verifying Dockerfile actually contains
ADD/COPY references to specified assembly.

Add a new parameter to AssemblyManager.verifyAssemblyReferencedInDockerfile
method to provide already processed AssemblyConfiguration object rather
than using AssemblyConfiguration from BuildConfiguration.

Signed-off-by: Rohan Kumar <[email protected]>
@manusa manusa added this to the 1.12.0 milestone Mar 31, 2023
manusa pushed a commit that referenced this issue Mar 31, 2023
… references in Dockerfile (#2100)

We're already seem to process AssemblyConfiguration before creating
docker tar archives. However, we're passing wrong object as
AssemblyConfiguration while verifying Dockerfile actually contains
ADD/COPY references to specified assembly.

Add a new parameter to AssemblyManager.verifyAssemblyReferencedInDockerfile
method to provide already processed AssemblyConfiguration object rather
than using AssemblyConfiguration from BuildConfiguration.

Signed-off-by: Rohan Kumar <[email protected]>
@github-project-automation github-project-automation bot moved this from Review to Done in Eclipse JKube Mar 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants