Lab 1: javac, java, Git

If you do not yet have an account, get one using this this link.

A. Java Compilation & Development

Java 1.8 is currently installed on the instructional machines (the Ubuntu ones, anyway). You may need to install it on your personal computer. You can do that by downloading the Java 1.8 JDK from Oracle. Downloading the JDK should also provide javac, a Java compiler. If you already have a Java 1.7 installation, it will do for now.

Java and Compilation

Java is sometimes called a "compiled language", and Python an "interpreted language"; neither of these terms, however, makes any sense. What is true is that in most Java implementatons, programs are compiled (translated into a form that is easily executed) in a separate, user-visible step from being executed, while most Python implementations give users the impression that the actual programs that they write are executed directly. The Java implementations we use compile Java source code (what is written by the programmer) into Java class files containing virtual byte code, which then may be executed by a separate program.

Let's see an example. Here is the "Hello World" program in Java. Don't worry about understanding it right now. We'll deconstruct it later in this lab.

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

Here is what the corresponding Java compiled code (called bytecode) looks like. The virtual machine can interpret this to run the program.

Java bytecode

Why Compilation?

At this point, you may be wondering why Java is (usually) compiled. Compilers are quite helpful for several reasons:

  1. They can check for errors prior to runtime (program execution). The Java compiler will catch and report errors like:

    • type errors, which can be produced by giving functions the wrong objects as parameters (like a String instead of an int)
    • syntax errors, which can be caused by forgetting syntactical elements like parentheses or braces

    Catching these and many other types of errors prior to runtime help catch many of the possible bugs caused by programmer error and make Java programs more stable before they are run.

  2. Compilers can help speed up programs. Programs run by interpreters can be slow because interpreters must parse text that is understandable to humans and translate it into an executable form. Furthermore, for various engineering reasons, this executable form is generally not actual machine code (directly executable by the hardware), but some other intermediate form that another program (the interpreter) then executes. A compiler does this translation work once and saves the instructions to a file variously called a binary, object file, or (in the case of Java) a class file.

There are many other reasons some languages have compilers, some of which you will learn by taking CS 61C. But for now, you will just need to know how to compile and run your Java program.

Compiling Java Programs

There are many different Java compilers, but we'll be using javac for command line in this class. As mentioned above, javac is included in Oracle's Java Development Kit (JDK), so you can set it up on your own computer if you'd like.

To compile a Java file called File.java, type the following command into your terminal:

$ javac File.java

You can also add some helpful options, which are called flags to the compile command. Full documentation is available here.

$ javac -g File.java

The "-g" flag is one of the most helpful flags because it will generate debugging information, including local variables. This is good for testing programs. We encourage you to use this flag when testing your code during the development process.

Running Java Programs

Compiling your program using the command above should give you .class files. Opening the .class files will show you something like the bytecode in the image at the very beginning of this lab.

Once you have your File.class file, you can run your Java program with this command in your terminal:

$ java File

Note that you do not type File.class. That is a common mistake that will cause an error message like this:

Error: Could not find or load main class

Running Hello World

Create a new text file called HelloWorld.java and type in the HelloWorld program above. Then compile and run it using the following commands:

$ javac HelloWorld.java
$ java HelloWorld

You should see Hello world! printed out in your terminal.

Java Documentation

The Java language has extensive API (Application Programming Interface) documentation, which is often very helpful when using classes and methods in packages created by other programmers. Don't worry about understanding how to use or read this documentation yet. Just know that it is available and will come in very handy in the future.

A Note on IDEs

An IDE (integrated development environment) is a program that can be used to write and run programs without using command line. They provide useful features like debugging and are popular tools for programmers to write and test their code. There exist many popular IDEs for Java such as

You may use these if you would like, and we will look at IntelliJ in a later lab.
For this course, however, you will not actually need anything other than a text editor (personally, I prefer Emacs).
It is important, also, that you know how to compile and run Java programs on command line.

B. Writing Java Programs

Java is Object-Oriented

Java is an object-oriented programming language. Those of you who took 61A/AS may recognize that term as having been applied to Python/Scheme. Java takes OOP a step further. In Java, all programs have class definitions. Methods and variables exist within classes.

Format of a Java Program

Every Java file contains a public class, interface, or enum. For now, let's just discuss class definitions. A definition provides the name of the class as well as its variables and methods.

Here is a deconstruction of the aforementioned "Hello World" program:

HelloWorld

A Java program consists of a collection of one of more of these Java files containing classes, interfaces, or enums. At least one of the classes in a Java program must contain a method called main. This main method is called in order to run the program.

This is why running the HelloWorld program prints out Hello world!. The main method in the HelloWorld class is being run when you type java HelloWorld into the terminal.

Comments in Java

There are two formats for comments in a Java program:

  1. Single-line comments start with two consecutive slash characters and continues to the end of the line

    // This is one kind of comment

In general, we use these only for temporary comments, or to add explanatory text in an example.

  1. Multi-line comments start with /* and end with */

    /* This is a
       multi-line
       comment */

Some commenting styles add single asterisks at the start of each line in the comment after the first, to improve readability.

/* This is a
 * multi-line
 * comment */
  1. Finally, a subclass of the multiline comments called documentation comments or javadoc comments are intended to provide specifications of methods (functions), classes, and instance variables. For example.

    / Returns the current size of the list. */ public int size() { ... }

Example: Leap-Year Program

For our first Java program, we'll be writing a program that prints out whether or not a year is a leap year or not. A leap year is either:

  1. divisible by 400 or
  2. divisible by 4 and not by 100.

For example, 2000 and 2004 are leap years. 1900, 2003, and 2100 are not leap years.

