If you see the message "6.170 setup complete", you are done. You must logout and login again for the changes to take effect.add 6.170
student-setup.pl
If you see an error message, contact the course staff for assistance. (The best way to get help is to visit an LA during office hours. Alternately, see the staff list for email information, or ask for help on the 6.170 zephyr instance.)
We do not recommend it, but you may choose to make the changes by hand rather than using the staff-supplied script. In that case, see the comments at the top of the student-setup.pl (/mit/6.170/arch/common/student-setup.pl) file, which describe in detail all the actions of the script.
To write code in Java, you start by writing a Java source file. Java source filenames usually have a ".java" extension. Source files are just text files, which you may create and edit with Emacs or your favorite text editor, or with an IDE (integrated development environment) such as Eclipse.
You must compile your source code before running it. The javac compiler is used to transform Java programs into bytecode form, contained in a class file. Class files are recognized by their .class extension. The bytecode in class files can be executed by the java interpreter.
Extensive on-line documentation for javac, java, and other tools in the JDK can be found through the Java documentation page at MIT.
A Java program consists of one or more packages, each of which defines a group of related abstractions. Each package consists of one or more classes. Each class is produced from a source file that implements the abstractions.
Using javac, one or more source files can be compiled into class files for execution by the interpreter. At least one of the resulting classes must define a method named main, which serves as the starting point for execution of the program. Once all of the source files have been compiled, the program can be run using java, the Java interpreter. Running the following line
will generate class files file1.class, file2.class, etc., for each specified source file. Type "man javac" at the Athena prompt for more information on javac options. You should almost always use the -g option, which will provide improved debugging output.javac [options] file1.java file2.java ...
Once you have compiled your source code into class files, you can execute it with the Java interpreter java. The command
java options classnamewill execute the class indicated by classname. This class must exist in your current CLASSPATH, or you will need to use the -classpath option to specify a different CLASSPATH. The class that you execute must also contain the "main" method discussed above. If you wish to run a class that is not in the default package, you must specify the complete class name; for instance, use
java ps1.Testto run the main method of the Test class in the ps1 package. For a complete description of all of java's options type java -help at the Athena prompt.
(load "/mit/6.170/etc/emacs/6170.el")This causes the following changes:
(setq make-6170-changes nil)to your .emacs file before loading the file. This will define all of the functions but make none of the customizations. Feel free to look at the 6170.el file and copy out the bits you find useful.
The javadoc170 program extends javadoc to recognize additional 6.170 tags, as well as all the tags accepted by the Sun Standard Doclet. These additional tags declare specification fields for classes and requires, modifies, and effects clauses for methods. Note that these tags must appear after all non-tag comments for classes and methods.
| Indicates that name is a abstract specification field of type T for the class, adding text as a comment if present | |
| Same as specfield, except that this also adds the property "derived" to the output information |
Derived fields can be viewed as functions on preexisting state; thus if a class had a specfield @specfield n : integer we could define a derived field
@derivedfield pos : boolean // pos = true iff n > 0
Derived fields are not allowed to hold any information that could not be already calculated from the already existing state in the object. Thus, you use specfields to introduce new state variables and derived fields to introduce functions on those state variables.
Derived fields are not strictly needed in specifications, but they may reduce complexity and redundancy.
| @requires X | Declares X to be a precondition for the method |
| @modifies Y | Declares that nothing besides Y will be modified by the method (as long as X holds when it is invoked) |
| @effects Z | Declares that Z will hold at exit from the method (as long as X holds when it is invoked) |
To use javadoc170 with javadoc, you use the same syntax as you would with the original javadoc tool, except that you invoke javadoc170 instead of javadoc. Thus, if you would normally generate specifications by typing
then to make use of javadoc170 you would type:athena% javadoc -d spec-directory -sourcepath /mit/$USER/6.170/ ps1 ps2 ps3
athena% javadoc170 -d spec-directory -classpath /mit/$USER/6.170/workspace/ps1/src:/mit/$USER/6.170/workspace/ps2/src:/mit/$USER/6.170/workspace/ps3/src:/mit/6.170/lib/junit.jar ps1 ps2 ps3 (where spec-directory is the directory you'd like to output to: for ex. /mit/$USER/6.170/workspace/ps6/doc)
After running javadoc170, you should check the output. You may find that you need to add line breaks (<br>) or paragraph breaks (<p>) for readability. Also, if you omit certain tags (such as @endspec), subsequent text may fail to appear in the output. Finally, since much of the text of javadoc comments is inserted in a HTML document, you must be careful with text that can be interpreted as HTML markup, such as the less-than (<) and greater-than (>) characters. For instance, if you write
then <x> and <y> will be interpreted as HTML tags in the output (and won't be displayed by a browser).@effects Adds <x> and <y>
We seem to have lost the source code, but the jar and the shell script that calls it are both available for you to download.
To send a nicely formatted compilation of your HTML documention to a printer, use the script: athena% /mit/6.170/bin/print_api.sh (Running this script without parameters will cause it output usage directions for you. An example is in the section below "Printing Javadocs")Report any weird behavior or complaints about javadoc170 to 6.170-tas@mit.edu.
You may want to subscribe to various zephyr instances pertaining to this class. These instances can be a useful resource, for instance as a supplement to visiting an LA during lab hours. The main instance is called 6.170. This zephyr instance allows you to get in touch with fellow classmates and any lab assistants that are on duty. (Lab assistants give priority to students who visit them in person during lab hours, which is a better way to interact with them in any event. However, they will attempt to monitor the instance and also provide help via that mechanism, time permitting.)
To subscribe, type:
zctl add message 6.170 \*
To write to the instance, type:
zwrite -i 6.170
zctl delete message 6.170 \*
To unsubscribe for the current login session only, substitute "unsub" for "delete" in the above line:
zctl unsub message 6.170 \*
For more information on zctl, type "man zctl" at the Athena prompt or check out the Inessential Zephyr document available on-line.
The 6.170 instance is intended strictly for questions and answers directly related to problem sets and Java. The TAs and LAs will generally subscribe to the 6.170 instance as long as the signal-to-noise ratio remains high. We will occasionally answer questions on the instances, especially if we see a "not-quite-correct" answer or general confusion. However, if you have a question for a TA, e-mail your TA instead. Also, questions on the instance are not guaranteed to receive a response from a staff member; to be sure of attention, visit an LA or TA during lab/office hours.
Certain questions are not appropriate for the zephyr instance. These include
You should either visit an LA or a TA, or you you should just ask your question on the instance and hope it gets an answer.
If you want to talk about 6.170-related topics which are not specific questions or answers, you should use the 6.170.d instance. For example, if want to start a debate on the aesthetic virtues of Java, wish to chat about the wonderful writing style of the problem set authors, or have to express frustration about the bug you've been hunting for two hours, the 6.170.d instance should be used instead of the 6.170 instance.
The mechanics of the 6.170.d instance are the same as 6.170, except you add a .d onto the obvious place in the examples above.
The 6.170 zlog is a solution to these two problems. It logs every message sent on the 6.170 zephyr instance. This way, you can unsubscribe from the instance and read the conversations that others are having on the instance separately, on your own time and at your own pace. You can also review conversations that took place while you were logged off. It is often very useful to skim the log before starting the problem set, just to check if there are any common problems with the Java runtime that other students are encountering and prepare to handle them yourself.
The 6.170 zlog is stored in the zlog locker on athena. To access it, first type at the athena prompt:
athena% add zlogThe 6.170 zlog is in the file
/mit/zlog/6.170
The zlog is a text file like any other. Therefore, you could try opening it in your favorite text browser. However, it can grow very large, which makes navigating the messages difficult.
Thus, it is recommended that you try the tail command as
an alternate way of reading the zlog. The tail command
is similar to the cat and head commands in
Unix, except that instead of starting at the beginning of a file and
printing the successive lines, it starts at some point near the end of
a file and then prints the remainder of the file to the terminal.
This way you don't have to scroll through pages of zephyrs you saw the
last time you were logged in; you just see the last few ones that were
sent.
You can tell tail to start at an arbitrary offset from
the end or the beginning of the file; the default action of
athena% tail /mit/zlog/6.170
is to print the last ten lines of the zlog. To have it start further
back, pass the -number option to
tail, where number is the number of lines to
offset the starting point from the end of the file. So,
athena% tail -50 /mit/zlog/6.170
outputs the last 50 lines of the log.
You can even have tail wait and print out new zephyrs as
they come in, if you prefer not to mix the 6.170 instance
conversations with your personal zephyr conversations. To do this,
use the -f option, as in:
athena% tail -f /mit/zlog/6.170
For more information on tail, read the man page, by
typing at the athena prompt:
athena% man tail
athena% add outland
athena% xwrits typetime=5 breaktime=0.50 +beep +clock +idle +mouse maxhands=5
+multiply +noiconify +lock &
You can also put the xwrits command in your .startup.X file.
athena% add acrowhich produces file.pdf.
athena% distill file.ps
Please note that distill is only available for the Sun platforms. If this is a problem, you may choose to run it on a dialup server, or may also use the ps2pdf utility in the gnu locker.
athena% dia &Dia can export its diagrams as encapsulated postscript files, which you can then convert to pdf. Or you can print out the diagrams from Dia itself.
If you have problems running dia, email noto@mit.edu (not 6.170-staff).
If you have problems using dia, see the links below:
Tutorial for Dia
Dia homepage
These setup instructions are only for the final project; however, the instructions for basic usage are relevant for problem sets as well as the final project. For examples of CVS usage that use Eclipse, please see S3: Problem Set Procedure.
The following instructions define how to access the repository created above. If you chose to use the skeleton project structure we have created for you, you do not need to follow these steps. Instead follow the instructions here.
After the repository has been created, each user should check out the gb module into their own working directory. First, create your working directory and switch to it:
cd /mit/6.170/groups/seNNM mkdir -p $USER; cd $USER
Then, check out the gb module:
cvs -d /mit/6.170/groups/seNNM/repository checkout gb
setenv CVS_RSH ssh
cvs -d
:ext:USERNAME@athena.dialup.mit.edu:/mit/6.170/groups/seNNM/repository
checkout gb
Finally, create a ~/.cvsrc file containing the following two lines:
diff -uSee the manual for more information about ~/.cvsrc files.
update -d -P
To update your working copy with the latest revision from the repository (but retaining any changes you have made in your local copy), use:
cvs update
CVS will try to merge any changes made since your last cvs update by both yourself and others. If some of your changes conflict with others' changes, cvs update will tell you so, and the source file will be changed to include both versions of any conflicting portions (yours and the one from the repository), in this format:
<<<<<<< filename YOUR VERSION ======= REPOSITORY'S VERSION >>>>>>> repository version's revision number
You must resolve the conflict by editing the file, removing the markers, and leaving whichever version of the code you prefer (or merging them by hand). (Searching for "<<<" until you've resolved all the conflicts is generally a good idea.) Once you've resolved any conflicts, you can safely commit the file to the repository.
Note that CVS works on a line-by-line basis. That is, it only knows whether an entire line has been changed, added, or deleted.
(cvs update displays the status of any files in your working directory that have changed or are different from the repository with a one-letter flag: "U" means it has been replaced with the latest copy from the repository. "M" means your working copy is different from the repository's latest version, and that merging is successful. "C" means that there are merge conflicts.)
To commit a file you've edited to the repository, use:
cvs commit filenameIf you omit the filename, CVS will commit all files in the current directory.
Important: You should always run cvs diff before running cvs commit. That will make it easier for you to see what changes you have made, to avoid committing changes that you do not intend to, and to write a descriptive log message.
When you run cvs commit, CVS will prompt you for a brief message describing your changes (possibly by starting an editor for you). Alternately, you can supply the log message on the command line:
cvs commit -m "a log message" filename
You should always enter a descriptive log message not something like, "Fixed some bugs."
To add a file to the repository, use:
cvs add filename
To remove a file from the repository:
rm filename cvs rm filename cvs commit -m "Removing the file for such and such reason"
These commands only mark the file for addition or deletion. After running cvs add or cvs rm, you'll still need to use cvs commit to actually notify the repository of the change.
To move or rename a file or a directory in CVS, you must remove it from one location and add it to another.
You can add a subdirectory with:
mkdir dirname cvs add dirname
cvs adding a subdirectory happens immediately, without the need to commit.
You cannot remove a subdirectory with CVS. (cvs rm cannot be used on a directory.) The best you can do is to rm and cvs rm everything in that directory, then run cvs update -P to get rid of any empty subdirectories in your working directory.
To see the change log, which is a list of the messages used when checking in changes,
cvs log filename
To see differences between the working copy and the repository's latest copy:
cvs diff [filename]Omit filename to see differences for all files. Use the -r1.xx flag to compare with a particular revision, and use two -r flags to compare two versions with each other.
Emacs has built-in-support for CVS. There are two ways you can invoke CVS commands from within Emacs: either from within a buffer that is visiting a file, or from a buffer that lists all modified files and permits you to perform operations on them.
CVS commands to perform actions from a file-visiting buffer are prefixed by C-x v (mnemonic: version control). The three most useful commands are
Alternately, you can use the pcl-cvs package to run CVS commands and browse the output. The primary command is
M-x cvs-update RETwhich runs cvs update and puts the results in a *cvs* buffer for you to browse. You can then operate on each line with commands such as the following:
CVS is no replacement for management! Coordination of work is important, even if you're working separately. You should minimize working on the same file at the same time if possible. If you do work on the same file, work on different portions. Modularizing code into multiple files often makes parallelizing work more efficient. You should always pass major design decisions by your teammates before implementing them, particularly if they involve interfaces that will affect their code.
When should you commit? If you commit too often without sufficient testing, you may introduce bugs into the repository that will affect your groupmates' work. However, if you commit too rarely, your groupmates will be using outdated code, which may cause wasted effort and merge conflicts later.
There is no hard and fast rule, but one good rule of thumb is to make sure everything at least compiles before you check in. There's nothing more annoying than having your code cease to compile after checking out someone else's changes.
Another good rule of thumb (though this one is far more malleable) is that you should minimize leaving something uncommitted when you quit for the day. A lot can happen while you're not coding, and it's generally better to get your change in working order and commit it before you leave. Since the previous rule (of never checking in non-working code) is more important, this can be hard to accomplish if you're making big changes. Thus, it's often good to tackle one feature at a time, so you can finish each piece quickly and keep the repository up-to-date.
Coordinating your efforts with your groupmates is, of course, the true key to minimizing merging hassles. Again, CVS is no replacement for management!
Some tips on avoiding common problems while using CVS:
One of the best communication features of CVS is its ability to send your commit message in email to other interested parties whenever you commit.
All you have to do is put your email address in a file called .cvsmail in any directory that you want to receive notifications about.
For example, suppose you have a repository called "antichess" and
you want user "ben_bitdiddle" to receive commit messages whenever
anyone commits in any subdirectory of the repository. You might have
checked out a sandbox of this repository into
~/6.170/workspace/antichess. Then you would create a new
text file ~6.170/workspace/antichess/.cvsmailthat would
contain the line ben_bitdiddle@mit.edu. Then you would add it to CVS and commit it.
Each new email address should go on a separate line. Of course you can just send all mail to "seNNN@mit.edu" from the top level of the repository if you want.
Don't forget to add the new .cvsmail file and commit it whenever you have made changes. Cvsmail relies on the committed version of the .cvsmail file, so changes in your sandbox alone will have no effect.
NOTE: if you want to use cvsmail in non-6.170 settings, you will have to copy the cvsmail.pl and commit_prep files from your group's $CVSROOT/CVSROOT/ to your other one, and update the loginfo and commitinfo files therein.
There's a lot more that CVS can do that isn't mentioned in this quick start guide. Please read the documentation for more help.
To read the CVS manual on athena, use the command info cvs. Alternately, from Emacs, do M-x info RET m cvs RET, where M-x is pressing x while holding down the meta key or the alt key, RET is the return key, and you do not need to type any of the spaces. See, in particular, the sections "Starting a new project" and "Overview/A sample session". Additionally, if one or more of your group members wants to work from home, you will want to read the section on "Repository/Remote repositories."
Additional information is available from CVS Home (see especially CVS for new users and the CVS manual). The CVS manual is available in a variety of formats.
Here are a few of the benefits of using Eclipse:
Using Eclipse's CVS on your own machine is the same as using it on Athena except that you will have to enter your password when you connect to the CVS repository. Also, if :ext mode does not work for you, try using :extssh.
Note: In general, all you need to do to run Eclipse from Athena is to call add eclipse-sdk; eclipse &. However, Eclipse looks for a directory called workspace/ in the directory from which it was launched, so we've wrapped these commands and aliased them to runeclipse so that you always launch Eclipse from your ~/6.170 directory.
| Autocomplete |
Ctrl-Space asks Eclipse to help
you complete some code you've started. Eclipse can complete lots
of things:
|
| Organize import statements |
Ctrl-Shift-O (that's O as in
Organize) automatically updates the import statements at the top of
your class, adding classes that need to be imported from other packages
and removing classes that you're no longer using. If a class name
is ambiguous -- e.g., List
might be either java.util.List
and java.awt.List -- then
Eclipse pops up a dialog asking you which one you want. |
| Look up Java API documentation |
Shift-F2 when your cursor is on
a class or method name. (You have to configure this feature with
the location of the API documentation; see PS0 for more details.) |
| Comment/uncomment a
block of code |
Ctrl+/ comments the highlighted
region. Ctrl+\ uncomments the highlighted region. |
| Mark todo items for
yourself |
Start a comment with TODO to
leave yourself a note about a piece of code that you need to fix.
Eclipse will automatically put the comment in the Tasks pane, the pane
where it shows your compile errors. (If you don't see the Tasks
pane, use Window > Show View > Tasks.) You can jump to todo
items or compile errors in your code quickly by double-clicking on them
in the Tasks pane. |
| See which files you
haven't committed to CVS yet |
Configure Eclipse so that the
file icons in the Package Explorer show you which files you've added or
changed but haven't commited to CVS:
|
| Generate get() and
set() methods |
Make sure the fields for which
you would like to create get() and set() methods are declared in the
class, then use Source > Generate Getter and Setter. |
| Run classes or unit tests that
you've run recently |
The little running man icon on
the Eclipse toolbar runs the last class or unit test you just
ran. Pull down its menu for your recent history of runs. |
| Renaming or moving packages,
classes, methods, and variables |
Right-click on any package,
class, method or variable
in the Package Explorer and select Refactor > Rename to rename it or
Refactor > Move to put it in another package or class. |