Saturday, January 31, 2009

Elements of the JNLP File

In my last blog I attempted to run an applet using the following jnlp file::

<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for ActiveMath -->

<jnlp spec="1.0+"
codebase="http://202.65.70.207/myweb/"
href="AMJ002.jnlp">
<information>
<title>Active Math Java Test</title>
<vendor>Softway Interactive Education</vendor>
<description>Active Math Java Test</description>
<homepage href="http://202.65.70.207/myweb/index.htm"/>
<description kind="short">ClickMeApp uses 1 custom class plus 1
standard one</description>
<offline-allowed/>>
</information>
<resources>
<jar href="ActiveMathJA002.jar"/>
<j2se version="1.6+"
href="http://java.sun.com/products/autodl/j2se"/>
</resources>
<application-desc main-class="AMJFormA002"/>
</jnlp>

The error message gave me a clue that perhaps I had not recorded the path to the Java bin file as an environmental variable. I had some trouble doing this on the old PIII I use for writing, but on the newer Core2 Duo, which I am using as a server, it was textbook doddle; computers and Windows installations degrade over time, and little things eventually don't work. Intermittent gremlins in Windows ought to be documented somewhere, but when some poor innocent experiences such a problem, and posts a question in a forum, it is amazing, the arrogance (illustrated here) with which some people respond.

I digress. The point is that after setting the path, I could run the jar file from my web directory, using the command prompt, but still not from a browser using the jnlp file. The error message was different, less informative, but still the application did not run. So I thought I'd continue the lesson by cross referencing my file with the elements table.

And of course the XML elements are not in the table. At the beginning of the tutorial we were given 4 screenshots to explain the simplest command, but now it is assumed we are all intimate with XML.

The first element to be explained, somewhat tautologously, is jnlp - the main xml element for a jnlp file. We are given a range of values for the attribute spec, including the wild card used in my file. The codebase is the URL for the folder hosting the jnlp file, and href gives the URL of the jnlp file relative to the codebase (which in this case is simply the filename).

Information is a containing element, which as the name suggests contains elements giving information about the application. I shall refrain from going through these as they are all pretty obvious, and do not seem essential to the running of the app.

Resources seems to be another containing element which: "Describes all the resources that are needed for an application". The first such contained in my file is jar, which: "Specifies a JAR file that is part of the application's classpath". The first attribute used in my file is href, which gives the URL of the jar file (relative to the codebase).

And now it gets confusing. Version, as an attribute of the jar element, is defined as "The requested version of the jar file". This is clearly not what is meant by the j2se version attribute in mine and the notepad jnlp file. And typically for this "non" tutorial, j2se, one of the tags used in their own example, does not appear in the elements table. What does appear as an attribute of the jar element is main, which: "Indicates if this jar contains the class containing the main method of the application", but again typically for this non-tutorial, no syntax or range of values is given.

The final element used in the example file is application-desc, which "Indicates if this jar contains the class containing the main method of the application", and the only attribute of this element is main-class, "The name of the class containing the public static void main(String[]) method of the application".

Maybe, therefore, the syntax of the attribute main in the element jar is similar to main-class in application-desc. Certainly that would be logical. Unfortunately the designers of java seem to have a rather limited grasp of logic, so I am not holding my breath, but I will try it. I'll remove the element j2se and it's attribute href (because according to the table it is not needed), and replace it with the attribute main. The finished file will look like this:

<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for ActiveMath -->

<jnlp spec="1.0+"
codebase="http://202.65.70.207/myweb/"
href="AMJ002.jnlp">
<information>
<title>Active Math Java Test</title>
<vendor>Softway Interactive Education</vendor>
<description>Active Math Java Test</description>
<homepage href="http://202.65.70.207/myweb/index.htm"/>
<description kind="short">ClickMeApp uses 1 custom class plus 1
standard one</description>
<offline-allowed/>>
</information>
<resources>
<jar href="ActiveMathJA002.jar/ main="AMJFormA002"/>
</resources>
<application-desc main-class="AMJFormA002"/>
</jnlp>

