Puzzled by bug and bug fix

I bumped into a strange bug the other day. I found a way to fix it, but I have no idea why it works and I’m wondering if someone can explain it.

Here is the situation. I built a small set of classes to aid in my game development. One class, “SoundFactory”, has only static methods for loading and playing Clips. It also has two static fields for HashMaps. I never intended to create an instance of SoundFactory.

The first game that I wrote with the help of SoundFactory worked fine, but the next one did not. The code simply stopped executing somewhere soon after a call to a SoundFactory static method. Subsequent Game runs always stopped at the same place, until I commented out a few miscellaneous instantiations. Then the code consistently stopped at a different spot. The “stopping spots” always included an instantiation. No errors were thrown. Code just stopped executing.

So why did Game1 work and not Game2? I commented out code until I finally found the difference. Game1 had the following field declaration/assignment:

Color color = Color.BLUE;

When I added this seemingly irrelevant line as a field for Game2, the code ran fine.

Can anyone explain what I was doing wrong? I am guessing that I should abandon the whole static idea, but I am still curious about what the hang-up might be.

I code in 1.4 using Eclipse with my Mac, 10.3.

thanks,

josh

You should post (parts of) your code to get proper help.

Ok, here is a pared down version of Game and SoundFactory. The code hangs in the Game constructor on creating a JFrame. The same hang happened with all sorts of other classes – it doesn’t have anything to do with JFrame. If I do not call the SoundFactory loadClip method, the JFrame is created. Most puzzling is this: when I leave in the call to loadClip, but also create a reference to a static constant, everything works fine??? This only works if a actually assign the field to a static constant: just declaring it doesn’t work.

Any insights would be appreciated.

[quote]public class Game {

//Color x = Color.BLACK;

public Game() {
	File b = new File("resources/Boom.wav");
	SoundFactory.loadClip(b, 3);

	System.out.println("About to create JFrame");
	JFrame jf = new JFrame();
	//following line doesn't happen unless I uncomment Color, above
	System.out.println("Created JFrame");
}

public static void main (String [] args) {
	new Game ();
}

}
[/quote]

[quote]public class SoundFactory {

private static HashMap availableClips;

static {
	availableClips = new HashMap();
}

public static void loadClip (File soundFile, int howManyCopies) {
	try {
		for (int x = 0; x < howManyCopies; x++) {
			InputStream is = new FileInputStream(soundFile);
			loadClip (is, soundFile.getName());
			is.close();
		}
	}
	catch (Exception e) {
		e.printStackTrace();
	}
}

public static void loadClip (InputStream is, String name) {

	if (!availableClips.containsKey(name)) {
		availableClips.put(name, new LinkedList());
	}
	
	List list = (List) availableClips.get(name);

	AudioInputStream audioInputStream = null;
	
	try {
		audioInputStream = AudioSystem.getAudioInputStream(is);
	} catch (UnsupportedAudioFileException e1) {
		e1.printStackTrace();
	} catch (IOException e1) {
		e1.printStackTrace();
	}
	
	AudioFormat	format = audioInputStream.getFormat();
	DataLine.Info info = new DataLine.Info(Clip.class, format);
	Clip clip = null;
	try {
		clip = (Clip) AudioSystem.getLine(info);
		clip.open(audioInputStream);
		list.add(clip);
		
		audioInputStream.close();
	}
	catch (LineUnavailableException e) {
		e.printStackTrace();
	}
	catch (IOException e) {
		e.printStackTrace();
	}
}

}
[/quote]

This really sounds like a race condition as the assignmetn has no effect on the code in question other then chnaging the timing.

Id have to look closer though to determine exactly what is racing…

what is a race condition?

http://java.sun.com/docs/books/tutorial/essential/threads/priority.html its been a while since I read it but I beleave it was in that section, its somewhere in the trail adleast