Home > Enterprise >  Error: Invalid or corrupt jarfile /bin/sh
Error: Invalid or corrupt jarfile /bin/sh

Time:10-01

I have problem with my spring boot app.

If I docker-compose up, I see this error -> Error: Invalid or corrupt jarfile /bin/sh

MongoDb, prometheus and grafana start correctly.

Dockerfile

FROM openjdk:11-jre-slim as build
ADD target/rest-test-0.0.1-SNAPSHOT.jar .
EXPOSE 8000
CMD java -jar rest-test-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-Dspring.profiles.active=prod","-jar"]

docker-compose.yml

version: "3.8"

services:
  rest-test:
    build: .
    restart: always
    ports:
      - "8000:8080"
    depends_on:
      - mongo_db
    environment:
      - "SPRING_PROFILES_ACTIVE=prod"
  mongo_db:
    image: "mongo:latest"
    restart: always
    ports:
      - "27018:27017"
  prometheus:
    image: "prom/prometheus"
    restart: always
    depends_on:
      - rest-test
    ports:
      - "9090:9090"
  grafana:
    image: "grafana/grafana"
    restart: always
    depends_on:
      - rest-test
    ports:
      - "3000:3000"

CodePudding user response:

That ENTRYPOINT line doesn't fit here, and you should remove it. If you do need JVM options, include them in the java command.

CMD java -Dspring.profiles.active=prod -jar rest-test-0.0.1-SNAPSHOT.jar
# no ENTRYPOINT

You're seeing two things happen in your original Dockerfile. Since CMD is a bare string, Docker automatically wraps it in /bin/sh -c; and since you have both ENTRYPOINT and CMD, the CMD gets passed as arguments to the ENTRYPOINT. This results in the nonsensical command

java -D... -jar /bin/sh -c 'java -jar rest-test-0.0.1-SNAPSHOT.jar'

which produces the error you see.

There is no requirement that an image have an ENTRYPOINT; in many cases specifying only CMD is easier to manage (for example, you can docker run --rm -it your-image sh to get an interactive debugging shell on a built image). If you do split CMD and ENTRYPOINT, either the ENTRYPOINT should be written so it accepts a complete command as arguments or the ENTRYPOINT should itself be a complete command and the CMD its arguments.

# "Container as command" pattern: lets you
#   docker run ... the-image -arg1 -arg2
# where the arguments get passed to the application
ENTRYPOINT ["java", "-Dspring.profiles.active-prod", "-jar", "rest-test-0.0.1-SNAPSHOT.jar"]
CMD []
# empty CMD is optional
# both must be JSON arrays, you do not want the `sh -c` wrapper
  • Related