I still can't get the sodding thing to work, but I have doubts about that main attribute, and the forward slashes, which seem to be scattered through the notepad.jnlp file quite at random.

Monday, January 26, 2009

Testing the JNLP File

In my last blog I attempted to reverse engineer the notepad example and ended up with the following text:

<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for ActiveMath -->

<jnlp spec="1.0+"
codebase="http://202.65.70.207/myweb/"
href="AMJ002.jnlp">
<information>
<title>Active Math Java Test</title>
<vendor>Softway Interactive Education</vendor>
<description>Active Math Java Test</description>
<homepage href="http://202.65.70.207/myweb/index.htm"/>
<description kind="short">ClickMeApp uses 1 custom class plus 1
standard one</description>
<offline-allowed/>>
</information>
<resources>
<jar href="ActiveMathJA002.jar"/>
<j2se version="1.6+"
href="http://java.sun.com/products/autodl/j2se"/>
</resources>
<application-desc main-class="AMJFormA002"/>
</jnlp>

which I saved as AMJ002.jnlp.

Before testing this home made code I cut and pasted the whole notepad example, saved it as notepad.jnlp in my web folder, and downnloaded the notepad.jar file into the same folder. I then copied the following from the tutorial:

If you click this link to the Notepad.jnlp file, you open and run the Notepad application from the sun server.

and pasted it into my web page. It obviously worked because it points to the original jnlp file on the original server. I then modified the pasted link as follows.

If you click this link, you open and run the Notepad application from my server.

To my amazement, the link worked, and Notepad opened, when I clicked on the link. (NB mine is a private server and it may not be turned on if and when YOU click on the link).

Then came the real test. Posting a link to my cobbled together file to run my app. Everything seemed to be fine until the moment when the app should have opened, and I got an error message saying: Unable to launch the application Active Math Java Test published by Softway Interactive Education from the server 202.65.70.207.

Disappointing ...

Sunday, January 25, 2009

Creating the JNLP File

This lesson is a subsection of the Deploying Java Web Start Applications lesson begun 2 blogs ago, and it continues to be as brilliantly written. It begins with an example. Examples are nice, but in most teaching traditions they are used to illustrate lessons already learnt from first principles. Sometimes they are posted early in a lesson to stimulate thought, and then referred back to as the the lesson unfolds to explain the principles applied in the example. In this case, there is actually no lesson, before or after the example. Instead there is simply a list of elements and attributes. It reminds me of the user manual for MS BasicA, which was published in 1982. I thought user documentation had progressed since then, but obviously not here.

It is hard to believe this is the same tutorial which used a screen shot to explain how to save a text file. Now we are left to reverse engineer a fiddly piece of code, with lots of redundant or superfluous tags, and translate it into something which applies to one's own code.

I personally have no experience manually coding anything in XML. I followed the web quite closely when it first began, and read up thoroughly HTML1 and HTML2, but after that, tools like Fireworks and FrontPage made it unnecessary for to keep pace with developments in the raw code of the web. GUI tools also introduce artists into the field of web development, and I ducked out.

The code in the example is therefore pretty unfamiliar to me and I shall look at it a line at a time. And the first line is no exception:

<?xml version="1.0" encoding="utf-8"?> 

I have no idea why the tag is surrounded by question marks, but there is nothing specific to the notepad app, so I shall cut and paste it in its entirety. The next line is a comment, and could be left out, or modified for ones own app:

<!-- JNLP File for ActiveMath --> 

The next line frankly looks recursive, because it posts a link to itself, but I guess for me it translates as follows:

<jnlp spec="1.0+"codebase="http://202.65.70.207/myweb/"
href="AMJ002.jnlp">

Then there is a whole section called information. I am sure this could be left out altogether, but I'll stick in an amended version for fun:

   <information>     
<title> Active Math Java Test</title>
<vendor> Softway Interactive Education</vendor>
<description> Active Math Java Test</description>
<homepage href="http://202.65.70.207/myweb/index.htm"/>
<description kind="short">
ClickMeApp uses 1 custom class plus one
standard one</description>
<offline-allowed/>
</information>

