Setup

A working Intelji IDEA development environment can be obtained by ./gradlew idea and then importing the generated project (owl.ipr) to IDEA.

If you instead want to work with the IDEA Gradle plugin, import the project as usual ("Open Project" > build.gradle) and perform the following configuration:

Checks

Before submitting code please executed ./gradlew check locally to run all code checks. Apart from jUnit tests, static code analysis is performed using PMD and ErrorProne (rules are located in the config folder). Further, checkstyle is used to check compliance with the Google Java Style Guide. Passing all these tests is mandatory for submitted code.

Coding Conventions

In general, features of Java 11, like Lambdas, Streams, Collections.of, forEach-style, etc., can and should be used frequently. Streams should only be used for prototypes or in non-performance critical code, since they do add noticeable overhead. Typical "best practises" like KISS and DRY should be adhered to, some performance can be sacrificed for clear and concise code. Nevertheless, performance must not be neglected.

Exceptions and Checks

The following conventions should be followed:

Utilities

Where applicable, JDK functionality should be preferred (e.g., JDK List.of over Guava ImmutableList.of). If the JDK does not offer some particular functionality, Guava usually provides it and that should be used. Before implementing your own methods, double check that none of owl's utility libraries provide it already.

Immutable tuples

For classes that are simple structured carriers, i.e. data containers or tuples, AutoValue should be used. Hiding the implementation class (by, e.g., giving it package visibility) is recommended, since Java may support value types natively in the near future. Finally, for performance critical code, double-check that the generated code is doing what you expect from it (e.g., no superfluous copies are performed).

Naming

In general, everything should have self-explanatory, english names. Also, the following naming schemes should be followed:

Sorting

Members of a class can be sorted alphabetically (adhering to the general order), but a logical structure is preferred. For example, one can keep setters and getter together or group methods by their type (e.g., simple property accessor, complex mutation, ...). For tuples (see above), the convention is the following: "fields", derived fields, factory methods ("of"), constructor-like methods ("with..."), other methods.

Javadoc

Javadoc isn't required everywhere, but strongly encouraged. Code without any documentation is not accepted. The Oracle and Google style guides apply. Specifically, block tags (like @throws, @return, etc.) should be continued by a lower-case sentence. For example, @throws IllegalArgumentException if the argument is not allowed or @return the thing.

Windows

To use development tools on Windows:

Dependency verification

When changing dependency versions, run gradlew --write-verification-metadata sha256 help to regenerate the checksums. Currently junit-bom.pom has to be added manually due to a bug.

To completely regenerate the file and prune stale entries, delete the file and run above command. Then, add

<trusted-artifacts>
 <trust file=".*-javadoc[.]jar" regex="true"/>
 <trust file=".*-sources[.]jar" regex="true"/>
</trusted-artifacts>

to the <configuration> section, otherwise IntelliJ complains.