Monthly Archives: November 2014

Swafford Consulting Hired for TrACER-R Project

I’m very pleased and excited to announce that Swafford Consulting has been selected by IVIR Inc. (Information Visualization and Innovative Research) to rewrite and expand the Training/Test Assessment Capabilities and Reporting for Research (TrACER-R) System.

The following information has been publicly released by IVIR and posted on this website with permission from them.

TrACER is an automated assessment and evaluation system, designed for research and test conduct. It automatically produces test instruments, collects tests data, correlates data and produces both statistical and descriptive analysis for final test reports. The system can be used for any procedure or skill set identified in critical research areas. It produces objective evaluation of subjects, and observer/controller performance for cognitive tasks, psychomotor skills, affective measurement, and decision making performance. It is particularly useful for medical research.

Swafford Consulting has done work for IVIR before, on the F2MC Trainer project .

JBoss 7 – Channel end notification received, closing channel Channel ID (inbound) of Remoting connection to null

As mentioned in a previous post I’ve recently upgraded to JBoss EAP 6.2 / AS 7.1. For a few weeks after the transition a small set of users were complaining about a ‘channel closed’ error. Few errors have driven me crazier than this one. It was not a good time, for me or the users.

After receiving this error the user was unable to do anything in my application; they had to shut it down and restart. In the server logs I was also seeing a steady stream of :


java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling

I try pretty hard to minimize the possibility of bugs. But, every once in a while one does pop up, and when it does I try to reproduce it in a development environment, write a failing test, and then solve the problem. Try as I might, I just could not reproduce this error in a development setup. After some time it became clear that the error had something to do with their environment.

Well, it turned out that about the same time I updated the application servers, the IT staff were busy upgrading firewalls. They pulled a Linux based firewall and replaced it with a Cisco ASA (I can’t remember the exact model). These ASAs are pretty clever. They have some logic built into them to detect when a connection is ‘dead’ and then forcibly closes the connection. What happens is, after about 30 minutes of inactivity the firewall decides that the connection between the application client and the server (which is offsite in a data center) must be dead, so it kills it, unbeknownst to the application. Then, the user goes to do something again, and the dreaded ‘Channel Closed’ error would appear.

You might think that is the end of the story. I wish it were.

Once the problem became clear I knew the solution would be to use some sort of ‘keep alive’ on the connection. And, as it turns out there is a way to do that. Just set this property (either in XML or programmatically as I do here):


clientProp.put("remote.connection.default.connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL","60000");

The issue was that I was mixing two different approaches to establishing remote connections, with the consequence being that my ‘heartbeat’ configuration was not taking effect. One method, which appears to be the less superior but better documented approach, is to use remote naming. There is also the EJB Client API, which according to this page is the better approach (though it doesn’t tell how to use it).

Long story short: if you want to use the EJB Client API, then your Context lookup should look something like this:

private static void getContext(String login,String hashedPassword) throws NamingException {
   Properties clientProp = new Properties();
   clientProp.put("endpoint.name", "programmatic-client-endpoint");
   clientProp.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
   clientProp.put("remote.connections", "default");
   clientProp.put("remote.connection.default.port", "4447");
   String namingProvider = System.getProperty("java.naming.provider.url");
   if (namingProvider==null) namingProvider="localhost";
   clientProp.put("remote.connection.default.host", namingProvider); 
   clientProp.put("remote.connection.default.username", login);
   clientProp.put("remote.connection.default.password", hashedPassword);
   cientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
   clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
   clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
   clientProp.put("remote.connection.default.connect.options.org.jboss.remoting3.RemotingOptions.HEARTBEAT_INTERVAL","60000");
   EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(clientProp);
   ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
   EJBClientContext.setSelector(selector);		
 
   Properties p = new Properties();
   p.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
 
   ctx = (Context) new InitialContext(p);
}

In particular please note that the Properties object passed into the InitialContext has just one key/value pair — the one that tells it to use the EJB Client API. All other configuration options should be passed into the PropertiesBasedEJBClientConfiguration. In my case I had some extra/ superfluous “stuff” in the Properties given to the InitialContext, and as a result the heartbeat messages were not going out. I think it had fallen back to using remote naming, but I can’t be sure. Once the extra junk was removed everything started working as expected.

chess4j learns some moves from Kasparov

Ok, “learn” is too strong a word. More accurately, chess4j now has a small opening book database populated with a little over 500 Kasparov games. Before doing any thinking on its own, chess4j will consult this database, and if a move is found it will play it. This has the effect of steering the game into a nice position that a Grandmaster might play fairly quickly, and it also adds some more variation to the opening moves as well.

500 games is not a lot, but at the moment the opening book is all contained in memory. That is, when the program starts it reads through those 500+ games, storing them in internal memory, and holding them in memory for the duration of the program’s execution. The next time it starts, it does it again.

I’m really pretty happy with the way this all came together. Here is the method that initializes this in memory opening book:

private static void initBook() throws Exception {
	OpeningBook book = OpeningBookInMemoryImpl.getInstance();
	FileInputStream fis = new FileInputStream(new File("pgn/Kasparov.pgn"));
	PGNIterator it = new PGNIterator(fis);
 
	PGNGame pgnGame;
	while ((pgnGame = it.next()) != null) {
		book.addToBook(pgnGame);
	}
 
	fis.close();
}

As you can see there are a few key classes that make this all work. First, we need an OpeningBook. OpeningBook is an interface, which in this case is implemented by the Singleton OpeningBookInMemoryImpl. I won’t go into the in memory implementation here, because in the future that will be replaced with something with a persistent datastore behind it (maybe MongoDB). But, I will show the interface it implements:

public interface OpeningBook {
 
	public void addToBook(PGNGame game);
 
	public List<BookMove> getMoves(Board board);
 
	public BookMove getMoveWeightedRandomByFrequency(Board board);
}

Pretty simple at the moment, and likely to be expanded. The key points are that you can add a move to the book, or get a list of BookMoves in a given position, or you can get a single BookMove using a weighted random selection algorithm.

Now that we have an OpeningBook, we need something that is capable of reading through a Portable Game Notation (PGN) file, producing a sequence of PGNGame objects.

PGNGame is really just a data object so I won’t show the code here. It really just encapsulates a game, which we can think of as a series of PGN tags, a list of moves, and a result (win, loss, draw).

The PGNIterator class is a little more interesting though. Since some of these PGN files get fairly large (40-50 mb is not unusual), it’s best to take a ‘streaming’ approach to processing them. Hence, if you look back at the initBook() method, you’ll notice the constructor for PGNIterator is given a FileInputStream. (It will accept any type of InputStream, which it uses internally to create a BufferedReader.)

Here is the next() method of PGNIterator :

public PGNGame next() throws IOException, ParseException, IllegalMoveException {
 
	PGNParser parser = new PGNParser();
	String nextGame = getNextPGN();
 
	if (nextGame != null) {
		return parser.parseGame(nextGame);
	}
 
	return null;
}

I’m glossing over a few details here but hopefully that gets the point across. The call to getNextPGN() looks far enough ahead in the stream to capture the String representation of a game, or returns NULL if it can’t (probably because it hit the end of the file). It then uses this PGNParser to convert the String into a PGNGame. As you might imagine PGNParser uses some regular expression stuff that frankly made my head hurt a little. Finally, we saw above that the PGNGame is added to the opening book.

All of this is part of the 3.0 development so it’s not in the latest release, but the source code is available (along with several unit tests) so if you’re the developer type feel free to check it out from the project website on SourceForge .