The next section called resources contains a line I don't understand. The first line is simple enough. It simply points to the jar file and becomes:

<jar href="ActiveMathJA002.jar"/> 

But the second one points to a directory on Sun's server. Do I use that, or do I use the j2se folder on my computer? I can't find a j2se folder on my computer, so I'll leave the URL pointing at Sun:

<j2se version="1.6+"
href="http://java.sun.com/products/autodl/j2se"/>

Finally there is a tag defining the main class in the applet, which in my case becomes:

<application-desc main-class="AMJFormA002"/> 


Saturday, January 17, 2009

The joys of Microsoft IIS

I had a problem installing IIS and as it was asking for the XP SP3 CD, I downloaded SP3, slipstreamed with my existing XP install files, and burnt a new bootable CD. And I hardly need record that IIS still wouldn't bloody well install. An illustration of the nightmare is given in this thread on the MS Community forum. Check out the tizzy some of the participants get into. The solution for me was given in the penultimate post in this long thread and it may be reached with this link.

Of course I had forgotten how set folder security through IIS, and I hadn't a clue which port was being used. The answers were provided for me in this thread in the MS forum (whatever faults MS may have, and despite the large egos of the some of its users, the forum is an excellent resource). I duly copied my web to inetpub (in a subfolder called myweb), allowed anonymous access, allowed access through port 80 in the Windows firewall, and mapped port 80 to the appropriate pc in my router.

To my amazement, not only could I view the web on my local network but also using my wan IP address. I am so pleased, I'll put a link here, although in case anyone wants to look at the site when my computer is turned off, I'll put a link to the ISP hosted version here.

Adding the JNLP MIME type was a bit more tricky. I seem to be the only person in the world still using IIS 5.1. For those using later editions here is a blog giving cryptic instructions, here is a discussion on the topic and here is a set of instructions which didn't apply to me but gave useful clues. But I can't test what I have done yet, because I haven't created the jnlp file.

Thursday, January 15, 2009

Setting up a Web Server

In the context of the Java Tutorial as a whole, the topic of Applets is a major section in the Deployment trail. It is preceded by another largish section Java Web Start. This promises "to launch full-featured applications with a single click". At this stage all I want to do is to launch my mini app with a single click, so I really don't want to get bogged with detail here.

But I am not optimistic. The second paragraph refers to a JNLP file, whatever that is. My hopes of a "quick" start are fading. It looks as if there is a lot to work through. And if you follow the thread in order, the first lesson, Running Java Web Start Applications, is interesting from the perspective of trying out the technology, but from my perspective useless right now, because it assumes the JNLP file already exists.

The second lesson, Deploying Java Web Start Applications, looks more hopeful but it contains a number of potentially quite tricky steps. And in the lesson the first of these, Setting up the Web Server, is as useful as the proverbial mammary gland on the male of a bovine species. I guess this is a Java tutorial not a website management tutorial, but as they provided detailed instructions on running that silly Hello World app on three different operating systems, They might have put at least some sort of link here.

I have set up a web server on Win2k, but it was a long time ago and I am rather rusty. A quick search reminds me I have to install Microsoft's Internet Information Service (IIS) using the Control Panel. But I now have XP SP3 installed and my Windows CD is only SP2. The problem I encounter is similar to this one (except that for me everything translates as SP3 not 2). To fix it apparently I have to slipstream XP3 into a new CD. What a bore. I so hope MS goes broke or falls into obscurity in my lifetime. The simplest task is always a bloody nightmare. Why do I still use them? Because I have yet to install a Linux distro that does everything for me. One day I might start a Linux blog, because I've certainly wasted a few hours fiddling around with it. Anyway, slipstreaming is a chore, but it's not that hard. My reference point for the task is a web site called theeldergeek. His page on slipstreaming SP3 is here.

An important ingredient is the network professionals version of SP3. It is a 316MB file, but do MS offer you a bit torrent option? No, that would be too sensible. So I have to go to thepiratebay to get a perfectly legal file. The download could be dodgy, it could wreck my computer, or it could simply not work. But the size looks exactly right, so I'll start to bring it in with Azureus. There seem to be lots of seeds and it's coming in quite fast, but it will take a few hours, so I'll continue tomorrow.

