JavaCOP Tutorial (using Java commands)
Contact Shane Markstrum (smarkstr at cs
dot ucla dot edu) with any questions or comments.
How to run JavaCOP as an extensible type checking compiler
Using JavaCOP is relatively as easy as using javac. In fact, JavaCOP
is simply an extension of the OpenJDK version of javac. We have a newer tutorial focusing on the use of
scripts we have provided for use with JavaCOP. However, if you prefer to
learn the basic Java commands to use for running JavaCOP from its jar
file, then this tutorial should provide you with the know-how.
First Steps:
- Obtain a copy of the JavaCOP jar from the SourceForge site,
which includes all components of JavaCOP discussed on the JavaCOP website except for scripts and examples.
- Run the JavaCOP Compiler with the -version flag and look
for the output show below.
Linux/Windows:
prompt> java -cp JavaCop.jar com.sun.tools.javac.Main -version
javac 1.7.0-ea_JavaCOP
Mac OS X*:
*Note that there is an error here! Well, that's because the OS X Java and the OpenJDK don't always play the same way with the classpath.
prompt> java -Xbootclasspath/p:JavaCop.jar com.sun.tools.javac.Main -version
compiler message file broken: key=javac.version arguments=javac, 1.7.0-ea_JavaCOP, {2}, {3}, {4}, {5}, {6}, {7}
- You're ready to start using the JavaCOP utilities! Note that you
will need to make sure the JavaCop.jar file is available on
the classpath for all of the remaining section. This requirement is
reflected in JavaCop.jar being shown explicitly on the
classpath of all further Java commands.
Compiling JavaCOP Rules
If you are eager to start type checking Java programs with JavaCOP,
then this section is optional so long as you download NonnullRules.jar. (This jar file
contains all of the necessary Java classes and annotations for
checking programs with a non-null type system developed in JavaCOP.)
Skip to next section
This section will teach you how to go from a JavaCOP rule file to a
compiled JavaCOP checker which can be utilized by the JavaCOP
compiler. If you are interested in learning how to write rules, you
can visit the rule
development section of the main tutorial.
- Obtain a copy of the JavaCOP Rule Examples and
untar it. Go to the examples/nonnull directory. You should
see two subdirectories here (javacop and tests) and
the file Nonnull.jcop.
- Nonnull.jcop is the file that contains the rule
specification for a flow-sensitive non-null checker written in
JavaCOP. The first step to creating a type-checking class is to
compile the rule specification into a Java file. This is accomplished
with the JavaCOP parser.
prompt> java -cp JavaCop.jar compiler.JcopParser Nonnull.jcop
Compiling file to: Nonnull.java
done
- At this point, there should now be another file in the
examples/nonnull directory: Nonnull.java. This file should
now be compilable with javac to produce the non-null type checker.
Since the checker is an extension of a class from the JavaCOP compiler, you
will need JavaCop.jar on your compilation classpath. It also depends
on the classes NonNullFlowFacts and RawTypesFlowFacts, which
are in the examples/nonnull/javacop/nonnull directory. Including the
current working directory in your javac classpath should compile
these classes, as well.
prompt> javac -cp JavaCop.jar:. -d . Nonnull.java
- Now, in the examples/nonnull/javacop/nonnull directory, you
should have four Java class files: Nonnull.class,
Nonnull$1.class, NonNullFlowFacts.class,
RawTypesFlowFacts.class. If compilation has succeeded, then you now
have a working copy of the flow-sensitive non-null type checker. The checker
can now be used by putting the examples/nonnull directory on the
classpath of a JavaCOP compiler invocation and specifying
javacop.nonnull.Nonnull as an option. The next section will go into
further details of how to type check Java programs.
Type Checking Java Files
At this point, you should have either a jar file or directory structure
which you can specify on the classpath of an invocation of the JavaCOP
compiler which contains the classes for the flow-sensitive type checker. In
all commands from this point, I will be using the placeholder
NonnullRules.jar to represent this classpath entry, such as:
prompt> java -cp JavaCop.jar:NonnullRules.jar com.sun.tools.javac.Main ...
- Before you can type check a Java file, you will need a file that
exercises the pluggable type system which you will load. In this case,
we will make a very simple Java class that has one field annoted as non-null
and which assigns into that field a new Object instance. Save this
class as TutorialClass.java
import javacop.annotations.Nonnull;
public class TutorialClass {
@Nonnull Object f;
public TutorialClass() {
f = new Object();
}
}
- Now, if you invoke the JavaCOP compiler to compile
TutorialClass.java and pass javacop.nonnull.Nonnull
as an argument to the -javacop option, it should compile
without an error.*
*Mac users will need to invoke the compiler as
previously specified at the beginning of the tutorial.
java -cp JavaCop.jar:NonnullRules.jar com.sun.tools.javac.Main -javacop javacop.nonnull.Nonnull TutorialClass.java
Loading constraints class: javacop.nonnull.Nonnull
Done, loaded 1 constraint sets.
- To create an error in TutorialClass, change the line
f = new Object();
to the line
f = null;
- Now, rerun the JavaCOP compiler and it will report an error.
java -cp JavaCop.jar:NonnullRules.jar com.sun.tools.javac.Main -javacop javacop.nonnull.Nonnull TutorialClass.java
Loading constraints class: javacop.nonnull.Nonnull
Done, loaded 1 constraint sets.
TutorialClass.java:8: Nonnull: Using possibly null value where a @Nonnull value is expected
f = null;
^
1 error
That's all there is to using JavaCOP. It can act as a javac
replacement in your toolchain or as a supplement. One thing to note is that
the JavaCOP compiler is based on the OpenJDK compiler, which is currently at
version 1.7. To run any classes compiled with the JavaCOP compiler, you will
need to target the compilation to a version of Java compatible with your
java executable.
Return to main tutorial page