CPSC 211
Introduction to Unix and Eclipse

Before the Lab

Objectives

This lab will serve as a refresher for Unix, Java, and Eclipse. You will be (re-)introduced to the Unix command line and Eclipse by compiling and running a small application both from the command line and in Eclipse. In this lab, you will:

  • (re)acquaint yourself with the Unix system's command line interface, and
  • review the process of using Eclipse to run a program.

For those of you who have never used Eclipse, here is a link to a short Eclipse tutorial. It would be a good idea to look at this tutorial even if you have used Eclipse before, since it also tells you how to set it up to run Java.

If you know C++, but have never used Java, we recommend that you take a look at the following page:

http://www.ugrad.cs.ubc.ca/~cs219/CourseNotes/Java/intro.html
The first few sections (up to and including the section on Inheritance) discuss the topics that are covered in CPSC 111 at UBC.

The first section of this lab introduces you to some basic UNIX commands. If you would like to learn a few more really useful Unix commands, we recommend that you consult

http://www.ugrad.cs.ubc.ca/~cs219/CourseNotes/Unix/intro.html
(with thanks to Karen Brennan, Daniel Ferstay, and Christina Wong for their work on these notes).

Introduction to Unix

Desktop

The UNIX desktop environment you see on your screen is managed by a window manager program called fvwm. There are many different window managers and desktop environments available, but fvwm is the default choice for the undergrad labs. The environment consists of open windows and icons and the button bar located at the bottom of the screen. The button bar contains:

  • xbiff - notifies you of mail by changing the picture
  • xload - graphically displays the system load
  • xclock - a clock
  • WWW - launches Netscape
  • xlock - password protected screen locking utility TIP: xlock
  • Mail - email application
  • Emacs - text editor TIP: text editors
  • Shell - brings up a new Xterm window with a UNIX shell command prompt inside TIP: shell
  • File_Manager - file management application
  • Text_Editor - simple text editor TIP: text editors
  • ChezUBCFront - graphical front end for Scheme interpreter
  • Group 0 - Switches to virtual desktop 0
  • Group 1 - Switches to virtual desktop 1
  • Group 2 - Switches to virtual desktop 2
  • Group 3 - Switches to virtual desktop 3
  • Exit - Pop up exit confirmation menu

Xterm

The Xterm is a window where you can enter UNIX commands. You will use commands to manage files, run programs, and make programs. An Xterm window contains a UNIX shell command prompt that has the name of the computer server you are connected to followed by the command number surrounded by angle brackets.

  • Click on the Terminal button in the button bar to bring up a new Xterm window
     
  • The UNIX shell should start in your home directory. You can find out what the present working directory is by entering the command:
    pwd
    You should be in /[a-z]/userid where [a-z] represents the first character of your user id.
     
  • If you are not in your home directory you can change directories by entering the command
    cd ~
  • Make a directory for this course in your home directory by entering:
    mkdir ~/cs211
  • Create the directory ~/cs211/labs in the same way. This directory will store all of your labs for this course.
     
  • Change to your labs directory by entering the command

    cd ~/cs211/labs

  • Now make a directory in the ~/cs211/labs directory called intro and change your current directory to the new directory by entering these commands:
    mkdir intro
    cd intro
  • Confirm you are in the right directory by entering:

    pwd

    You should be in /ugradnumber/userid/cs211/labs/intro

UNIXhelp

The following site provides a helpful introduction to UNIX: http://unixhelp.ed.ac.uk/index.html

You are not expected to read through the entire site but keep it in mind. During this lab you are expected to read through the following sections of the site to learn how to copy, delete and move files and directories:

Note that at the end of the lab, your TA will ask you to do one or more of the following tasks:

  • change directory
  • create a directory
  • copy a file or directory
  • move a file or directory
  • delete a file or directory

Please make sure that you are comfortable performing these tasks before moving on.

Compiling and Running a Java Program on a UNIX system