Wednesday, January 14, 2009

Running JAR-Packaged Software

In The Java Tutorial, the lesson on running jar package software opens by introducing three scenarios:

  • Your JAR file contains an applet that is to be run inside a browser.
  • Your JAR file contains an application that is to be invoked from the command line.
  • Your JAR file contains code that you want to use as an extension.
The second of these I have already covered, I have no idea what the third means, so I shall focus on the first. I shall create an experimental page on my web site to test the line by line. From the example given:
"open brace"
applet code="TicTacToe.class"
archive="applets/TicTacToe.jar"
width="120" height="120"
"close brace"
I shall post:
"open brace:
applet code="AMJFormA002.class"
archive="ActiveMathJA002.jar"
"close brace"

I have removed the height and width parameters because they don't apply to my app.

When I refresh my page I get a brief flash of the java logo, then a long error message.

Ages ago, I read that something needs to be installed on the server side, and when I checked with my ISP they replied that they didn't have it and weren't planning to any time soon. Perhaps bad people plant java applets in web pages to do bad things. Be that as it may I must find out what it was. I shall follow the link to the Applets lesson.

Tuesday, January 13, 2009

A close look at the NetBeans output

My intention at this point was to visit the lesson on running jar package software, but NetBeans, after building the app, suggested running it with the following command:

java -jar ActiveMathJA002.jar

I think I'll try that first, as I have a command window open and all the files are in the right place.

Well the command worked OK, and my app opened, but it didn't work properly. Months have passed since I drafted the code, but it seemed as if an early version was running. Why would it work one way when run from within NetBeans and another when run as a stand-alone?

I commented earlier that I was surprised to see draft versions included in the NetBeans built jar file. I think I'll take the drafts out. While I'm at it I'll check the dates of the main class files.

The date on the class files extracted from the jar file is Aug 31 2008. That seems wrong, because I ran the build command yesterday. Checking out the build folder, there are two class files with slightly more recent dates (September 2 2008). I'll use them and rerun the command to build the jar file with the specified entry point and see what happens.

Now it's looking for

AMJFormA002$2.class
which I assumed was an early draft. So I'll add that back to the folder I'm using for my manual build. Now the app runs pretty much as it does from NetBeans. There is some stuff being written to standard output which I thought I'd commented out, but besides that the basic execution path seems to be the same.

A number of questions arise from all of this:

  • Why don't the built file dates match the last time I ran the build command?
  • Why is has the jar file an earlier date than the class files?
  • Why are three class files needed for the main class?
  • Why was the entry point not included in the manifest?

It turns out that the answer to all of but one of these questions was that for some reason I was running NetBeans from a backup drive, and therefore running the tests on the wrong files. When I looked closely at the correct jar file, everything was as it should be. The main class still seemed to made up of three files, but apart from that everything was fine.

Monday, January 12, 2009

Setting an Application's Entry Point

In the Java Tutorial, this lesson begins with the example:

Main-Class: MyPackage.MyClass

Notwithstanding all the work on packages in recent blogs, I'm still working with the jar file made from the version without a custom package assigned. But according to a recent post on the beginners' forum, if the class is in the default package, this line reads:

Main-Class: MyClass

Which in my case will be:

Main-Class: AMJFormA002

I have saved this line (with a carriage return at the end) in a file called entry.txt. Now I have to run the generic command

