This handout describes how to perform common Java development tasks in the Allen Center software labs with IntelliJ.
Contents:
If you are working on your own computer or a CSE Linux Home VM, and you are working through the handouts in the recommended order, you should have installed IntelliJ. Else, it is installed on the department machines.
You may be able to click and icon or search for IntelliJ in your program launcher.
Otherwise, go to the directory where IntelliJ is installed and then go into the
bin
subdirectory. Then type the following command:
./idea.sh
IntelliJ will start up, display a splash screen, and then potentially show a settings import dialog:
IntelliJ is asking you whether to import settings. If you have used IntelliJ before, pick the first option and locate the settings. Otherwise, pick the second option.
From the start menu, search for IntelliJ.
IntelliJ will start up, display a splash screen, and then potentially show a settings import dialog:
IntelliJ is asking you whether to import settings. If you have used IntelliJ before, pick the first option and locate the settings. Otherwise, pick the second option.
We expect your code to not have any generics-related problems. For example, the following code is unacceptable:
List myList = new ArrayList(); myList.add("foo");
The generic type List
of myList
should be parametrized, for
instance, to String
by replacing the first line with
List<String> myList = new ArrayList<String>();
Note that
List<String> myList = new ArrayList();
is also incorrect.
By default, IntelliJ does not show generics problems as or errors. You can run a generify tool to ensure that your code contains acceptable generics.
To make this configuration, go to Refactor » Generify..., update the preferences as required and click on Preview. Use this to ensure that all the changes being made are correct, and click Do Refactor.
First, set up an ssh key.
Then follow the following steps:
git@gitlab.cs.washington.edu:cse331-19wi-students/cse331-19wi-YourCSENetID.git
(where YourCSENetID is your CSE Net ID)Please ensure your project is using JDK 11. Go to File | Project Structure... and under Project SDK select 11 if it is available. If not, click New and select the folder in which JDK 11 is installed (on Windows something like C:/Program Files/Java/jdk-11.x.x). If you cannot find JDK 11, please make sure it is installed.
Also be sure to change the Project language level to 11. Your Project Structure should look like this:
Click File | New | Module from Existing Sources... then select build.gradle in your project. Click OK
From here, change the Gradle JVM to JDK 11. Your dialog box should look like this:
Once everything looks correct, click OK. This will take some time but after finishing you should now have Gradle integrated with IntelliJ.
You can open multiple files in IntelliJ by double-clicking each of them from the Project View pane. Once you have multiple files open, you can switch between them quickly by holding down Ctrl and hitting Tab to bring up a dropdown box of open files, and then using the arrow keys to select the file whose editor you wish to bring into focus. You can also navigate through different files using the tabs on top of the editor pane.
To create a new Java source file (with the .java
extension),
right click on the package you want to add the file to New »
Java Class. A window will pop up, asking you for the name of the class.
Choose a name for your class (e.g. MyClass
) Type this name in the
"Name" field and click Finish.
(If you want your new class to be executable, it will need a main
method.)
There is a similar procedure for creating new non-Java files such as text files.
Right click on the directory you want to add the file to
New » File. In the resulting dialog box, type the desired filename.
If you want to create a new directory, you can do so by appending the directory
name in front of your desired filename. For example, if you want to create a file
problem0.txt
in the directory hw1/answers
, but the
answers
directory does not yet exist, you can choose hw1
as
the parent directory, and then type answers/problem0.txt
as the
file name, and IntelliJ will create the new directory and file for you.
Here are some useful actions that you can perform when editing Java code:
Autocompletion is the ability of an editor to guess what you are typing after you type out only part of a word. Using autocompletion will reduce the amount of typing that you have to do as well as the number of spelling mistakes, thereby increasing your efficiency.
IntelliJ continuously parses your Java files as you are editing, so it is aware of the names of variables, methods, etc... that you have declared thus far.
CTRL+Space can be used to autocomplete most
things inside the IntelliJ Java editor. For example, if you have declared
a variable named spanishGreeting
in the current class,
and have typed the letters spanishGree
in a subsequent line,
IntelliJ can infer that you mean to type spanishGreeting
.
To use this feature, press CTRL+Space while your cursor is at the right of the incomplete
name. You
should see spanishGree
expand to spanishGreeting
.
IntelliJ can also help you autocomplete method names.
Suppose you have a variable myList
of type List
, and
you want to call the method clear
. Begin typing "myList.
"
— at this point, a pop-up dialog will display
a list of
available methods for the type List
, and you can select the
appropriate method with the arrow keys. You can force the popup to appear
with CTRL+Space.
You can press
CTRL+ALT+o to
organize your imports in a Java file.
IntelliJ will remove extraneous import
statements and try to
infer correct ones for types that you refer to in your code but
have not yet been imported.
(If the name of the class that needs to be imported is
ambiguous – for example, there is a java.util.List
as
well as a java.awt.List
– then IntelliJ will prompt you
to choose which one to import.)
Although you can directly browse the Java 8 API and other documentation at the Oracle website, it is often useful to be able to cross-reference parts of your code with the appropriate documentation from within your editor.
Note that you need to generate the API documentation locally before you can view docs for classes in the assignment.
IntelliJ provides multiple ways to look at documentation of code directly from the IDE. Their website contains documentation on the same. Click here to view this documentation.
If you are adding documentation of code that is written by you, you will
need to prepend the file location with file:///
.
Please read about version control and git here first.
Pulling from git takes all the changes from your GitLab repository and brings them onto your machine.
To pull changes, choose VCS | Git | Pull. The Pull Changes dialog will open. You can usually leave all the options as default and click Pull to fetch and apply changes from the remote repository. If there are merge conflicts of any sort, you will be notified.
Commiting changes allows you to create checkpoints of your homework progress as you go. These commits will later be pushed to git.
To commit in IntelliJ, click the button in the top right of the window, or press Ctrl+K. The Commit Changes dialog box should appear. In here, you can select which files you would like to commit and leave a commit message at the bottom. This message can be anything you choose, but we recommend using informative descriptions of exactly what was changed. After writing your message and choosing your changes, click Commit. Please note that your changes have not been uploaded to GitLab. To do this, we need to push
After you have created a commit, you must push it in order for it to appear in your GitLab repository. This can be done by pressing Ctrl+Shift+K or by choosing VCS | Git | Push from the main menu. In this dialog, click Push and your changes will be synced with GitLab. If there are any merge conflicts, you will be informed (this should rarely happen as you are the only one pushing code to your repository).
In CSE 331, we ask you to create tags in order to turn in your homeworks. To create these tags in IntelliJ, go to VCS | Git | Tags.... In this dialog box, enter a name for your tag and choose a commit, or none for HEAD (which is likely the most recent push). Click Create Tag. Now you must push the tag. Press Ctrl+Shift+K or choose VCS | Git | Push in the main menu and then make sure Push Tags is checked. Now click Push. You should always double check the tag exists in GitLab.
Gradle is a build system, which automates development tasks.
Gradle can be run from inside IntelliJ or from the command line.
To invoke Gradle from the command line, run the command
./gradlew
in directory
~/cse331-18au-$USER
.
The most common command is ./gradlew build
.
It runs the "build" task, which checks your program for common errors, compiles your program, runs tests, and generates documentation.
Using a build system like gradle is better than you having to remember to run each of those tasks separately.
Run ./gradlew tasks
to see a list of other tasks you can use.
To run Gradle in IntelliJ there are 2 different tool windows you could run it from:
View > Tool Windows > Gradle
)
You can select the task you want to run under each folder. For example,
the command ./gradlew build
on the command line
is equivalent to selecting build > build
in the tool window.
For this class, most of the tasks you are able to run are under
build
, validation
, and other
.
You can also run the task you want by clicking on the icon, and typing in the name of the task you would like to execute.
You will be able to run most ./gradlew
command line targets on
this terminal.
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.
IntelliJ is set up by default to automatically recompile your code every time you save. Classes with compile errors are marked in the Project View with a red underline.
If your file is saved and IntelliJ says that it does not compile but you believe that it should, make sure that all of the files on which your file depends are saved and compiled. If that does not work, try refreshing your project or using Build » Rebuild Project to force IntelliJ to recognize the latest versions of everything.
Once you have compiled your source code into class files, you can execute it with the Java interpreter.
To run a program, right click on the Java source file containing the
main()
method and choose Run 'FILENAME' where
FILENAME is the file with the main()
method.
There is also a button near the top-right-hand side of the IntelliJ window that looks like which will re-run the last application (or JUnit test, see below) that you ran.
JUnit is the testing framework that you will use for writing and running tests.
For more information, visit:
JUnit is normally integrated with IntelliJ, but since we are using Gradle, we must tell IntelliJ to delegate work to Gradle.
File > Settings
for Windows and Linux or
IntelliJ IDEA > Preferences
for macOS
Build, Execution, Deployment > Build Tools > Gradle >
Runner
Now, if you run any tests under src/test/java/hw*
, it will use Gradle to
run it. To run any specific test file:
To run all of the tests in your test suit, select Verification > test
in the IntelliJ Gradle tool window.
A test result window should pop up near the bottom of the screen momentarily and run all the tests. You can double-click on failed tests to jump to the code for that test. When you're done inspecting the JUnit results, you can close the JUnit pane.
Because your JUnit tests will likely have different class and method names
than those of your classmates, there needs to be a standardized way
of accessing every student's tests. Thus, each assignment comes with
the JUnit test classes hwN.test.SpecificationTests
and
hwN.test.ImplementationTests
. You will load all
the JUnit tests you wrote in one of these two test suites.
hwN.test.SpecificationTests
, as it name suggests, should
contain only specification tests — that is, those tests that
check only for features implied by the specification. Consequently,
your specification tests should be valid tests for any other person's code
that claims to satisfy the same specification, even if that implementation
is inherently very different.
Conversely, hwN.test.ImplementationTests
should contain
implementation tests — that is, those tests that test only
details that are specific to your implementation.
As an example, suppose you were implementing the following specification:
/** Frobs the blarghnik. * @spec.requires b != null */ public void frob(Blarghnik b);
A specification test should never pass in a null parameter to this method — this would violate the specified pre-condition. However, your particular implementation might check for the null parameter and throw a NullPointerException. Your implementation test can safely exercise this case by passing in null.
Similarly, an iterator specification which does not specify the order in which elements are returned indicates that no specific order should be assumed in a specification test. Your implementation may happen to keep elements in a sorted list, and so your implementation test may wish to check that the elements returned by the iterator are sorted.
Before your submit each assignment, you should run tests with ./gradlew build
and validate your assignment with ./gradlew build
.
The javadoc tool produces API documentation (in HTML form) from source code annotated with special comments.
To run the Javadoc tool, issue this command:
./gradlew javadocYou can find the generated API documentation, in HTML form, under
build/docs/javadoc
.
You can also generate API documentation in IntelliJ by selecting
Tools > Generate Javadoc...
If IntelliJ fails due to unknown tags, you will need to add the tags to IntelliJ.
Your Java code comments contain "tags", which are introduced by an at-sign (@). The Javadoc tool formats these specially in the HTML output.
We have extended the javadoc tool to recognize additional CSE 331 tags, in adition to the standard tags. These additional tags declare specification fields for classes and requires, modifies, and effects clauses for methods. Note that all Javadoc tags must appear after all non-tag comments for classes and methods.
@spec.specfield name : T // text | Indicates that name is a abstract specification field of type T for the class, adding text as a comment if present |
@spec.derivedfield name : T // text | 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 @spec.specfield n : integer
we could define a
derived field:
@spec.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.
@spec.requires X | Declares X to be a precondition for the method |
@spec.modifies Y | Declares that nothing besides Y will be modified by the method (as long as X holds when it is invoked) |
@spec.effects Z | Declares that Z will hold at exit from the method (as long as X holds when it is invoked) |
You may need te specify the path to the git
executable:
In the Settings/Preferences dialog (Ctrl+Alt+S), select Version Control | Git in the left pane.
It is bad style to have tab characters in code files, because they display differently for different people.
(Pressing the Tab key while using your editor is great, but that key should should insert spaces.)
In IntelliJ IDEA, make sure that the
Editor >> Code Style >> Default Indent Options : Use tab character
checkbox is not selected.
IntelliJ will warn you about unrecognized the 331 Javadoc tags (@spec.*
).
There are two ways to eliminate the warnings.
File > Settings
for Windows and Linux or
IntelliJ IDEA > Preferences
for macOS
Editor > Inspections > Java > Javadoc
and uncheck the
box next to "Declaration has Javadoc problems".
Using the keyboard shortcut:
Alt + Enter
.
Using the settings panel
Options >
Additional Javadoc Tags
and add all of the extended tags.
After you have done one of the above, the warnings for the extended tags will go away.
Optionally, you could install the Google Java Format plugin to IntelliJ that will reformat
your code using the google-java-format tool. This is the same tool that
./gradlew reformat
and ./gradlew checkFormat
uses to run on
your source code.
File > Settings
for Windows and Linux or
IntelliJ IDEA > Preferences
for macOS
Plugins
If the staff provides a new version of a library, IntelliJ will not automatically know about the library's new symbols (classes and methods). As a result, IntelliJ will not do completion and may issue warnings about them. To resolve the problem:
git pull
./gradlew build