[SOLVED] Runnable JAR outputs (input == null) IOException error after exporting.

For those who wanted to help out, here’s a link to my GitHub repository, so that anyone can help look at the problem.
GitHub repository: http://github.com/tommai78101/PokemonWalking.git

I’m having trouble with exporting a runnable JAR file recently. The problem seems to be an issue with class paths, but I’ve checked to see there’s no issues with it.
I’m actually stumped by this problem. I’m going to post a few pictures in hope that someone else may point out the problem that I didn’t see.

Picture of class path settings:

Picture of the output error log via console:

Loading resources code:


public class Art {
	
	//Entities
	public static BaseBitmap[][] player;
	public static BaseBitmap[][] testDownAnimation;
	
	//Tiles
	public static BaseBitmap testTile;
	public static BaseBitmap smallTree;
	
	//Area
	public static BaseBitmap testArea;
	public static BaseBitmap testArea2;
	
	//Others
	public static BaseBitmap sprite;
	
	public static void loadAllResources(BaseScreen screen) {
		sprite = screen.load("/art/test.png");
		player = screen.cut("/art/player/player.png", 16, 16, 0, 0);
		testTile = screen.load("/art/floor/testTile.png");
		smallTree = screen.load("/art/wall/treeSmall.png");
		testDownAnimation = screen.cut("/art/player/test_walk_down_animation.png", 16, 16, 0, 0);
		
		testArea = screen.load("/area/test/testArea.png");
		testArea2 = screen.load("/area/test/testArea2.png");
	}
}

Any answers/suggestions are fully welcomed. :frowning:

Try adding the res folder in the “Source” tab not the “Library” tab. Also what does your “screen.load()” method look like?

The screen.load() method is actually based on a superclass. It consists of the entire thing, so here you go:


package screen;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class BaseBitmap {
	protected int[] pixels;
	protected int width;
	protected int height;
	
	public BaseBitmap(int w, int h) {
		this.width = w;
		this.height = h;
		this.pixels = new int[w * h];
	}
	
	public BaseBitmap(int w, int h, int[] p) {
		this.width = w;
		this.height = h;
		this.pixels = p;
	}
	
	public BaseBitmap load(String filename) {
		try {
			BufferedImage image = ImageIO.read(BaseBitmap.class.getResource(filename));
			return load(image);
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public BaseBitmap load(BufferedImage image) {
		if (image == null) return null;
		
		int width = image.getWidth();
		int height = image.getHeight();
		
		return new BaseBitmap(width, height, image.getRGB(0, 0, width, height, null, 0, width));
	}
	
	public BaseBitmap[][] cut(String filename, int w, int h, int clipW, int clipH) {
		try {
			BufferedImage image = ImageIO.read(BaseBitmap.class.getResource(filename));
			int xTiles = (image.getWidth() - clipW) / w;
			int yTiles = (image.getHeight() - clipH) / h;
			BaseBitmap[][] results = new BaseBitmap[xTiles][yTiles];
			for (int x = 0; x < xTiles; x++) {
				for (int y = 0; y < yTiles; y++) {
					results[x][y] = new BaseBitmap(w, h);
					image.getRGB(clipW + x * w, clipH + y * h, w, h, results[x][y].pixels, 0, w);
				}
			}
			return results;
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public int getWidth() {
		return this.width;
	}
	
	public int getHeight() {
		return this.height;
	}
	
	public int[] getPixels() {
		return this.pixels;
	}
}


And I just checked to see if moving the class path to the “Source” tab helps. Same error occurred.

Class Path right now:

Try using the classLoaders getResource() method or removing the first ‘/’ from the path name.

http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResource(java.lang.String)

First of all, I reverted back by moving the “res” folder from the “Source” tab to the “Libraries” tab.

Then I tried using the ClassLoader method. When debugging, an error occurred saying the ImageIO.read() caught an unknown source URL.

Then I removed the ‘/’ in front of each of the file paths. Debugging the application works correctly, but it doesn’t work when I finished exporting it as a Runnable Jar.

Here is the error log via command prompt:

I also did a test to see if it’s a problem with Eclipse by creating a new Java project, using the load() method below, and then exporting it as a runnable JAR:


BufferedImage image = ImageIO.read(BaseBitmap.class.getResource("/test/this/folder/out.png");
//Yes, it is 3 folders deep.

The result show that the JAR executable runs correctly, with no error logs or whatever, and the out.png image is displayed properly on the screen. This led me to suspect that there’s something wrong with the setup that’s persistent in the GitHub repository.

Another thing I recreated that’s shown below (I reused and modified the screenshot as a test image.) Turns out that the exported runnable JAR outputted an error message in the command prompt stating: “no main manifest attribute in test.jar”. I now have no more clues to continue on.

Do you want the res folder to be packed inside the jar file itself?

[EDIT]: And also, re-read the links I posted about relative paths and how the getResource() method works and differns from class and ClassLoader.

Okay, I re-read the links. I think I have figured it out.

I put this code just before I used ImageIO.read() to get the resource URLs.

			Enumeration<URL> urls = this.getClass().getClassLoader().getResources(filename);
			for (URL url = null; urls.hasMoreElements();) {
				url = urls.nextElement();
				System.out.println(url.toString());
			}

What it does is, it outputs only 4 image URLs, when it should have been 5 image URLs. I went and check the file path in the source codes first, then commented out any references to the fifth image URL. Finally, I did an export of my project.

The result is a success. ;D

Now, I was curious as to why it’s not working before, so I went and check the resource file. Lo and behold, the resource file had a file extension name in all capital letters. (It should be “.png”, but it was “.PNG”.) The moment I saw it, I realized what it was: corrupted file.

I went ahead and fix the corrupted file by reloading/resaving/overwriting over the file with a fresh copy. Then uncomment the references I had in my source code. Debugged to check to see if everything is okay. Finally, re-export the project as a runnable JAR.

The result is now a success. ;D

You can actually tell what I did. Problem solved. :point: