An open API service indexing awesome lists of open source software.

https://github.com/vegardit/no-npe

A repository of Eclipse External null Annotations (EEA) for better static null analysis
https://github.com/vegardit/no-npe

annotations eclipse eclipse-platform eea external-null-annotations java null-analysis null-safety nullability-analysis spring-framework

Last synced: about 2 months ago
JSON representation

A repository of Eclipse External null Annotations (EEA) for better static null analysis

Awesome Lists containing this project

README

        

# No NPE!

[![Build Status](https://github.com/vegardit/no-npe/workflows/Build/badge.svg "GitHub Actions")](https://github.com/vegardit/no-npe/actions?query=workflow%3A%22Build%22)
[![License](https://img.shields.io/github/license/vegardit/no-npe.svg?color=blue)](LICENSE.txt)
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.1%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)
[![Maven Central](https://img.shields.io/maven-central/v/com.vegardit.no-npe/no-npe-parent)](https://central.sonatype.com/artifact/com.vegardit.no-npe/no-npe-parent)

**Feedback and high-quality pull requests are highly welcome!**

1. [What is it?](#what-is-it)
1. [Usage](#usage)
1. [Binaries](#binaries)
1. [Building from Sources](#building)
1. [Validating/Updating EEA files](#validate_update)
1. [Adding a new Maven module](#new_module)
1. [Acknowledgement](#acknowledgement)
1. [License](#license)

## What is it?

**No NPE!** is a repository of [Eclipse External Null Annotations](https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations) for
better static Null Analysis with the Eclipse Java Compiler (ecj).

## Usage

Usage of External Null Annotations in Eclipse is documented at
https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm

### Binaries

Latest **Release** binaries are available on Maven central, see https://search.maven.org/search?q=g%3Acom.vegardit.no-npe

Latest **Snapshot** binaries are available via the [mvn-snapshots-repo](https://github.com/vegardit/no-npe/tree/mvn-snapshots-repo) git branch.
You need to add this repository configuration to your Maven `settings.xml`:

```xml





no-npe-snapshots
no-npe-snapshots
https://raw.githubusercontent.com/vegardit/no-npe/mvn-snapshots-repo
false
true





no-npe-snapshots

```

### Building from Sources

To ensure reproducible builds this Maven project inherits from the [vegardit-maven-parent](https://github.com/vegardit/vegardit-maven-parent)
project which declares fixed versions and sensible default settings for all official Maven plug-ins.

The project also uses the [maven-toolchains-plugin](http://maven.apache.org/plugins/maven-toolchains-plugin/) which decouples the JDK that is
used to execute Maven and it's plug-ins from the target JDK that is used for compilation and/or unit testing. This ensures full binary
compatibility of the compiled artifacts with the runtime library of the required target JDK.

To build the project follow these steps:

1. Download and install Java 11, Java 17 **AND** Java 21 SDKs, e.g. from:
- Java 11: https://adoptium.net/releases.html?variant=openjdk11 or https://www.azul.com/downloads/?version=java-11-lts&package=jdk#download-openjdk
- Java 17: https://adoptium.net/releases.html?variant=openjdk17 or https://www.azul.com/downloads/?version=java-17-lts&package=jdk#download-openjdk
- Java 21: https://adoptium.net/releases.html?variant=openjdk21 or https://www.azul.com/downloads/?version=java-21-lts&package=jdk#download-openjdk

1. Download and install the latest [Maven distribution](https://maven.apache.org/download.cgi).

1. In your user home directory create the file `.m2/toolchains.xml` with the following content:

```xml



jdk

11
default


[PATH_TO_YOUR_JDK_11]



jdk

17
default


[PATH_TO_YOUR_JDK_17]



jdk

21
default


[PATH_TO_YOUR_JDK_21]



```

Set the `[PATH_TO_YOUR_JDK_11]`/`[PATH_TO_YOUR_JDK_17]`/`[PATH_TO_YOUR_JDK_21]` parameters accordingly
to where you installed the JDKs.

1. Checkout the code, e.g. using:

- `git clone https://github.com/vegardit/no-npe`

1. Run `mvn clean verify` in the project root directory. This will execute compilation, unit-testing, integration-testing and
packaging of all artifacts.

### Validating/Updating EEA files

The EEA files can be validated/updated using:

```bash
# validate all EEA files of all eea-* modules
mvn compile

# validate all EEA files of a specific module
mvn compile -am -pl
mvn compile -am -pl libs/eea-commons-io-2

# update/regenerate all EEA files of all eea-* modules
mvn compile -Deea-generator.action=generate

# update/regenerate all EEA files of a specific module
mvn compile -Deea-generator.action=generate -am -pl
mvn compile -Deea-generator.action=generate -am -pl libs/eea-commons-io-2
```

Updating EEA files will:
- add new types/fields/methods found
- remove obsolete declarations from the EEA files
- preserve null/non-null annotations specified for existing fields/methods

### Adding a new Maven module

1. Create a new sub-directory under `libs/` using the name pattern `eea-[LIBRARY_NAME]-[LIBRARY_MAJOR_VERSION|latest]`

1. Create a pom.xml in the new directory like this:

```xml

4.0.0


com.vegardit.no-npe
no-npe-parent
[CURRENT_SNAPSHOT_VERSION]

no-npe-eea-[LIBRARY_NAME]-[LIBRARY_MAJOR_VERSION]



[LIBRARY_GROUP_ID]
[LIBRARY_ARTIFACT_ID]
[LIBRARY_VERSION]
provided



```

For example:

```xml

4.0.0


com.vegardit.no-npe
no-npe-parent
1.0.0-SNAPSHOT

no-npe-eea-cool-library4



org.example.cool-library
cool-library
2.0.2
provided



```

1. Add an eea-generator.properties file in the same directory where you specify the relevant packages of the library.

```properties
packages.include=package1,package2
```

E.g.

```properties
packages.include=org.example.cool-library.api,org.example.cool-library.spi
```

The following options are available:
|name|description|default|
|-|-|-|
|`packages.include`| The comma separated packages to recursively scan for class files| n/a
|`classes.exclude`| A comma separated list of regex patterns that are matched against fully qualified class names to exclude them from scanning| n/a
|`action`| The default action (`validate` or `generate` to perform during `mvn compile`) | `validate`
|`output.dir`| Path to the root directory containing the .eea files. Used for validation and generation.| `src/main/resources`
|`input.dirs`| Comma separated additional paths of root directories containing .eea files to read null annotations from on `generate`.| n/a
|`omitRedundantAnnotatedSignatures`| If `true` lines with annotated signatures are not written to the file if they don't contain any null annotations | `false`

These options can also be specified in the command line as system properties like `-Deea-generator.=`,
e.g. `-Deea-generator.omitRedundantAnnotatedSignatures=true`

1. In the parent project's pom.xml file reference the module in the `` section.

1. Run the generator in the parent project to create the EEA files

```bash
mvn compile -Deea-generator.action=generate -am -pl
```

E.g.

```bash
mvn compile -Deea-generator.action=generate -am -pl libs/eea-cool-library-2
```

1. Manually add missing null/non-null annotations in the generated EEA files under `src/main/resources`

## Acknowledgement

**No NPE!** was created by [Sebastian Thomschke](https://sebthom.de) and is sponsored by [Vegard IT GmbH](https://www.vegardit.com).

Creation of this project was inspired by https://github.com/lastnpe/eclipse-null-eea-augments/ but a different approach in
generating/packaging/validating of EEA files/archives has been taken.

**No NPE!** would not have been possible in its current form without the following technologies and learning resources:

**Technologies/Libraries**
- [ClassGraph](https://github.com/classgraph/classgraph) - fast Java classpath scanner
- [gmavenplus-plugin](https://groovy.github.io/GMavenPlus/) - Maven plugin to execute arbitrary Groovy code during Maven lifecycle phases
- [exec-maven-plugin](https://www.mojohaus.org/exec-maven-plugin/) - toolchain aware Maven plugin to execute custom Java code during Maven lifecycle phases
- [AssertJ](https://github.com/assertj/assertj) - strongly-typed assertions for unit testing

**Tutorials**
- Null Analysis/External Annotations https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations
- Using external null annotations https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm
- Type Signature Syntax https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/Signature.html
- NullPointerException presentation given at EclipseCon Europe 2016 https://www.slideshare.net/mikervorburger/the-end-of-the-world-as-we-know-it-aka-your-last-nullpointerexception-1b-bugs
- Field Descriptors https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.3.2

## License

All files are released under the [Eclipse Public License 2.0](LICENSE.txt).

Individual files contain the following tag instead of the full license text:
```
SPDX-License-Identifier: EPL-2.0
```

This enables machine processing of license information based on the SPDX License Identifiers that are available here: https://spdx.org/licenses/.