Home > Blockchain >  Can't run .jar file created with IntelliJ / Gradle. "no main manifest attribute, in app.ja
Can't run .jar file created with IntelliJ / Gradle. "no main manifest attribute, in app.ja

Time:01-09

I've followed the advice of other solutions. Like this one.

And this one.

I've also tried the solution belonging to this

$ java -cp app.jar main.Main

I get an error that would not normally occur when running the project inside of IntelliJ.

Here is that error:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.awt.image.BufferedImage.getSubimage(int, int, int, int)" because "img" is null
        at entities.MiqoCharacter.loadAnimationMale(MiqoCharacter.java:280)
        at entities.MiqoCharacter.<init>(MiqoCharacter.java:50)
        at gamescreens.CharacterDisplayScreen.initClasses(CharacterDisplayScreen.java:33)
        at gamescreens.CharacterDisplayScreen.<init>(CharacterDisplayScreen.java:27)
        at main.Game.initClasses(Game.java:33)
        at main.Game.<init>(Game.java:22)
        at main.Main.main(Main.java:7)

Like I have stated, this error does not occur inside of the program itself. I believe that it has to do with the resources folder. This is the method that is causing the errors.

 public static BufferedImage GetSpriteAtlas(String fileName) {
        BufferedImage img = null;
        InputStream is = AssetLoader.class.getResourceAsStream(fileName);
        if (is != null) {
            try {

                img = ImageIO.read(is);

            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {

                    is.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return img;
    }

When running the full code inside of IntelliJ, I can see the program just fine. Here is the GUI of the application displaying correctly when running inside of IntelliJ.

I have created the .jar file using IntelliJ, and I have built it using Gradle. this is my build.gradle file.

plugins {
    id 'java'
}
jar {
    manifest {
        attributes "Main-Class": "main.Main"
    }
}


group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}


test {
    useJUnitPlatform()
}

and here is my MANIFEST.MF

Main-Class: main.Main

I've tried to follow the advice of several threads on stack overflow as well as from videos on youtube. I can't seem to find the answer to this. And i get errors that would indicate that my .jar file had not compiled the contents of the resource folder, nor detect the Main class in my project.

CodePudding user response:

Found the solution by looking here I solved this answer by doing as follows:

I added this to the build.gradle file, although this didn't seem to do much, because I have to manually modify the MANIFEST.MF inside of the jar by using 7ZIP, but I'll get to that in a bit. this is what i added:

jar {
from('src/main/resources') {
    include '**/*.*'
}
manifest {
    attributes "Main-Class": "main.Main"
}

}

After this, I changed some things inside of the File > Project Structure > Artifacts.

Oh another thing, when using the sign to create the .jar file in the >Artifacts section, do "copy output to director and link manifest" change the directory from \src\main\java to \src\main\resources

After this, add the 'resources' to the jar by pressing the dropdown inside of Output Layout and select the resources folder.

Images:

This is a link to what I've added.

And this is how i've added it.

After this, it should add the resource folders to the inside of the .jar.

But that's not it. Rebuild/Build the jar again with Build > Build Artifacts > Build.

And then use 7Zip or WinRar to open the .jar archive. Go inside of META-INF --> MANIFEST.MF and drag it somewhere. I used my desktop.

Open up that copy of the MANIFEST.MF and then add Main-Class: main.Main just below the line that says Manifest-Version: 1.0.

this is what my full MANIFEST.MF looks like.

Manifest-Version: 1.0
Main-Class: main.Main
Build-Date: 2021-09-22
Build-Revision: 9883ffa5ab9ddb27ce33f6d2ace9f6be16403f40
Build-Time: 20:54:36.897 0200
Built-By: JUnit Team
Bundle-ManifestVersion: 2
Bundle-Name: JUnit Jupiter API
Bundle-SymbolicName: junit-jupiter-api
Bundle-Version: 5.8.1
Created-By: 11.0.12 (Eclipse Foundation 11.0.12 7)
Export-Package: org.junit.jupiter.api;version="5.8.1";status=STABLE;uses
 :="kotlin,kotlin.jvm.functions,kotlin.jvm.internal,org.apiguardian.api,
 org.junit.jupiter.api.function,org.junit.jupiter.api.parallel,org.junit
 .platform.commons.annotation,org.opentest4j",org.junit.jupiter.api.cond
 ition;version="5.8.1";status=STABLE;uses:="org.apiguardian.api,org.juni
 t.jupiter.api.extension",org.junit.jupiter.api.extension;version="5.8.1
 ";status=STABLE;uses:="org.apiguardian.api,org.junit.jupiter.api,org.ju
 nit.jupiter.api.function,org.junit.jupiter.api.parallel,org.junit.platf
 orm.commons",org.junit.jupiter.api.extension.support;version="5.8.1";st
 atus=EXPERIMENTAL;uses:="org.apiguardian.api,org.junit.jupiter.api.exte
 nsion",org.junit.jupiter.api.function;version="5.8.1";status=STABLE;use
 s:="org.apiguardian.api",org.junit.jupiter.api.io;version="5.8.1";statu
 s=EXPERIMENTAL;uses:="org.apiguardian.api",org.junit.jupiter.api.parall
 el;version="5.8.1";status=EXPERIMENTAL;uses:="org.apiguardian.api"
Implementation-Title: junit-jupiter-api
Implementation-Vendor: junit.org
Implementation-Version: 5.8.1
Import-Package: org.apiguardian.api;resolution:=optional;version="[1.1,2
 )",org.junit.platform.commons.logging;status=INTERNAL;version="[1.8,2)"
 ,kotlin;resolution:=optional,kotlin.collections;resolution:=optional,ko
 tlin.jvm.functions;resolution:=optional,kotlin.jvm.internal;resolution:
 =optional,org.junit.jupiter.api;version="[5.8,6)",org.junit.jupiter.api
 .extension;version="[5.8,6)",org.junit.jupiter.api.function;version="[5
 .8,6)",org.junit.jupiter.api.parallel;version="[5.8,6)",org.junit.platf
 orm.commons;version="[1.8,2)",org.junit.platform.commons.annotation;ver
 sion="[1.8,2)",org.junit.platform.commons.function;version="[1.8,2)",or
 g.junit.platform.commons.support;version="[1.8,2)",org.junit.platform.c
 ommons.util;version="[1.8,2)",org.opentest4j;version="[1.2,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Specification-Title: junit-jupiter-api
Specification-Vendor: junit.org
Specification-Version: 5.8.1


Now save this copy of the MANIFEST.MF file, and drag&drop it into your .jar archive (that you have open still with 7Zip or WinRar. ) and replace the file inside with the one that you have created.

Now run:

java -jar app.jar

Let me know if I've got anything incorrect.

CodePudding user response:

RootCause: When you run self-executable jar, java will look for the Main-Class in MANIFEST.MF file located under META-INF folder. If it is not able to find an entry,then it will complain with Unable to execute jar- file: “no main manifest attribute”.

Try to change your manifest attributes like:

jar {
  manifest {
    attributes(
      'Main-Class': 'package.MainClass'
    )
  }
}

And then just change 'package.MainClass' to '.' (where your Main class has a main method). In this case, you make in your manifest an attribute, which point to this class, then a jar is running.

for adding it using CLI the following command will do the job:

jar cmvf META-INF/MANIFEST.MF <new-jar-filename>.jar  <files to include>

You can also refer to this article https://www.javatpoint.com/no-main-manifest-attribute

  • Related