Archive for Coding

Eclipse Debugging Error: ClassNotFoundException

I just hit a really annoying (sort of) bug in Eclipse. I could not debug any of my projects because they immediately stopped with a call stack like the following:

terrain.TerrainApp at localhost:49827   
    Thread [main] (Suspended (exception ClassNotFoundException))   
        ClassLoader.findBootstrapClass(String) line: not available [native method]   
        Launcher$ExtClassLoader(ClassLoader).findBootstrapClass0(String) line: not available   
        Launcher$ExtClassLoader(ClassLoader).loadClass(String, boolean) line: not available   
        Launcher$AppClassLoader(ClassLoader).loadClass(String, boolean) line: not available   
        Launcher$AppClassLoader.loadClass(String, boolean) line: not available   
        Launcher$AppClassLoader(ClassLoader).loadClass(String) line: not available   
        Launcher$AppClassLoader(ClassLoader).loadClassInternal(String) line: not available

I found people with similar issues on various message boards, but no solutions.

Then I figured out that if I kept hitting continue (to go past the breakpoint) it would eventually reach my actual application. Along the way though, java was triggering ClassNotFoundExceptions for every single class referenced in my code, which was causing Eclipse to break. It turns out that these ClassNotFoundExceptions are normal behavior – they are supposed to happen for every new class, but having eclipse set a breakpoint for each one is definitely not!

To solve the problem, I had to open up the breakpoint window and disable the breakpoint “ClassNotFoundException: caught and uncaught”  — I have no idea how this breakpoint got set in the first place, I certainly didn’t do it!

So now I can finally debug my programs without relying on tons of print statements… that should help my progress.

Comments (44)

Mini Tutorial: Making Java Webstarts

Here is a quick an easy tutorial for making a Java Webstart version of a Slick based game with the help of Eclipse. A more thorough wiki on the subject is available here, and an older and I think slightly out of date document is here.

Create a Jar file

First, right-click on your project and select “Export…”

Second, select a Java – Jar File.

Third, choose “Export generated classes and resources”, and put checkmarks next to any folders in your project which contain either source files or resources (images, sounds, etc). Fill in a name for the exported jar file, and hit Next.

Fourth, (optional) select the “Save description…” box and put in a place to save your export properties. This will allow you to easily export your jar file again later when you want to update your webstart.

Create a JNLP file

Fifth, we create a .jnlp file. This provides the meta information about your project like where it is located on the web, and what other libraries it requires. In Eclipse, choose to create a new File, and name it yourproject.jnlp.

Sixth, fill in the file with this template (borrowed from the Slick wiki)

<?xml version="1.0" encoding="utf-8"?>
<jnlp
  spec="1.0+"
  codebase="http://www.mydomain.com/games"
  href="mygame.jnlp">
  <information>
    <title>My Game</title>
    <vendor>My Vendor Name</vendor>
    <homepage href="http://www.mydomain.com"/>
    <description>My Game</description>
    <description kind="short">My Game</description>
    <icon href="icon.gif"/>
  </information>
  <resources>
    <j2se href="http://java.sun.com/products/autodl/j2se" version="1.4+" max-heap-size="128m"/>
    <jar href="mygame.jar"/>
    <extension href="http://slick.cokeandcode.com/demos/slick.jnlp" version="0.4"/>
  </resources>
  <application-desc main-class="MyMainStartupClass"/>
</jnlp>

Seventh, replace the generic info with the specifics of your project. In particular, you must specify:

  • codebase: the URL for the directory where your .jnlp and .jar files will eventually be stored
  • href: the name of the .jnlp file you just created

The title and homepage you can fill in as you wish.  In the <resources> section you can specify if your code requires a specific version of Java. The second line <jar href=”mygame.jar”/>, should be replaced with the name of the .jar file you made way back in step 3. Finally, the <application-desc main-class=”MyMainStartupClass”/> should specify the class in your project with the “main” method.

Send it to the web

You have now created the two files you need.  All that remains is to upload the .jar and .jnlp files to your webserver.  Be sure that you place the files into the same exact directory that you specified in the .jnlp file!