jar cfm MyJar.jar Manifest.txt MyPackage/*.class

Which in my case translates as:

jar cfm ActiveMathJA002.jar entry.txt *.class

Before doing this I note the the current jar file has the date Aug 31 08 (how time flies). There's a pause but no error messages when I run it. And sure enough the jar file date has changes. I'll just file away the expanded contents and run the extract command again to see what's in the new jar file. That looks good, and now the new manifest reads:

Manifest-Version: 1.0
Created-By: 1.6.0_03 (Sun Microsystems Inc.)
Main-Class: AMJFormA002

I believe at this point I am ready to try running the app.

Sunday, January 11, 2009

Checking the NetBeans jar file

I've noticed in the fora that when people using IDE tools run into difficulties there is a chorus from the crowd that they should learn to do it all manually before working with fancy tools. I have also noticed that NetBeans has produced a so-called executable jar file for me, but before trying to run it, I'll use the lessons to check out a few details.

First I'm just going to try out the code in the Viewing the Contents of a JAR File lesson to check the content of the jar file. The output is as follows:

META-INF/
META-INF/MANIFEST.MF
AMJFormA002$1.class
AMJFormA002$2.class
AMJFormA002.class
AMJQGenA002.class

I am curious that the jar file seems to include two early drafts of the main class. That's not a problem now (the file is still only 10kb) but it could become an issue in the future. Besides that everything seems to be there. A manifest seems to have been included although I am not sure what it says.

I'll now apply a code scrap from the lesson Extracting the Contents of a JAR File to check out the manifest. The files extract to the folder where I ran the code and the manifest extracts to the subfolder meta-inf. I open the manifest with a text editor and the contents are:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.6.0_03-b05 (Sun Microsystems Inc.)
X-COMMENT: Main-Class will be added automatically by build

This is interesting, because according to the lesson Setting an Application's Entry Point, an entry point needs to be set. Why hasn't NetBeans done this? The last line could be a clue. Because the jar file existed, I assumed the build command had been executed when when I ran the app. I'll select build explicitly from the build menu and try again. No it hasn't made any difference. The last line was lying. Now I'll have to go through the tedious manual process outlined in the lesson.

Saturday, January 10, 2009

Packages and packages

My first instinct when I had created an applet, with a beginning, a middle and an end, was to deploy it - to make it run outside the NetBeans IDE. I needed to revisit packaging not least because the first lesson in the Deployment Trail is entitled Packaging Programs in JAR Files (my italics). What induced Sun to use such confusing nomenclature? It was only after spending hours pouring over every word in the Packaging trail, that I realised that the two concepts are wholly unrelated.

The term package in the context of classes and interfaces refers to an implicitly defined collection of source code files. Belonging to a "package" is an attribute of a source code file, given in the first line of code.

The term package when used in the Java tutorial in the context of deployment has the more common (in my opinion) meaning of bundle of files, or archive, like a zip or rar file. And the file extension of the package even sounds like rar. It is in fact jar, which is presumably an abbreviation of "java archive".

Having sorted that out, I am now ready to start the first lesson in the packaging (second meaning above) trail: Using JAR Files: The Basics. After describing a .jar file in the previous paragraph as like a zip file, I am pleased to read in the first line of this lesson: "JAR files are packaged with the ZIP file format". Why can't they call the sodding things zip files and shorten the Java learning curve a bit?

The lesson continues with instructions on how to create and view jar files and various other routine tasks, and more interestingly how to run an application packaged as a JAR file. Given that most readers will have worked with PKZip and other archiving tools, I shall refrain from plodding through these lessons line by line, but I shall refer to them as I need them.

Thursday, January 8, 2009

Re-using code

So now I have an applet which works (and works jolly well, though I say so myself), but the code has been assigned to the wrong package, and I'd like to start again, with everything assigned to an appropriate package, but I don't want to fiddle around with the graphics on the JFrame getting all the shapes sizes and fonts right again. So I want to reassign the classes I've already created to the right package.

Coming from a Microsoft background, I think in terms of exporting files to a package, and I look in the file menu for something resembling export or import. There is something for project groups, but nothing about assigning files to packages or importing or exporting. Next I look in tools. Maybe there is a package assignation tool? No luck there. Options? I am clutching at straws now.

So I scan through every menu, and find nothing. Maybe if I right click on the class file icon there will be a context menu item about assigning the class to a package. But no, I can only open, copy or paste. There is an idea. Let's copy it into a new project. Hmm that seemed to work. At any rate the class has attached itself to the new project tree. I think I'll do that for the other class in the original project.

And I also remember noticing in the context menu for the project there is a create new package option. I'll try that. I'll call it JHipptest. And now I'll try dragging the pasted classes in to the new package. Hmm that seemed to work. But I can't open them. I know, let's copy and paste the source code from the original project into the new package. Now let's have a look at the code, and Yes! very cleverly NetBeans has added "package JHipptest;" as a first line in the source code.

I have spent weeks and months researching this in fora, NetBeans help, and the tutorial to no avail. It reminds me of when I first used a Mac. I had to ring a technician to ask how to delete a file. There was no right mouse button, and nothing about file deletion in the menus. I felt a real fool when I was told I just had to drag the file to the Trash. Maybe NetBeans was written by an old Mac user.

In summary, it is not a disaster if you forget to assign your class to an appropriate package when you first create the source code in NetBeans. You simply add a package to your project, and then drag your source file to the package node in the project explorer pane. And you don't need to start a new project as I did - you can do it all in the original project. On the other hand, if you want to use existing code in a completely new project, it is simply a matter of copying and pasting the source files in the project explorer pane.

Sunday, January 4, 2009

Applying the lesson

After completing the introductory trail Learning Swing with the NetBeans IDE, I decided to apply the lesson by building an applet of my own. Like the Celsius converter, the applet included a text box, a label, and a button, but it also needed something more. Whereas the Celsius converter takes input from the user and processes it to produce a directly related output, I wanted my applet to generate some output of its own, and then respond to the user's response to the initial output.

At this point I ask: Am I alone. The answer is definitely not, because people have been doing what I am doing since computers were invented. But am I in a minority of Java users? I guess if I think of the majority of forms on the web, they certainly kick off with mainly empty test boxes, and then they respond to what is written in the text boxes, initially with the application of a business rules layer, and then perhaps by writing to a database or generating a message for someone.

My applet is education based. Rude people call it drill and practice, and perhaps in this first Java version it is. I have seen similar functionality out there, but I don't know exactly how they store data on the fly. Perhaps they don't. Perhaps everything is dredged from or written to a database. However other people do it, I could not see from the lessons read so far, how to do it myself.

In VB, a form is an object, and just as objects in Java have fields to store data (or record state), so forms in VB can have data hanging off them, both visibly, in text boxes and labels, and invisibly in variables defined at the form level. So I was looking to define variables at the JFrame level, but NetBeans wouldn't have a bar of it.

After much soul searching and fruitless forum posting, I decided to create my own class, with all the fields I desired, and then put an instance of the class on the form. Everything seemed to work quite well. After creating and compiling the class, I was even able to drag it on to the JFrame. But because the lessons on packages had been so jolly confusing (even the name is confusing - I thought I needn't read those lessons properly until distribution time), I put my custom class in the wrong package and nothing worked.

The correct procedure is to put both the JFrame and the custom class into a custom package. A fudge which worked for me first time was to ignore all the warnings and put them both in the default package. What doesn't work is putting one in a custom package and the other in the default package.

Saturday, January 3, 2009

NetBeans IDE Basics

This lesson talks you through NetBeans IDE application interface. This is worth a read. My first impression, having forked out several hundred dollars for VB5 and the same again for later editions, was to be amazed at the sophistication of the application. I was quite excited about the prospect of using it.

The next lesson, Creating the Celsius Converter GUI, takes you step by step through the process of adding components to the JFrame (or form, as I still like to think of it). It's not rocket science, but it's nicely explained, and from my perspective as an ex-VB user, I was pleased to see the instructions pretty much as I expected them to be.

This is followed by Adjusting the Celsius Converter GUI, which fine tunes the components. Again there is nothing too frightening here, but I couldn't help concurring with the lesson comment: "...you might be surprised at the amount of code that has been generated ...". The word bloat came into my mind. I started to worry a little bit. I like code to be elegant and concise.

I was also a little concerned at being locked out of the generated code. Perhaps I am being greedy. I know VB locks you out of a lot of behind the scenes stuff. But every automated process has quirks, and sometimes it is nice to un-automate. Just for fun I opened the form source file with a text editor. This was disappointing. The were no line breaks. It looked difficult to edit.

Carrying on with the lesson, Adding the Application Logic talks you through adding code to the button, as well as a little more fine tuning. You are then invited to run the application, and if you are lucky it works.