1

I have a spring project with Gradle. I created a task in the build.gradle:


task dockerFile(type: Dockerfile) {
    destFile.set(project.file('Dockerfile'))
    from "alpine:$alpineVersion"
    runCommand 'apk add --no-cache openjdk11'
    copyFile "build/libs/${jar.archiveFileName.get()}", '/app/'
    workingDir '/app/'
    entryPoint 'java'
    defaultCommand '-jar', "/app/${jar.archiveFileName.get()}"
}

Everything works fine. Dockerfile is generated. But when I try to run the image it gives me the error: no main manifest attribute, in /app/demo-0.0.1-SNAPSHOT-plain.jar

Also here is my entire build.gradle:

import com.bmuschko.gradle.docker.tasks.image.Dockerfile

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.7.6'
    id 'io.spring.dependency-management' version '1.0.15.RELEASE'
    id 'com.bmuschko.docker-remote-api' version '6.6.1' apply false
}

group = 'ms10gradle2'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-data-jpa:$jpaVersion"
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

task printJpaVer{
    print "JPA VERSION: ${jpaVersion}"
}

task printfiles {
   doLast {
       def files = "cmd.exe /c dir".execute().text.trim()
       println(files)
       project.getAllprojects().forEach(System.out::print)
   }
}

task printTasks{
    project.getTasks().forEach{
        println("task name: "+ it)
    }
}

task printTasksInsideSubModulesTrueOrFalse{
    project.getAllTasks(false).entrySet().forEach(System.out::println)
}


task printTaskVersion{
    project.getAllprojects()
        .forEach(p -> println p.name +"- "+p.getVersion())

    print "================================================================"
    project.getAllprojects().forEach(p -> println p.getVersion())
}


task dockerFile(type: Dockerfile) {
    destFile.set(project.file('Dockerfile'))
    from "alpine:$alpineVersion"
    runCommand 'apk add --no-cache openjdk11'
    copyFile "build/libs/${jar.archiveFileName.get()}", '/app/'
    workingDir '/app/'
    entryPoint 'java'
    defaultCommand '-jar', "/app/${jar.archiveFileName.get()}"
}


and Dockerfile:

FROM alpine:3.11.2
RUN apk add --no-cache openjdk11
COPY build/libs/demo-0.0.1-SNAPSHOT-plain.jar /app/
WORKDIR /app/
ENTRYPOINT ["java"]
CMD ["-jar", "/app/demo-0.0.1-SNAPSHOT-plain.jar"]

Aziz Gasimov
  • 66
  • 3
  • 13
  • 1
    Have you tried running your application with the command `java -jar demo-0.0.1-SNAPSHOT-plain.jar` before putting it into the docker file? Did that work? I would guess it did not, which means you have to fix your jar file (i.e. you need to ensure that a `Main-Class` attribute is written into the `META-INF/MANIFEST`.MF file of your jar.) – Thomas Behr Dec 22 '22 at 15:18
  • Yes thank you for the comment the problem in fact was related to the jar file. And `demo-0.0.1-SNAPSHOT-plain.jar`. I edited the task to use the other jar file inside the build folder. – Aziz Gasimov Dec 22 '22 at 19:24

1 Answers1

-1

Looks like you tried to run jar is not executable. Let's say you have main class in your code with name fully.qualified.MainClass There are 2 ways:

  1. It it necessary to add manifest with main-class(preferable):

for maven:

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        ...
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>fully.qualified.MainClass</mainClass>
            </manifest>
          </archive>
        </configuration>
        ...
      </plugin>

maven documentation for more info.

for gradle

it is necessary to add jar task with Main-Class:

jar {
  manifest {
   attributes 'Main-Class': 'fully.qualified.MainClass'
  }
}

Jar task documentation and also there was question about gradle executable jar: Creating runnable JAR with Gradle

  1. run jar with your main class as param:
java -cp MyJar.jar fully.qualified.MainClass

How to run a class from Jar which is not the Main-Class in its Manifest file

Rustam
  • 378
  • 2
  • 6