Your Java file should be called LeapYear.java. These lines should go into the main method of the LeapYear class. Remember that your class name should match the name of your file. Your program should include the line:

int year = 2000;

If you're not sure where to start, you can copy and paste lines from this file.

Some Java Vocabulary in Leap Year

Testing Leap Year

When you've arranged the lines properly and compiled successfully, running the program should print out the following line:

2000 is a leap year.

You can test your program with other year values by changing the line

int year = 2000;

to other numbers. Once your program is correct, save it as LeapYear.java. You'll be submitting it below.

C. Using Git

Note: In this class, you will be using a tool called Git to submit your work.You need not use your instructional account for this; Git runs on Unix, Windows, and MacOS installations.
If you'd like to learn more about using your instructional account, please read this guide.

Git is a very useful tool, but a tricky one. We've written a guide that you'll be using through the semester. Read through sections A, B, and C of our Git guide, and then work through the exercise in section D.

D. Using Your Central Git Repository

STOP! Did your read the Git guide? If you didn't, don't go ahead. Read the guide first! You'll need it for the steps that follow this point.

While it is technically possible to copy and paste most of what is below without understanding what is going on, it is always wise to understand your tools.

Setting Up Your Git Repository

For this lab, work on the instructional machines (if using a laptop, log in remotely to one of the servers, such as derby.cs.berkeley.edu).

On the instructional machines, the command

  $ init-git-repo

invokes a script that will create a clone of a central repository for your work (one that we and the autograder share). To set up your repository on other machines (your personal laptop, for example), you'll need to execute the same steps the script does, which are described in the Git guide, and printed by the script.

Working on the Skeleton

  1. You must now fetch from the shared remote in order to get the starter code for lab1. You will also do this when new projects and assignments are released. We assume that you are in the repo directory (or whatever you've named it on your home machine).
    $ git fetch shared
    $ git merge shared/lab1 -m "Start Lab 1"
    $ git push

This copies our skeleton code for lab1 into your local repository (in a subdirectory called lab1). It then transfers this branch to your central repository. Now that you've done this, you can fetch this assignment from any other local repository (your laptop, for example) that you've cloned from your central repository.

  1. Move LeapYear.java into the lab1 directory.
  2. Stage and commit LeapYear.java.

    $ git add lab1/LeapYear.java
    $ git commit -a -m "Completed LeapYear.java"
  3. Push these changes to the master branch on the origin central repository.

    $ git push

Get into the habit of saving your files and doing the git commit step often. It can save your derrière when you mess things up, since it allows you to back out of changes and to see what you have changed recently. Use git push whenever you intend to move to another computer to work, so that your edits will be available at the new location. For example, if you've been working on the instructional machines and move to your home computer (where you have cloned your central repository), then you start a local lab1 branch on your home machine (if it's not there yet) with

    $ git pull --rebase

Complete Lab 1

Now that you have the skeleton, you should see a file in the lab1 directory called Year.java.

You should fill it out, using your code in LeapYear.java. This time, however, you'll notice that year is a parameter for the isLeapYear method rather than a local variable within a method.

After you have filled out that file, commit your work as you did before. Since you haven't added any new files since your last commit, you can just use

     $ git commit -a -m "Filled in Year.java"

Running Unit Tests & Submitting Homework

  1. At some points in your development, you may want to run the autograder. For this lab, we have given you an explicit program to show how this sort of thing works. The file AGTestYear.java contains a number of unit tests, a term that refers to simple tests of individual components (units) of a program. In this case, there is one component in question: your isLeapYear program.

    Compile the autograder with

       $ javac -g AGTestYear.java

    You can run it with

       $ java AGTestYear
  2. If your program was correct, then you'll get an encouraging message like

       Time: 0.014
       Ran 4 tests. All passed.   

    Otherwise, you'll get messages such as

       There were 2 failures:
    
       1) test400(AGTestYear)
          should be leap year
          at AGTestYear.test400:12 (AGTestYear.java)
    
       2) ...

    If you didn't get an error message, try deliberately breaking your program by inserting a bug and try testing it again (remember to compile it before trying to test it!). Undo the damage before submitting.

    Note 1: In later assignments, we may hide the autograder from you, and send you email about the results. We'll explain how that works in a later assignment.

    Note 2: This autograder may not be running the full number of tests that will be used to grade your assignment. (This is especially true for the projects.) It should be used as a sanity check, not as a thorough test.

  3. If you are ready to submit your homework, first make sure that all your work is committed. The command

     $ git status

    Should tell you that your working directory is clean.

  4. Now tag your latest commit as a submission. Tags in Git are symbolic names given to specific commits (snapshots) of a directory.

    • Create a tag for this commit.

      $ git tag lab1-0

      Tag names have the form of the assignment name, followed by a sequence number.

    • Now push your commits and tags to your central repository so that we can see them, too.

      $ git push
      $ git push --tags
    • You won't receive any indication of your submission this time, so do not worry about that.
    • You can continue updating your work and submitting newer versions by following the same procedures (again, always commit before you tag). Just increase the sequence number to keep the submissions distinct: lab1-1, lab1-2, etc. The actual numbers don't matter; the largest is your official latest submission at any time.

Recap

  1. You can use javac and java to compile and run your code.
  2. Java is an object-oriented language. Every Java file must contain either a class, interface, or enumeration.
  3. When running a Java program, the main method runs. This main method can call other methods/classes in the program.
  4. Git is a version control system that tracks the history of a set of files in the form of commits.
  5. Commit often and use informative commit messages.
  6. Fetch from the shared remote repository to get or update starter code for assignments.
  7. Tag a commit and push it and your tags to submit assignments.