MCS-378 Lab 4: Communication Middleware, Fall 2015

Due: December 15, 2015

Introduction

In this lab, you (and, optionally, a partner) will complete development of a client/server version of the "15 Puzzle" (sliding tile) application using JMS (Java Message Service) to transmit JSON (JavaScript Object Notation) messages from the clients through a queue to the server and from the server through a topic to the clients. I am providing the stand-alone (non-JMS) version of the program as well as the server side of the JMS version and a template of the client side. You are to complete the client side.

My instructions assume you will be doing this on the computer you have been issued, running the Ubuntu distribution of Linux. You can actually use any system that has a current version of Java EE 7; only the installation instructions are Ubuntu-specific.

Time-consuming but mindless preparation

To get Java EE 7 installed requires quite a few steps. Hopefully I've remembered to list them all here:

  1. Install Oracle Java 7 as described on the linked web page and also set the environment variables as described on that same page. (Java 8 ought to work, too, though I haven't tried it.)

  2. Install the maven project management tool:

    sudo apt-get install maven
    
  3. Install some libraries that are needed by the updatetool for glassfish, the Java EE server:

    sudo apt-get install libjpeg62:i386 libstdc++6:i386 libgtk2.0-0:i386 libpangoxft-1.0-0:i386 libpangox-1.0-0:i386 libxxf86vm1:i386 libsm6:i386 libidn11:i386 unity-gtk2-module:i386 libcanberra-gtk-module:i386 gtk2-engines-murrine:i386
    

    I'm pretty sure that if a fix to bug #1262022 were available, overlay-scrollbar-gtk2:i386 should also be included, but even without it, updatetool seems to work adequately, just producing some extra error messages.

  4. Download the Java EE 7 SDK (not the Java EE 7 Web Profile SDK) from Oracle's download page and then unzip it to create the glassfish4 directory. (My following instructions assume this is directly within your home directory.)

  5. Run the updatetool using the following command in a shell:

    ~/glassfish4/bin/updatetool
    

    The first time you run this, it will download some software needed by the updatetool itself, after which it will require you to run it a second time using the same command. This second time should pop up the window for a graphical user interface, even though some error messages come out in the terminal window.

    It is particularly important that you download the update for the Java EE 7 Tutorial because there were some changes in the JMS example software we'll be using. Within the updatetool window, select Available Updates and then clock Install.

  6. If you like working within an integrated development environment (IDE), you might consider installing the NetBeans IDE as described in the tutorial, because it is the IDE that the tutorial describes. I haven't tried it out myself. Other IDEs such as Eclipse might also be options. I just edited the Java source files using a normal text editor (emacs) and ran the Maven build process from within a shell.

  7. After installation, as well as after any reboot of your system, you need to start up the GlassFish server using this command in a shell:

    ~/glassfish4/bin/asadmin start-domain
    
  8. Create the resources for the tutorial's simple JMS examples. We'll be using those examples as a starting point, and for simplicity our puzzle program will use the same resources. In particular, our client and server will communicate through a queue called jms/MyQueue and a topic called jms/MyTopic. The directions for creating these resources are in the tutorial; a more full version of the commands follows:

    cd ~/glassfish4/docs/javaee-tutorial/examples/jms/simple/producer
    ~/glassfish4/bin/asadmin add-resources src/main/setup/glassfish-resources.xml 
    
  9. Build the simple JMS examples as described in the tutorial. Assuming you are doing this in the shell rather than with NetBeans or another IDE, the full version of the commands would be as follows:

    cd ~/glassfish4/docs/javaee-tutorial/examples/jms/simple
    mvn install
    
  10. Check that you can use the example programs, particularly the producer and asynchronous consumer, to send and receive messages using the queue and topic as described in the tutorial. Note that these programs will be slow in starting up and will produce some extra informational messages at the start. For an example of the full version of the commands, here are the ones for running the producer:

    cd ~/glassfish4/docs/javaee-tutorial/examples/jms/simple/producer
    ~/glassfish4/glassfish/bin/appclient -client target/producer.jar queue 3
    

A possibly useful extension to a tutorial example program

Because I am providing a working server for the puzzle program, it is entirely possible that you could just test your client using this. If you want to see the messages, you can also use one of the consumer example programs from the tutorial. However, you might find it interesting to be able to manually send messages as well during the testing and debugging process. I know I found that helpful while working on the server side.

The example producer program has the limitation that it sends a specific format of message that is hardwired into it. Your program won't be interested in receiving messages saying "This is message 1 from the producer". Therefore, I have made a slight variant of the tutorial's producer, called flexproducer, which reads from the standard input (normally your keyboard) and sends each line of input as a message.

You can download this program as flexproducer.zip, unzip it, and then build and run it analogously to the tutorial's examples:

cd flexproducer
mvn package
~/glassfish4/glassfish/bin/appclient -client target/flexproducer-1.0.0.jar topic
Something to send.
More to send.
(control-D when done)

The puzzle application

You can download the puzzle application as puzzle.zip, unzip it, and build it using

cd puzzle
mvn package

After building the application in its supplied form you can run any of the following three commands:

~/glassfish4/glassfish/bin/appclient -client target/puzzle-1.1.0.jar
~/glassfish4/glassfish/bin/appclient -client target/puzzle-1.1.0.jar server
~/glassfish4/glassfish/bin/appclient -client target/puzzle-1.1.0.jar client

These run the stand-alone version of the program, the server, and the client. However, the client will report an exception because the ProxyModel.java source file is just a template waiting for you to fill it in.

We spent class time discussing the structure and function of this program. Here is the diagram of the structure:

UML diagram of puzzle program

Suggested plan of work

Here is a suggested plan of work for what you need to do in ProxyModel.java:

  1. Delete the throwing of "not yet written" exceptions from setView and the ProxyModel constructor. Rebuild the puzzle package using the mvn package command. At this point, you ought to be able to start up a puzzle client as shown above. It will come up with all the tiles blank. If you push on the Initialize button or any of the blank tile buttons, you will get a "not yet written" exception. Exit from the client.

  2. In the body of initializeTiles, replace the throwing of a "not yet written" exception with a line of code that sends to the commands Destination the text

        ["init"]
    

    including the brackets and double quote marks. This is a one-element JSON array containing the string "init". You can find examples of sending text to a JMS Destination in both the puzzle's ProxyView class (the server side) and the Java EE tutorial's producer example (as well as my flexproducer variant). In order to make this possible, you will also need to add one or more instance variables to the ProxyModel class and put some code in the constructor to initialize these instance variables. Rebuild the puzzle package again and re-run it. Again it should come up with all tiles blank. But now if you press the Initialize button, you won't get an exception. In another terminal window, run the Java EE tutorial's asynchconsumer program with the queue destination. You should see the ["init"] message that the client program should have queued up. If you click the button again, you should see the message again. If your client passes these tests, you can quit from asynchconsumer and rerun it with the topic command line argument instead of queue. Now in a third terminal window, run the puzzle server. Although the client tiles will remain blank, you should see using asynchconsumer that the server is retransmitting the initial board configuration each time you click on the Initialize button. Exit from the client after testing it. If these tests aren't passing, work to get them to pass before moving on.

  3. Modify the pushTile method in the ProxyModel class analogously to initializeTiles. The message it sends should have this form

        ["push",0,3]
    

    for a push in the upper right corner (row 0, column 3). This is a three-element JSON array. Rebuild and run the puzzle client. You still should have blank tiles, but now if you push them you should be able to see in the asynchconsumer's output that the server is actually sliding the tiles appropriately. For example, pushing the upper right tile results in the first row now being ["1","2","3",""] and the last row being ["13","14","15","12"]. If this isn't working, you can get more insight into what is going wrong by killing off the puzzle server and the asynchconsumer and restarting the asynchconsumer with queue. That will show you whether your puzzle client is sending the correct command. As usual, get this portion of the work debugged before moving on.

  4. Fill in the setView method with code that does two things: (a) records the View into an instance variable for later use, (b) transmits a ["send"] command to the commands destination analogously to the ["init"] command. If you rebuild and re-execute the client, you should be able to see that when it first starts up, it uses the ["send"] command to prompt the server to transmit its state.

  5. Change the ProxyModel constructor to set this ProxyModel to be the MessageListener for a consumer on the states Destination. You can find an example of this in the puzzle's ProxyView class (the server) as well as in the tutorial's asynchconsumer. If you re-build and re-execute the client, you should find that now whenever the sever (or flexproducer) sends a puzzle state to the topic, the "not yet written" exception is thrown by the onMessage method.

  6. Fill in the onMessage method with code to translate the received state into an array of arrays of Strings and invoke the View's displayState method (assuming a non-null View has been set). At this point, the client should be fully functional.

What you should turn in

You should upload to moodle a completed version of ProxyModel.java. If you want to do something that extends beyond this, I'd be happy to talk it over with you. However, I'd be satisfied with just a working version of this one class.


Instructor: Max Hailperin