Unzipping and compiling .java source files:
  • Change directory so that ~cs211/labs/intro is your current working directory (use the cd command, see above)
     
  • Download paddleballfiles.zip and save it to your ~cs211/labs/intro directory. You can unzip all the files using the following command:

    unzip paddleballfiles.zip

  • There should now be a src directory in your current directory containing several java source files in the package ca.ubc.cs.cpsc211.paddleball. You can list them by entering the following command (use the TAB key to auto-complete the directory names):

    ls src/ca/ubc/cs/cpsc211/paddleball/

    The directory should contain the files:

    Ball.java
    Collidable.java
    GamePiece.java
    Paddle.java
    PaddleBallApp.java
    PaddleBallFrame.java
    PaddleBallPanel.java
    Trajectory.java

  • Use the java compiler to compile all of these files by entering the following command (again using TAB to auto-complete directory names):

    javac src/ca/ubc/cs/cpsc211/paddleball/*.java

    This command asks the java compiler to compile all .java files in the provided directory. If you list the contents of the directory again, you will see that a number of .class files have been generated by the compiler.

  • You can now run the sample program, a simple paddleball game, by entering the command

    java -cp src ca.ubc.cs.cpsc211.paddleball.PaddleBallApp

    The -cp src option tells java to find the compiled class files in the src directory, and ca.ubc.cs.cpsc211.paddleball.PaddleBallApp is the fully-qualified name of the class to run (by invoking its main() method).
  • To start a new game, click 'Play', then 'Go'. The up and down arrow keys are the only ones that do anything. You may use the 'Paddle Color' menu to change the color of the paddle. 'Play --> Exit' is obvious.
Running a .jar file:
  • Download paddleball.jar and save it to your ~cs211/labs/intro directory
     
  • With a .jar file, there is no need to unzip or compile any .java source. The .jar file already contains the compiled code, so all you have to do to run the program is ask the java runtime environment to execute the program in the provided jar file; that is, from your ~cs211/labs/intro directory, just enter the command

    java -jar paddleball.jar


Introduction to Eclipse

Now we'll use the Eclipse Integrated Development Environment (IDE) to compile and run the paddle ball application. To begin, you will need to set up a new project and import  the source code that makes up Paddleball into it.

  • Create the directory ~/cs211/workspace. The workspace is where Eclipse will store the projects and code on which you will work in 211.
     
  • In Eclipse, create a new Java project called PaddleBall. (You do not need to change any of the default settings in the wizard.)
     
  • Import the source files into Eclipse by selecting the PaddleBall project in the PackageExplorer, bringing up the right context menu and selecting "Import".  Choose "General->Archive File" and provide the path to the paddleball.zip archive provided with this lab.
     
  • You should see a package named "ca.ubc.cs.cpsc211.paddleball" containing 8 classes in your PaddleBall project.
     
  • You now have a simple game of Paddle Ball. The main class is called PaddleBallApp. To run it, right-click on that class and select Run As > Java Application. In Eclipse, there is again no need to perform any code compilation yourself, because the development environment takes care of that for you by building all of the project's code automatically.

A note on package naming... As much as possible in this course, we will use full package names  for code that start with "ca.ubc.cs.cpsc211".  This is a good habit to get into because when you develop software professionally you have to make sure that the naming is correct.  Java relies on unique hierarchical naming to help ensure a Java system never has two packages of the same name, which could potentially lead to problems in resolving which code should be used for a given class.


Saving your Eclipse Code

Most programmers store their code in a source code repository that maintains different versions of files on which they have worked and that helps them share code with other programmers. You will learn more about source code repositories in CPSC 310. For now, we recommend that after each lab or each significant work session on your code, you snapshot the code from Eclipse into a safe place in your directory (say ~/cs211-archive). Creating a snapshot is easy:

  • Select the project containing the code you want to save away.
  • Bring up the right-context menu and select "Export".  Select "General->Archive File" and specify the snapshot name, say ~/cs211-archive/lab1-20080916, to indicate code from lab 1 on September 16, 2008.

It is possible that your Eclipse workspace can be corrupted. In most cases, we will be able to help you recover your workspace. As your directories are backed up only periodically, we strongly recommend the snapshot approach as well.


Running JUnit Tests in Eclipse

JUnit is a framework that makes it easy to create and run tests for a piece of software ( a unit like a class ).   Instead of writing a test driver, with JUnit we create a test class (as a subclass of TestCase that is defined in the JUnit library) and write tests as methods of this class. Each test method's name starts with test (e.g., testMyMethod()) and performs one or more tests for a method of the class that is being tested.  Instead of using print statements for output, JUnit tests call various assert functions to compare expected and actual results.  One more fact you need to know about JUnit tests is that there is a setUp method that can be defined in a JUnit test class that gets called automatically before each test method is called in the class.

This section will NOT show you how to define JUnit test. We'll do that in a later lab. In this lab you will just learn how to use Eclipse to run JUnit tests that we have prepared for you.

As an example we have defined two simple classes: 1) CreditCard that holds the information for a credit card and 2) a class CreditCardTest that contains tests for the CreditCard class.  To download the code for these classes and create a project for them you should follow the next steps:

  • Download the creditCard.zip file and store it in your home directory ~/.
  • Create a new Java project (you may name it CreditCard).
  • In the Package Explorer select the CreditCard project and right-click on it
  • Select "Import". Expand the General category and select "Archive File". Press Next. Select the creditCard.zip archive file. Click "Finish".
  • When prompted, allow the imported files to overwrite your .project and .classpath files. (This will ensure JUnit is enabled for your project.)

You should now have two packages in your project: ca.ubc.cs.cpsc211.ccard and ca.ubc.cs.cpsc211.ccard.test. The first package contains the CreditCard class and the other has the CreditCardTest class. (It is common practice to separate the JUnit tests into a separate package that ends in "test".)

Running CreditCardTest

In Eclipse, JUnit test classes do not need a main() method to run because the test classes are run in a special JUnit mode. When running in JUnit mode the output/results of the test run are reported via the JUnit view which opens automatically when a JUnit Test is running.
 

Select CreditCardTest.java in Package Explorer and right-click on it. Then select Run As...-> JUnit Test. Remember that because CreditCardTest has no main() it cannot be run as a Java Application. The JUnit view will open, sharing space with Package Explorer.

In the JUnit view there are two panes: a top pane and a bottom pane. The top pane displays a list of the tests that were run. The Failure Trace pane (at the bottom of the JUnit window) displays information about a particular test case  that is selected in the first pane. If the test that is selected passed, then the Failure Trace pane does not show any information.

When you run CreditCardTest.java, you can notice a few things immediately in the JUnit view. The bar at the top of the view is red. A red colour indicates that tests have failed. When you are running JUnit tests, the goal is typically to keep the bar in the JUnit view green, which indicates all tests have passed. The JUnit view you are looking at now should show four passing tests, indicated with green checkmarks, and three failed tests, indicated with blue "x"s.

Typically, your goal in using tests is to solve problems with the software. So, we will focus on the the failures. Double click on the first failure (should be testGetCreditLimit()).  The bottom pane will show a trace for this failure and the method testGetCreditLimit will be highlighted in the editor.  A number of lines in the Failure Trace for testGetCreditLimit refer to the JUnit methods and you should ignore them. Two lines in that list are important: the first line that explains the failure and the 6th line( at ca.ubc.cs.cs211.....)  that shows the line in the code that produced the failure. The rest of the lines in the failure trace show method calls to the JUnit and Java libraries that were executed before and after the failed line in the CreditCardTest was executed.  You can safely ignore these lines and focus on the 6th line that points to the failed statement in the code of our  test. If you double-click on the 6th line, the corresponding  line in the code is highlighted.  From the message on the first line, we can see that the statement  assertEquals(card2.getCreditLimit(), 1000, 0); failed because card2.getCreditLimit() is 0 not 1000.  We now have to determine why this assertion is failing. Here are some steps we can take:

  1. First, we should check what the getCreditLimit method does. A simple way to do this is to put your cursor on "getCreditLimit" in "card2.getCreditLimit()" of the testGetCreditLimit method. Now hit "F3". This takes you to where the getCreditLimit method is defined. We can see from the definition that the method simply returns a value of a field in the CreditCard object.
  2. Now the question is where is this field defined. Put your cursor on "creditLimit" in the getCreditLimit class and press "Ctrl-Shift-G" (or from the right context menu, select References->Workspace). This runs a search for all of the places where creditLimit is defined or used. The search view shows the results of running the search. You can double click on any search result to see that location in the code.
  3. The search view should show three search results. Double clicking on the first result ("addCharge(double)") shows code that just uses the value of creditLimit.
  4. Double clicking on the second result ("CreditCard(String,double)") shows a location in the code where creditLimit is assigned a value. This location shows that the creditLimit cannot be less than 0.
  5. So why are we getting a failure on asserting that card2's creditLimit is 1000? Double clicking on the failure again in the Junit pane takes us back to where the test failed. We want to know what card2's creditLimit was set to when it was constructed, since the constructor takes the creditLimit as a parameter.
  6. If we put the cursor on card2 in the line assertEquals(card2.getCreditLimit(), 1000, 0) and search for references (remember, Ctrl-Shift-G or right-click and select "References->workspace"), we find setUp() as the first search hit.
  7. Double-clicking the setUp() search result we are shown the code for the setUp() method and we can see that -200 was passed in the constructor for card2. Since the constructor takes any negative value passed as a parameter for the creditLimit and sets the creditLimit to zero, we can see that the assertion can never be true.
  8. In this case, the fault lies with the test case. If we change the parameter in the assertion in testGetCreditLimit to 0 for card2 and rerun the test, what happens?

Now you'll see only two failures in the Junit pane. Double click on the first failure that now appears in the list and find the line that failed.   What could be wrong here? An initial point to start from is to consider that getBalance() works correctly. Since setup() would have run just before this test, the balance must have started at zero, getBalance() would return 0 and the value of b-200 being -200 would be correct. If so, then there must be a fault in the addPayment() method.   Take a close look at the code for the addPayment method. (Put your cursor on addPayment and hit F3.) Is the if statement correct? We want to process the payment if the payment is positive and ignore it if it is negative.  Correct the condition and run the test again.

Now you'll see only one failure. Use the same procedure to find out what the error is. Correct the error and run the test again. You'll discover that there is still another failure in the same method. You also need to figure out this error, correct it and run the test once more. In this case it should produce no failures.

Sometime before the end of the lab your TA will come and check your progress. It will help if you keep track of what you did to correct the errors and show the TA the final test.


Helpful Tips

xlock - Always use xlock to lock your screen whenever you have to leave your terminal unattended. Your screen will be locked until you enter your password. However after 15 minutes, a public logout button will appear and someone can log you out and take over your terminal.

text editors - You are free to use whatever text editor you like when you program, but in the future you may want to take advantage of some of the advanced features of emacs. Emacs can be a little bit tricky, but can be of great help later on.

UNIX shell - There are a few shorthand abbreviations that you can use in the shell to make navigation easier:

  • a single period, ., can be used in place of the current directory's full pathname
  • two periods, .., can be used in place of the parent of the current directory's full pathname
  • the tilde, ~, by itself can be used in place of your home directory. In front of a username it can represent the home directory of that user. Be sure you know the difference between ~cs211 and ~/cs211; the first is the cs211 course account and the second is your cs211 directory!
  • the asterisk, *, is a wildcard that can be used to represent any number of characters, and can be used at the beginning, end or middle of a string when specifying files

ampersand - The ampersand (&)indicates that you wish the program to run in the background. Space between the program name and the ampersand is OK too. You will notice that if you run the program without the ampersand, the prompt will not return until the program exits. By running the program in the background, the prompt comes back right away and you can continue to use the command prompt. You will usually run programs that make their own windows in the background.

more - A very useful utility for viewing text files one screen at a time. A similar program called less is more powerful (In UNIX less is more than more). View the man page for less if you want more information.

man - The online reference manual viewer. To find out about a program, you can usually learn something from its man page by entering the command:

man program

where program is the program you want to learn more about. man pages can be very long and complicated; don't worry if you don't understand everything. Press q to quit the man viewer.