Mohammad Karmi
Mohammad Karmi

Reputation: 1465

spring boot run JarLauncher when extracting jar

I'm building a fat jar using spring boot , the fat jar works using

java -jar app.jar

the problem is that I'm using docker and I want to expand the jar contents for better usability , I do the following to extract :

unzip app.jar

now I run the jar with the following :

java -cp "." org/springframework/boot/loader/JarLauncher

I get the following error :

 Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jaxRsServer' defined in class path resource 

so it couldn't find my bean altough it's configured :

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@ImportResource("classpath:spring/beans_context.xml")
public class SpringBootJaxrsApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootJaxrsApplication.class, args);
    }

}

beans_context.xml :

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />


<import resource="classpath:META-INF/spring/*_context.xml"/>

Upvotes: 3

Views: 12116

Answers (1)

Thomas Vitale
Thomas Vitale

Reputation: 1808

Which Spring Boot version are you using? Since 2.3.0, a new layered mode is available for packaging fat JARs. Once you enable the layered mode, you can then do something like this to build the Docker image.

FROM adoptopenjdk:11-jre-hotspot as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
RUN java -Djarmode=layertools -jar application.jar extract

FROM adoptopenjdk:11-jre-hotspot
WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/resources/ ./
COPY --from=builder application/application/ ./
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]

Notice that the command is java org.springframework.boot.loader.JarLauncher.

The example is fully explained in this post from the Spring blog. For more information on how layering works in Spring Boot 2.3, you can refer to this post, again from the Spring blog.

Instead, if you're using an older version of Spring Boot, you can build your Dockerfile as explained in this post. In this case, the entrypoint will be java -cp app:app/lib/* hello.Application.

FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

Upvotes: 6

Related Questions