Starter Code
From CS227B Wiki
FAQs about CS227B code
How do I get syntax highlighting of .kif files in my editor?
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:
- Open Project -> Properties
- Click on the Libraries tab
- Select the JRE System Library and click Edit
- Select Alternate JRE
- Click Installed JREs
- Click Add
- Next to JRE home directory click Browse
- 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
- 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
