As of 2017, all exercises are coded in Java. Each Pityoulish exercise comprises:
- A description in HTML, from files in src/main/prose/
- A JAR file, compiled and assembled from source code in src/main/java/
- JavaDocs, generated from the same source code
All student files for an exercise are packaged into a single zip archive. Instructors can build notes and server-side JARs in a similar fashion. This readme describes how to set up a development environment, how to build various components with Ant, and how the build process works.
Table of Contents:
- Setup - install your own build environment
- Ant Targets - use Ant to build exercises and related stuff
- Build Steps - how the build process works
- Prose - write exercises or instructions in HTML
To set up a command-line based development environment, you will need:
- a Java Software Development Kit, for example OpenJDK
Linux distributions typically provide that through their package manager. - Command-line tools:
git,ant
Linux distributions typically provide these through their package manager. - Java libraries:
ant-contrib,junit4,hamcrest
Linux distributions may provide some through their package manager. Download the JAR files for the others.
Expect JMockit to appear in this list in the future. - optional: grip for previewing markdown before committing
My workflow is based on an editor, command line, and browser. When building exercises, the Java sources are pre-processed with Ant, to punch in the gaps that students have to fill. You might find it tricky to use an IDE for that step. The actual coding and unit-testing during development is done without pre-processing though. It should work smoothly with an IDE.
To get started...
- Clone the Pityoulish GitHub project.
- Make sure Ant has access to the ant-contrib tasks.
- Copy
ant.local.templatetoant.local. Edit the latter and specify the paths to the extra JAR files. For example on my Linux workstation:junit4.jar = /usr/share/java/junit4.jar hamcrest.jar = /usr/share/java/hamcrest-all.jar - In a terminal, change to the project directory and execute:
This should pass without errors or warnings. To see the main Ant targets, execute:
ant _clean compile test jdocant -projecthelp - Point your browser to
src/main/prose/local-index.htmlin the project directory.
This page contains links to the test results and JavaDocs from the previous step, and more.
Happy hacking!
Run ant -projecthelp to list the main Ant targets.
Targets without a hyphen (-) apply to the whole project, across exercises.
This includes "compile", "test", and "jdoc" mentioned in Setup above.
Ant targets specific to an exercise have at least one hyphen in their name, and an acronym in the description. For example:
| Target | Acronym | Purpose |
|---|---|---|
| prep-java | tpj | Tutorial: Prepare for Java exercises |
| client-sockets-java | xjs | Exercise: Java Sockets |
| server-sockets-java | ijs | Instructions: Java Sockets |
| follow-sockets-java | fjs | Follow the board: Java Sockets |
| client-rmi-java | xjr | Exercise: Java RMI |
| server-rmi-java | ijr | Instructions: Java RMI |
| follow-rmi-java | fjr | Follow the board: Java RMI |
The target for an Exercise or its Instructions will build a zip archive for students or instructors, respectively.
This requires several sub-targets to be built. Ant prints these sub-targets while it executes.
If you are working on a specific part of an exercise, you can build the respective sub-target directly to save time.
For example, building the Tutorial with prep-java builds these sub-targets, among others:
tpj-jar- The JAR file with bugs to fix, and another without the bugs.tpj-jdoc- JavaDocs just for the classes in the JAR file.tpj-prose- The tutorial description in HTML.tpj-all- The zip archive comprising JAR, JavaDocs, and description. Same asprep-javaitself.
The Java source code for all clients, servers, and other programs is in one combined source tree at src/main/java/.
Unit tests are in a similar source tree at src/test/java/.
For development, the source tree is compiled into one class tree, and different programs started by running Main from different packages.
There is no packaging into subsets of classes for the different programs at this point.
The unit tests are also compiled into one class tree.
Some relevant Ant targets are:
ant compilecompiles the main sources into classesant compile-testscompiles the unit tests into classes. Requires the main sources to be compiled.ant compile-pitfillpreprocesses the sources and compiles the result. See the next section about preprocessing.
The code in the source tree is fully functional. For the exercises, selected parts are removed to introduce the bugs that students have to fix. This is achieved by processing the source code before compilation. Special comments in the code indicate which parts to remove. For example:
// PYL:keep
Missing.here("bind a socket to a hostname");
Missing.pretend(IOException.class);
// PYL:cut
Socket so = new Socket();
so.bind(isa);
// PYL:endFor development, this code is compiled as-is. The calls to class Missing are no-ops there. The subsequent calls perform the expected operation.
To trigger a MissingException during development, call Missing.here(null), without an argument string.
The source code is pre-processed twice, into a pitted version from which to build student JARs (faulty), and into a filled version from which to build instructor JARs (good). The Ant targets "preprocess" and "compile-pitfill" take care of preprocessing and of compiling the preprocessed sources, respectively.
For the pitted version, the lines between PYL:keep and PYL:cut are retained, while the lines between PYL:cut and PYL:end get removed.
In the faulty JARs built from these sources, calls to Missing.here raise an exception. This leads students directly to the point in the code where the functional lines have been removed.
For the filled version, the lines between PYL:keep and PYL:cut get removed, while the lines between PYL:cut and PYL:end are retained.
In the good JARs built from these sources, there are no references to class Missing at all. That class itself is missing.
These JARs can be handed out for reference after an exercise. Without the special comments, the sources are less confusing for the students.
PYL:keep, PYL:cut, and PYL:end lines must always appear in triplets, even if one of the sections is empty.
These lines themselves are removed from both versions. Besides the keyword, they may contain only whitespace and comment markers.
In combination with multi-line comment start /* and end */, this can be used for creative handling of special cases.
For example if the pitted version of a class is abstract, while the full source file would not compile with that keyword:
/* PYL:keep
abstract
// PYL:cut */
// PYL:end
public class FooImpl implements Foo {
// PYL:keep
// PYL:cut
public int bar() { return 8; }
// PYL:end
}All exercise descriptions and instructor's notes are written as static HTML files in src/main/prose/.
You can read all the information by browsing the files on your local machine, without running a build or a web server.
local-index.html is the table of contents.
When building the prose for a zip archive, the relevant files are copied to a dedicated directory, and one of them is renamed to index.html.
By browsing the dedicated directory, you can verify that all relevant files have been copied.
There is a naming convention to support the co-existence of all the exercises and notes in a single directory:
pityoulish.cssor other files without a hyphen (-) provide a common style. These files are copied into every exercise and instructor package.- xyz
-index.htmlbecomes theindex.htmlfile when building the xyz-proseAnt target. message-board.htmlor other files with a hyphen (-) are copied only into zip archives for which they are relevent. Their name remains unchanged.- Some files with a hyphen (-) are just local, not relevant for any of the zip archives:
local-index.htmlis the table of contents. It links to all xyz-index.htmlfiles with their local name. It also links to default locations of exercise-specific JavaDocs, as generated by the xyz-jdocAnt targets.color-palette.gpais the GPick palette from which the colors inpityoulish.csswere chosen.
Due to this naming convention, links to non-index files work everywhere.
Backlinks to index.html are broken in the source directory, but work in the dedicated directory.
Links to xyz-index.html work only in the source directory, but are broken everywhere else.