Starter Code

From CS227B Wiki

Revision as of 18:40, 27 January 2010 by Newacct (Talk | contribs)
(diff) ← Older revision | Current revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

FAQs about CS227B code

How do I get syntax highlighting of .kif files in my editor?

See KIF syntax highlighting.

Starter Code

Players fail to play or play nil

There is a rather nasty bug in the starter code due to two classes which should be thread-safe not being thread-safe. These are the GdlPool and the SymbolPool. To fix this add the

synchronized

keyword to all of the method declarations. For example, the first method in Symbol pool should become

public synchronized static SymbolAtom getAtom(String value)

GdlPool is in util/gdl/grammar and SymbolPool is in util/symbol/grammar

Speeding up synchronized SymbolPool and GdlPool

We found that synchronizing every method in SymbolPool and GdlPool reduced the performance of our gamers on multicore machines by at least a factor of 2. An implementation with less overhead is available at Concurrent SymbolPool and GdlPool.

Speeding up Unifier

Profiling identified Unifier as a major bottleneck. Turns out, it uses exceptions in the normal control flow. This is bad for Java's performance. Getting rid of these exceptions sped up our program 5x. Here's the code.

No players show up in player panel on Unix-like OSes

In ProjectSearcher.java the line that begins

CP = CP.split

should become

CP = CP.split(System.getProperty( "path.separator" ))[0];

Apparently the classpath separator is platform-dependent.

Server crash if no stylesheet available

Right now the java server will choke if it tries to play a game for which no stylesheet exists. Either create an empty stylesheet with the right name, or you can do the following:

Change the

VisualizationPanel.observer(ServerNewGameStateEvent event)

function to be:

	private void observe(ServerNewGameStateEvent event)
	{
		boolean atEnd = index == gameStatePanels.size()-1;		
		ProverMachineState s = event.getState();
		
		try
		{
			String XML = s.toXML();
			String XSL = GameStateRenderPanel.getXSLfromFile(gameName+".xsl", 1); //1 because machinestate XMLs only ever have 1 state
			JPanel newPanel = GameStateRenderPanel.getPanelfromGameXML(XML, XSL);
			
			if(!gameStatePanels.isEmpty() && atEnd)
			{
				this.remove(gameStatePanels.get(index));
				index++;			
			}		
			
			if(atEnd)
			{
				tabs.add(Integer.toString(gameStatePanels.size()),newPanel);
				tabs.setSelectedIndex(tabs.getComponentCount()-1);
			}
			
			gameStatePanels.add(newPanel);
		} catch(Exception ex) {
			System.err.println("Visualization failed for: "+gameName);
		}
	}

And if you want to have less error text comment out

ex.printStackTrace(); 

in FileUtils.java.

sourceTextField sizing problems

The sourceTextField sometimes exhibits sizing problems when the server begins running a game. The new controls to the right sometimes push the controls to the left and make them small. The fix is to change the sourceTextField declaration in ServerPanel to the following:

managerPanel.add(sourceTextField, new GridBagConstraints(1, 0, 1, 1,
0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
new Insets(5, 5, 5, 5), 5, 5));
Native look-and-feel

To use the native look-and-feel, place the following code in your main() method:

try {
  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
catch(Exception e) {
 System.err.println("Unable to set native look and feel."); 
 e.printStackTrace();
}
Running PlayerPanel/ServerPanel from the console

To get the code to run from the console you need to cd into the bin directory and run one of:

 java -classpath "`pwd`":../src/external/FlyingSaucer/core-renderer.jar apps.player.PlayerPanel
 java -classpath "`pwd`":../src/external/FlyingSaucer/core-renderer.jar:src/external/JTidy/Tidy.jar apps.server.ServerPanel
Launching PlayerPanel/ServerPanel hangs with blank window

If you try to run the code on a machine that has more than one version of Java installed (for instance Java 1.5 and 1.6) and you might see only a blank window when you try to run one of the apps. The problem is that the code is setup to use the wrong JRE. You need to configure Eclipse to use your native JRE for the project:

  1. Open Project -> Properties
  2. Click on the Libraries tab
  3. Select the JRE System Library and click Edit
  4. Select Alternate JRE
  5. Click Installed JREs
  6. Click Add
  7. Next to JRE home directory click Browse
  8. Locate where the JRE is installed on your machine, on Debian Linux it is: /usr/lib/jvm/java-6-sun-1.6.0.10/jre
  9. The JRE System Libraries list should now be populated, click Ok and select the new JRE for use in the project

Performance optimizations

Using the server JVM

Eclipse uses the client JVM by default, but the server JVM is much faster -- for us, the speedup was about 35%.

To use the server JVM, you first need to tell Eclipse to use it to run your program. Click the little down arrow next to the play button which launches your program, and select "Run Configurations...". For each of your run configurations, add "-server" to the VM arguments (under the Arguments tab).

You may find that Eclipse now gives you an error about being unable to launch the server JVM when you try and run your program. (It might not display any error at all but instead just beep at you.) If that's the case, you probably need to add the server binaries to your JVM folder. The JDK (the Java compiler) has these binaries in *its* copy of the JRE. Anyway, just find your JDK and JRE and copy the files as suggested below.

copy from: C:\Program Files\Java\jdk1.6.**\jre\bin\server
copy to: C:\Program Files\Java\jre1.6.**\bin\server