Tenth (sorry we skipped a few numbers), open up the URL of your .jnlp file and play your game!

What if it doesn’t work?!

A few things can go wrong.  Most comonly, you don’t set a path or file name right for either the .jnlp, .jar, or main class. Double check those first. Also, keep in mind that you cannot just change a local version of the .jnlp file on your desktop and double click it — you must upload the changed file to the server to make the changes have any effect.

If going to the .jnlp URL just results in showing you the text inside of the file, then you need to tweak some settings on your web server so it understands that web clients don’t want to read XML, they want to play your game! A couple of solutions to this are available here. Most likely you can fix the problem by adding these lines to a .htaccess file in the directory with your .jnlp:

AddType application/x-java-jnlp-file .jnlp

Hope that helps!

Leave a Comment

A Multi-layer Starfield

Everyone wants to grow up to be an astronaut [citation needed]. Sadly, I don’t think it is in the cards for me, so instead I am working on a little game where I can fly my own spaceship.

There was interest in how to make a parallax style starfield on the slick forums, so I figured I’d share some of my code.

package tspace.gfx;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.util.Log;

/**
 * This creates a starfield effect where different layers of stars scroll by at
 * different speeds as the player moves.
 * @author twood
 *
 */
public class SimpleStars {

	private Image img;
	private int TILESIZE = 512;
	private float x, y;
	private int width, height;
	private float[] depths;

	/**
	 * Creates a new starfield
	 * @param w - width of the canvas to draw to
	 * @param h - height of canvas
	 * @param depths - an array of floats specifying the depths of the star layers.
	 */
	public SimpleStars(int w, int h, float[] depths){
		loadImage();
		width = w;
		height = h;
		this.depths = depths;
	}

	/** Load the images used for different layers of the star field.
	 *
	 * This uses the same image for all layers, but can be extended to use
	 * different ones at different depths.
	 *
	 * @param i the layer to be loaded
	 */
	public Image loadImage()
	{
		if(img == null)
		{
			try
			{
				img = new Image("res/stars.png");
			}
			catch (SlickException e) {
				Log.error("ERR loading star image", e);
			}
		}
		return img;
	}

	/**
	 * Render each layer of the starfied. Works by determining a different offset for
	 * each layer to give the effect that some are moving faster than others.
	 *
	 * @param g the graphics context to draw to.
	 */
	public void render(Graphics g)
	{
		g.setDrawMode(Graphics.MODE_ADD);
		for(int d=0; d < depths.length;d++) {

			float scale = depths[d];
			float cornerX = x/scale-width/2/scale;
			float cornerY = y/scale-height/2/scale;
			float startX = (float) (Math.floor(cornerX/TILESIZE)*TILESIZE);
			float startY = (float) (Math.floor(cornerY/TILESIZE)*TILESIZE);
			float offsetX = -cornerX;
			float offsetY = -cornerY;

			for(int row = (int) startY; row < startY+2*height; row+=TILESIZE)
			{
				for(int col = (int) startX; col < startX+2*width; col+=TILESIZE)
				{
					g.drawImage(img, col+offsetX, row+offsetY);
				}

			}
		}
		g.setDrawMode(Graphics.MODE_NORMAL);
	}

	public void setPos(float x, float y) {
		this.x = x;
		this.y = y;
	}

}

This class can be used to generate the starfield. In an init() function, you might call sometin like this to create a starfield with 5 layers:

float[] depths = {12f, 8f, 5f, 3.5f, 1f};
stars = new Starfield(container.getWidth(), container.getHeight(), depths);

Then in the update() function of your game you must call setPos(x,y) to specify the current position of the camera. Finally, you must call render(g) to actually display the graphics.

You can use this star image, or you can create your own.

How it works: The basic idea is that you have multiple star images which get layered on top of each other with different offsets.  As you move around, the front layer’s offset moves quickly, while the back layers will move more slowly since their offset is adjusted in a different ratio. This ratio is determined by the depths array. Larger numbers are used for further back layers of stars.

Note: This code assumes you are using the Slick library – to learn more about slick, go here.

Comments (2)