0

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.

  • The only reason `ImageIO.read` will return `null` is if the image is not a supported image format - there's not enough context to be sure, but I'd be making sure that the images you're trying to load are included within your resulting jar. Also, your question title doesn't match you question, which is very confusing – MadProgrammer Jan 08 '23 at 21:25
  • What about is confusing? I'm having trouble building the jar. It's finding a .png. Click the link here: https://i.stack.imgur.com/ZFIWe.png , as you can see, i'm not having issues with my program in intellij. I am having issues with .jar – Sage Belknap Jan 08 '23 at 21:39
  • 1
    Title: `"no main manifest attribute, in app.jar"`; Question: `Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.awt.image.BufferedImage.getSubimage(int, int, int, int)" because "img" is null` - Those are two different issues, so, which problem are we actually looking at – MadProgrammer Jan 08 '23 at 21:58
  • Unzip the Jar - make sure the image files are included. [Add resources and config files to your JAR using Gradle](https://stackoverflow.com/questions/24724383/add-resources-and-config-files-to-your-jar-using-gradle) might also be worth a look – MadProgrammer Jan 08 '23 at 21:58
  • What is the value of `fileName`? – g00se Jan 08 '23 at 22:02
  • Sorry for the confusion of the title and the question. The error that i receive is not relevant, for it does not appear outside of running the jar. My problem is that my jar is not properly building. – Sage Belknap Jan 08 '23 at 22:04
  • Unzipping the jar I see there are no resource folders, and no image files. The link that you have sent has a depreciated solution. – Sage Belknap Jan 08 '23 at 22:09
  • That should already have been taken care of, using IntelliJ – g00se Jan 08 '23 at 22:11
  • fileName gets used in several places. It loads in more than one image file. When looking in the jar file with 7Zip, it appears that there is no resources folder, and there is no "Main-Class: main.Main" inside of the MANIFEST.mf, but every time that I try to change that, it reverts. – Sage Belknap Jan 08 '23 at 22:14
  • I don't use IntelliJ but it seems like you need to find out how to define resources with it – g00se Jan 08 '23 at 22:19
  • I've now tried to add this to the build.gradle: `jar { from('src/main/resources') { include '**/*.*' } manifest { attributes "Main-Class": "Main" } } sourceSets { main { java { srcDirs = ['./src/main/java'] } resources { srcDirs = ['./src/main/resources'] } } }` However, this does not work. source; https://stackoverflow.com/questions/70466312/gradle-does-not-include-resource-folder-to-jar :/ I'm so lost. – Sage Belknap Jan 08 '23 at 22:19
  • Found the solution: https://stackoverflow.com/questions/28337418/intellij-resources-not-in-built-artifact I'm going to write a full response soon. – Sage Belknap Jan 08 '23 at 22:33
  • Have you tried using the [Application plugin](https://docs.gradle.org/current/userguide/application_plugin.html)? It provides a convenient option for setting the main class. – aSemy Jan 09 '23 at 09:35

2 Answers2

0

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.

0

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

ITGeek
  • 26
  • 5
  • When you say >And then just change 'package.MainClass' to '.' (where your Main class has a main method). < Do you mean that I should make the build.gradle say ` jar { manifest { attributes "Main-Class": ".main.Main" } } ` or is it fine without the precursory '.' ? – Sage Belknap Jan 09 '23 at 11:08
  • I mean at the place of package.MainClass replace your main class's package with class name, suppose my psvm(String args[]) method is in AppRunner class and my AppRunner class is in com.app package so I will re-write it like this: jar { manifest { attributes( 'Main-Class': 'com.app.AppRunner' ) } } – ITGeek Jan 09 '23 at 12:36