0

I tried use docker-compose, docker build a demo Spring-boot project and run on docker. But created the jar file, and that throw ClassNotFoundException, when the CMD [ "java", "-jar", "/usr/local/lib/demo.jar"] command has triggered from Dockerfile.

  • I did use docker-compose run to build & run.
  • I tried many solution from StackOverflow, didn't solve the problem.

My docker-compose file:

version: '3.5'
services:
  demo-service:
    container_name: demo-service
    build:
      context: ./demo
      dockerfile: dockerfile.demoservice.mvn
    ports:
      - "9091:9091"
    # depends_on:
    #   - demo-service-db

Dockerfile file:

FROM maven:3.6.3-jdk-11-slim AS build

RUN mkdir /home/app
COPY ./pom.xml /home/app/pom.xml
COPY src /home/app
RUN mvn -f /home/app/pom.xml clean package spring-boot:repackage
RUN ls /home/app/target

# Package stage
FROM openjdk:11-jre-slim
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
EXPOSE 9091
CMD [ "java", "-jar", "/usr/local/lib/demo.jar"]

There is the pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
        <!-- The main class to start by executing "java -jar" -->
        <!-- If I remove this, java -jar will be thrown no main manifest attribute (maven) -->
        <start-class>com.example.demo.DemoApplication</start-class>
    </properties>
...
...
...
    <build>
<!-- Didn't solve the problem: no main manifest attribute-->
      <pluginManagement>
        <plugins>
            <plugin>
        <groupId>org.springframework.boot</groupId>
<!-- Didn't solve the problem: no main manifest attribute-->
        <artifactId>spring-boot-maven-plugin</artifactId>
        <version>${project.parent.version}</version>
        <executions>
            <execution>
                <goals>
                <goal>repackage</goal>
                </goals>
                <configuration>
                    <classifier>spring-boot</classifier>
                                <manifest>
              <addClasspath>true</addClasspath>
              <!-- Didn't solve the problem: no main manifest attribute-->
<mainClass>com.example.demo.DemoApplication</mainClass>
            </manifest>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                    <!-- Unable to find main class-->
                    <!-- <skip>true</skip> -->
                    </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
      </pluginManagement>
    </build>

The project structure is as initialized, didn't change anything. (main function in java/com/example/demo/DemoApplication.java)

The error message is: Exception in thread "main" java.lang.ClassNotFoundException: com.example.demo.DemoApplication.

  • Java version 11;
  • Spring boot version 2.6.3
  • maven:3.6.3-jdk-11-slim
  • openjdk:11-jre-slim

Where did I do wrong? Thanks!

Ekestfa
  • 38
  • 6
  • if you directly run the jar file without docker, does it still work? – fauzimh Feb 20 '22 at 05:15
  • I have installed `Apache Maven 3.6.3`, first executed `mvn clean package spring-boot:repackage`, after that, executed `java -jar ./target/demo-0.0.1-SNAPSHOT.jar`, and it works correctly. – Ekestfa Feb 20 '22 at 08:40

1 Answers1

0

I think you missed to use the plugin. pluginManagement won't really activate the plugin, but it is just to make the plugin available for the maven sub module to use. Basically, pluginManagement is just to declare that this plugin is available for use.

see: Difference between <plugins> and <pluginManagement> tag in Maven `pom.xml`

You should still use this plugin below:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.example.demo.DemoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

You might be able to remove the executions tag from the plugin above as you have declared it in your pluginManagement. Try it out and see. Try running the standalone jar without the docker first.

fauzimh
  • 594
  • 4
  • 16
  • It can be packaged and executed correctly without `Docker`, but when I use `docker-compose` and `docker`, it fails. – Ekestfa Feb 20 '22 at 08:41