I have a server side project written in java
including maven
and spring-boot
And I’m trying to run it in Docker.
I write the whole program in VSCODE and create a special Dockerfile for it.
Then I want to be able to create a jar from my project and when I build an image and run it in the container I can see server side.
this is my Dockerfile:
FROM maven:3.8.1-openjdk-11 AS build
WORKDIR /usr/src/app
COPY pom.xml .
COPY src ./src
RUN mvn package
ENTRYPOINT ["java","-jar","target/my-app-1.0.0.jar"]
this is my 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>
<groupId>src</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<properties>
<start-class>src.MyApplication</start-class>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<mainClass>src.MyApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
MyApplication.java:
package src;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
And my folder structure is like this:
.
├── src
| └──controllers
| │ └──controller.java
| └──models
| │ └──classA.java
| | └──classB.java
| └──services
| | └──service.java
| └──MyApplication.java
├── Dockerfile
├── pom.xml
When I run the docker build -t app
command. There seems to be no problem and the build is successful, but when I later run the command docker run -p 8080:8080 app
I get this error
Error: Could not find or load main class src.MyApplication Caused by: java.lang.ClassNotFoundException: src.MyApplication
Does anyone have an idea for a solution for me?
2
Answers
The word
src
is confusing in several ways.By convention the source code is held in folder called
src/main
and then beneath that you’d normally make folders for your organisation name and application.So suppose you were ACME Corporation and had a domain name acme.com and your application was about fish, then you’d package all your code under the package name
com.acme.fish
(domain name reversed, then application name, etc).In java is that Classes needs to be in files that match the class name, and by convention those files should have initial capitals. So
ClassA.java
notclassA.java
.This then would be a more conventional structure:
Then in your
pom.xml
<mainClass>
would be:Start by restructuring like this.
Then if this still does not work, use an unzip tool and look at the structure of your zip file. In the
classses
folder you should end up with acom/acme/fish/MyApplication.class
Couple of things that are wrong.
src/main/java
spring-context
dependency and thespring-boot-autoconfigure
dependency, already included through the starters.spring-boot-maven-plugin
not themaven-jar-plugin
.The corrected
pom.xml
Move your classes to a base package something like
io.maia
and usesrc/main/java
for the proper Maven structure.Spring Boot 3.x requires Java 17 or higher, so update your
Dockerfile
as well. You might also want to leverage a multistage build (1 stage for the build, 1 stage for actually running it).Or if your only goal is to run the application in a container, ditch the
Dockerfile
all together and runmvn spring-boot:build-image
instead to get a runnable and optimized image.