Thursday, September 22, 2011

Fixing the PHP connection

I was so keen to minimize disruption to existing code that I forgot a couple of crucial steps. The first was to add the following line to public void init():

jso = JSObject.getWindow(this);

I also added the following diagnostic code to public void start():

if(jso != null )
addItem2("jso filled... ");

This enabled me to confirm that the jso object variable was filled as soon as the Applet opened.

The next necessary step was to tidy up the datInsert() function, which creates the SQL insert string, so that the string became:

ItemEntry = "INSERT INTO Items " +
"(Partid, OpCode, ItemLeft, ItemRight, Raw, Rate) " +
"VALUES (" +
sessTime + ", " +
OpCode + ", " +
ItemLeft + ", " +
ItemRight + ", " +
Raw + ", " +
SRate + ")";

The new variables ItemLeft and ItemRight were declared, but the old Itemdet was not removed, because it is still needed to populate a field. After that, with a few more comments thrown in here and there, the Applet ran.

Wednesday, September 21, 2011

Coding for a new database connection

When I worked for Mellon Bank, a favourite expression of my boss there was "If it ain't broke, don't fix it". I love that expression, and it really applies to what I am doing now.

Now I know you can work in the Collabnet working folder, but I prefer to copy files from there into another working folder, so I can just drag and drop from the original folder into another clean working folder when I stuff up. And because I am a little paranoid, the first thing I do is compile the code, just to make sure nothing strange has happened to prevent it doing so.

In the current version, the main class, AMJApp, makes a call to a function/method in my workhorse class QTrack.

The function call, which actually produces an argument for another local function is as follows:


And the function is:

public String datInsert() {
try {
ItemEntry = "INSERT INTO Items " +
"(Partid, OpCode, Itemdet, Raw, Rate) " +
"VALUES (" +
sessTime + ", " +
OpCode + ", '" +
Itemdet + "', " +
Raw + ", " +
SRate + ")";
buffer = "insert succeeds... ";
} catch(Exception ex) {
buffer = "SQLException: " + ex.getMessage();
return buffer;

Now, I want to minimize disruption, so the first thing I'll do is add another local function, which I shall call addItem3(String newWord). It is initially identical to addItem3(String newWord):

private void addItem3(String newWord) {
if(dbDEBUG) {

I quickly recompile to see if this has destroyed the delicate balance. It hasn't yet, so I make another small change, making the function call:


I have to do this three times in different places in the code. And I recompile again, just to be safe. All OK so far.

My next change is a very subtle one, changing the value returned by the function in QTrack from buffer to ItemEntry. I recompile both classes again, and so far all is OK.

Now comes the crunchy part. I've been putting it off for a long time because I know it will stuff everything up. I have to make the addItem3(String newWord) function do some work. This is the function which will pass the data line to PHP.

I shall borrow the code from a previous post in my Learning Java blog. This code includes a JSObject, and that is why it gets messy. The JSObject requires the import of netscape.javascript.JSObject, which in turn calls on a collection of classes which can be found in a java archive called plugin.jar, while my main class also calls on other classes. So the compile command is no longer a simple javac but rather:

javac -classpath "C:\Users\MJHIPP\Documents\Current\Java\CodeLocal\AMJ110920\plugin.jar";"."

I recompile again just to be safe, and then to be ultra safe I simply add the import line before recompiling with the new command. There was a bit of fiddling around, because that class path is a bit of a fiddle, but that is why I like to recompile after every small step. I can cope with one error, but not a whole screen full.

The next small step is to add the JSObject, and I put it right at the beginning, with my other supporting class declarations. Another recompile and all is still OK. Finally I have to add code to the addItem3(String newWord) function:

private void addItem3(String newWord) {
if(LIVE) {
if(jso != null )
try {"updateWebPage", new String[] {newWord});
catch (Exception ex) {

The modified class compiles just fine, but I now realise a fatal flaw in my methodology. I complied at every step but I did not check to see that the modified Applet actually ran. I was therefore very disappointed when it did not.

After some discussion on the Java Applet development forum it seemed to have something to do with JDK versions. And after fiddling for a while with cross-compilation options, I removed everything to do with Java from my computer, installed JDK 6.27, and recompiled, and now the new Applet runs.

It's not posting data yet, but hopefully that is a small diagnostic problem, to be fixed another day.

Tuesday, September 20, 2011

Database modifications

I need to modify the structure of my database, because I noticed in my practice AJAX call to PHP, the "+" sign was getting lost. I'm sure I could fiddle around to get it back, but I'd lose generality and I don't need it. I already store an operation code in the database, so I simply need to record the numbers being operated on in their own fields.

Rather than changing the fields in an old table, I'll just create a new one. As this is an open source project, for future reference and replication, it seems cleaner to record a single create command, than to recall a dud one and a series of changes. The SQL command was:

Partid BIGINT,
PRIMARY KEY ( Itemid )

I ran this with phpMyAdmin, because my ISP offers it, and it was quick and easy to do so.

I am now ready to make the coding changes in the Applet.

Monday, September 19, 2011

Review of current data insertion methods

Before changing the database and attempting to write new data insertion code, I need to refresh my memory of what the Applet currently does.

So in the second of four statutory Applet methods, public void start(), the Applet includes the following code:

if(LIVE) {

I like this construct, and I shall be sorry to lose it. The theory behind the code is described in a post entitled Functions in my Learning Java blog.

Essentially the explicit purpose of the method is to return a string for display in the Applet, but the database connection code is written into the code of the method, and the string returned is either connection succeeds or connection fails, depending on the outcome.

Anyway sadly, it has to go, because under the new rules, the connection code has to be contained in a PHP file.

In the third statutory Applet method, public void stop(), is the following code:

if(LIVE) {

This is just a void method, I guess because if the Applet is closing, there is nowhere to display any returned message.

Then in the core of the Applet code is the following:


This is another diagnostic display function, with data insertion code written into it, and it is run every time an item is completed. This is the code, which needs to be modified carefully to send a query to PHP, without disrupting too badly the functionality of the Applet.

Sunday, September 18, 2011

CollabNet Subversion

CollabNet Subversion can be downloaded from the CollabNet Subversion Downloads page. The manual can be read or downloaded from here, although the manual should come with the product download, and in Windows is even accessible from the Program menu.

To access code from an externally hosted project, such as my Rasch Itembank Project, only the client software needs to be installed.

And although they are kind enough to put the manual in the Windows GUI menu, the program itself has to be run from the command line. There is no need to set a binaries path, and if you navigate to the folder where you want to store your working copies of the code files, there is no need to set a target path either.

I had logged into my project from a browser before running the checkout command, and I was not asked for authentication when I ran it. The command for me was:

C:\Users\MJHIPP\Documents\Current\Java\Code\110918>svn checkout

This put a complete copy of my working files, including subfolders, into my working folder, as shown below. A quick glance at the screenshot will also reveal a batch file, which I used to run the svn command, to save typing.

On this occasion I simply added a stable working copy to the tags folder and reuploaded. To add the copy I had to use the svn copy command:

C:\Users\MJHIPP\Documents\Current\Java\Code\110918\rasch-itembank~svn\trunk>svn copy client C:\Users\MJHIPP\Documents\Current\Java\Code\110918\rasch-itembank~svn\tags\Client110918

The basic syntax of the command is similar to DOS copy, except that you simply have to name a folder and all contents will be copied.

I then wanted to add a text file explaining the significance of the copy. Here I had to create the file first and then use svn add. So this command does not create files, but adds them to some sort of a list.

C:\Users\MJHIPP\Documents\Current\Java\Code\110918\rasch-itembank~svn\tags>svn add Client110918.txt

Before committing the changes I wanted to run svn status. Initially I tried to run the from the parent directory into which I had downloaded my working copy, but it actually had to be done from the root directory of the working copy:

C:\Users\MJHIPP\Documents\Current\Java\Code\110918\rasch-itembank~svn>svn status

and the report came back:

A tags\Client110918.txt
A + tags\Client110918

The svn update command confirmed that nothing had changed on the server while I was working. I then added a comment to the svn commit command:

C:\Users\MJHIPP\Documents\Current\Java\Code\110918\rasch-itembank~svn>svn commit -m "Added working copy to tags folder."

My web log in had timed out by the time I did this, so I was prompted to log in again on the command screen.

Authentication realm: Subversion Repository
Username: jhipp117
Password for 'jhipp117': ******
Adding tags\Client110918
Adding tags\Client110918.txt
Transmitting file data .
Committed revision 12.

Having done this, I am now free to start hacking away at the main code.