{"id":25201932,"url":"https://github.com/vegardit/no-npe","last_synced_at":"2025-06-10T20:05:36.377Z","repository":{"id":57620990,"uuid":"527225406","full_name":"vegardit/no-npe","owner":"vegardit","description":"A carefully curated repository of Eclipse External null Annotations (EEA) for enhanced static null analysis","archived":false,"fork":false,"pushed_at":"2025-06-02T11:33:48.000Z","size":12601,"stargazers_count":5,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-02T23:44:15.957Z","etag":null,"topics":["annotations","eclipse","eclipse-platform","eea","external-null-annotations","java","null-analysis","null-safety","nullability-analysis","spring-framework"],"latest_commit_sha":null,"homepage":"https://buymeacoffee.com/vegardit","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vegardit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-08-21T14:09:55.000Z","updated_at":"2025-06-02T11:33:45.000Z","dependencies_parsed_at":"2025-05-15T15:36:39.863Z","dependency_job_id":null,"html_url":"https://github.com/vegardit/no-npe","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fno-npe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fno-npe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fno-npe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fno-npe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vegardit","download_url":"https://codeload.github.com/vegardit/no-npe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vegardit%2Fno-npe/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258828274,"owners_count":22763940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotations","eclipse","eclipse-platform","eea","external-null-annotations","java","null-analysis","null-safety","nullability-analysis","spring-framework"],"created_at":"2025-02-10T06:14:45.634Z","updated_at":"2025-06-10T20:05:33.044Z","avatar_url":"https://github.com/vegardit.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# No NPE!\n\n[![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)\n[![License](https://img.shields.io/github/license/vegardit/no-npe.svg?color=blue)](LICENSE.txt)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.1%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)\n[![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)\n\n\n**Feedback and high-quality pull requests are highly welcome!**\n\n1. [What is it?](#what-is-it)\n1. [Usage](#usage)\n   1. [Binaries](#binaries)\n   1. [Building from Sources](#building)\n   1. [Validating/Updating EEA files](#validate_update)\n   1. [Adding a new Maven module](#new_module)\n1. [Acknowledgement](#acknowledgement)\n1. [License](#license)\n\n\n## \u003ca name=\"what-is-it\"\u003e\u003c/a\u003eWhat is it?\n\n**No NPE!** is a repository of [Eclipse External Null Annotations](https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations) for\nbetter static Null Analysis with the Eclipse Java Compiler (ecj).\n\n\n## \u003ca name=\"usage\"\u003e\u003c/a\u003eUsage\n\nUsage of External Null Annotations in Eclipse is documented at\nhttps://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm\n\n### \u003ca id=\"binaries\"\u003e\u003c/a\u003eBinaries\n\nLatest **Release** binaries are available on Maven central, see https://search.maven.org/search?q=g%3Acom.vegardit.no-npe\n\nLatest **Snapshot** binaries are available via the [mvn-snapshots-repo](https://github.com/vegardit/no-npe/tree/mvn-snapshots-repo) git branch.\nYou need to add this repository configuration to your Maven `settings.xml`:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003csettings xmlns=\"http://maven.apache.org/SETTINGS/1.2.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd\"\u003e\n  \u003cprofiles\u003e\n    \u003cprofile\u003e\n      \u003crepositories\u003e\n        \u003crepository\u003e\n          \u003cid\u003eno-npe-snapshots\u003c/id\u003e\n          \u003cname\u003eno-npe-snapshots\u003c/name\u003e\n          \u003curl\u003ehttps://raw.githubusercontent.com/vegardit/no-npe/mvn-snapshots-repo\u003c/url\u003e\n          \u003creleases\u003e\u003cenabled\u003efalse\u003c/enabled\u003e\u003c/releases\u003e\n          \u003csnapshots\u003e\u003cenabled\u003etrue\u003c/enabled\u003e\u003c/snapshots\u003e\n        \u003c/repository\u003e\n      \u003c/repositories\u003e\n    \u003c/profile\u003e\n  \u003c/profiles\u003e\n  \u003cactiveProfiles\u003e\n    \u003cactiveProfile\u003eno-npe-snapshots\u003c/activeProfile\u003e\n  \u003c/activeProfiles\u003e\n\u003c/settings\u003e\n```\n\n\n### \u003ca id=\"building\"\u003e\u003c/a\u003eBuilding from Sources\n\nTo ensure reproducible builds this Maven project inherits from the [vegardit-maven-parent](https://github.com/vegardit/vegardit-maven-parent)\nproject which declares fixed versions and sensible default settings for all official Maven plug-ins.\n\nThe project also uses the [maven-toolchains-plugin](http://maven.apache.org/plugins/maven-toolchains-plugin/) which decouples the JDK that is\nused 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\ncompatibility of the compiled artifacts with the runtime library of the required target JDK.\n\nTo build the project follow these steps:\n\n1. Download and install Java 11, Java 17 **AND** Java 21 SDKs, e.g. from:\n   - Java 11: https://adoptium.net/releases.html?variant=openjdk11 or https://www.azul.com/downloads/?version=java-11-lts\u0026package=jdk#download-openjdk\n   - Java 17: https://adoptium.net/releases.html?variant=openjdk17 or https://www.azul.com/downloads/?version=java-17-lts\u0026package=jdk#download-openjdk\n   - Java 21: https://adoptium.net/releases.html?variant=openjdk21 or https://www.azul.com/downloads/?version=java-21-lts\u0026package=jdk#download-openjdk\n\n1. Download and install the latest [Maven distribution](https://maven.apache.org/download.cgi).\n\n1. In your user home directory create the file `.m2/toolchains.xml` with the following content:\n\n   ```xml\n   \u003c?xml version=\"1.0\" encoding=\"UTF8\"?\u003e\n   \u003ctoolchains xmlns=\"http://maven.apache.org/TOOLCHAINS/1.1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"http://maven.apache.org/TOOLCHAINS/1.1.0 https://maven.apache.org/xsd/toolchains-1.1.0.xsd\"\u003e\n     \u003ctoolchain\u003e\n       \u003ctype\u003ejdk\u003c/type\u003e\n       \u003cprovides\u003e\n         \u003cversion\u003e11\u003c/version\u003e\n         \u003cvendor\u003edefault\u003c/vendor\u003e\n       \u003c/provides\u003e\n       \u003cconfiguration\u003e\n         \u003cjdkHome\u003e[PATH_TO_YOUR_JDK_11]\u003c/jdkHome\u003e\n       \u003c/configuration\u003e\n     \u003c/toolchain\u003e\n     \u003ctoolchain\u003e\n       \u003ctype\u003ejdk\u003c/type\u003e\n       \u003cprovides\u003e\n         \u003cversion\u003e17\u003c/version\u003e\n         \u003cvendor\u003edefault\u003c/vendor\u003e\n       \u003c/provides\u003e\n       \u003cconfiguration\u003e\n         \u003cjdkHome\u003e[PATH_TO_YOUR_JDK_17]\u003c/jdkHome\u003e\n       \u003c/configuration\u003e\n     \u003c/toolchain\u003e\n     \u003ctoolchain\u003e\n       \u003ctype\u003ejdk\u003c/type\u003e\n       \u003cprovides\u003e\n         \u003cversion\u003e21\u003c/version\u003e\n         \u003cvendor\u003edefault\u003c/vendor\u003e\n       \u003c/provides\u003e\n       \u003cconfiguration\u003e\n         \u003cjdkHome\u003e[PATH_TO_YOUR_JDK_21]\u003c/jdkHome\u003e\n       \u003c/configuration\u003e\n     \u003c/toolchain\u003e\n   \u003c/toolchains\u003e\n   ```\n\n   Set the `[PATH_TO_YOUR_JDK_11]`/`[PATH_TO_YOUR_JDK_17]`/`[PATH_TO_YOUR_JDK_21]` parameters accordingly\n   to where you installed the JDKs.\n\n1. Checkout the code, e.g. using:\n\n    - `git clone https://github.com/vegardit/no-npe`\n\n1. Run `mvn clean verify` in the project root directory. This will execute compilation, unit-testing, integration-testing and\n   packaging of all artifacts.\n\n\n### \u003ca name=\"validate_update\"\u003e\u003c/a\u003eValidating/Updating EEA files\n\nThe EEA files can be validated/updated using:\n\n```bash\n# validate all EEA files of all eea-* modules\nmvn compile\n\n# validate all EEA files of a specific module\nmvn compile -am -pl \u003cMODULE_NAME\u003e\nmvn compile -am -pl libs/eea-commons-io-2\n\n# update/regenerate all EEA files of all eea-* modules\nmvn compile -Deea-generator.action=generate\n\n# update/regenerate all EEA files of a specific module\nmvn compile -Deea-generator.action=generate -am -pl \u003cMODULE_NAME\u003e\nmvn compile -Deea-generator.action=generate -am -pl libs/eea-commons-io-2\n```\n\nUpdating EEA files will:\n- add new types/fields/methods found\n- remove obsolete declarations from the EEA files\n- preserve null/non-null annotations specified for existing fields/methods\n\n\n### \u003ca name=\"new_module\"\u003e\u003c/a\u003eAdding a new Maven module\n\n1. Create a new sub-directory under `libs/` using the name pattern `eea-[LIBRARY_NAME]-[LIBRARY_MAJOR_VERSION|latest]`\n\n1. Create a pom.xml in the new directory like this:\n\n    ```xml\n    \u003c?xml version=\"1.0\"?\u003e\n    \u003cproject xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n      xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n\n      \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n\n      \u003cparent\u003e\n        \u003cgroupId\u003ecom.vegardit.no-npe\u003c/groupId\u003e\n        \u003cartifactId\u003eno-npe-parent\u003c/artifactId\u003e\n        \u003cversion\u003e[CURRENT_SNAPSHOT_VERSION]\u003c/version\u003e\n      \u003c/parent\u003e\n\n      \u003cartifactId\u003eno-npe-eea-[LIBRARY_NAME]-[LIBRARY_MAJOR_VERSION]\u003c/artifactId\u003e\n\n      \u003cdependencies\u003e\n        \u003cdependency\u003e\n          \u003cgroupId\u003e[LIBRARY_GROUP_ID]\u003c/groupId\u003e\n          \u003cartifactId\u003e[LIBRARY_ARTIFACT_ID]\u003c/artifactId\u003e\n          \u003cversion\u003e[LIBRARY_VERSION]\u003c/version\u003e\n          \u003cscope\u003eprovided\u003c/scope\u003e\n        \u003c/dependency\u003e\n      \u003c/dependencies\u003e\n    \u003c/project\u003e\n    ```\n\n    For example:\n\n    ```xml\n    \u003c?xml version=\"1.0\"?\u003e\n    \u003cproject xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n      xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd\"\u003e\n\n      \u003cmodelVersion\u003e4.0.0\u003c/modelVersion\u003e\n\n      \u003cparent\u003e\n        \u003cgroupId\u003ecom.vegardit.no-npe\u003c/groupId\u003e\n        \u003cartifactId\u003eno-npe-parent\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.0-SNAPSHOT\u003c/version\u003e\n      \u003c/parent\u003e\n\n      \u003cartifactId\u003eno-npe-eea-cool-library4\u003c/artifactId\u003e\n\n      \u003cdependencies\u003e\n        \u003cdependency\u003e\n          \u003cgroupId\u003eorg.example.cool-library\u003c/groupId\u003e\n          \u003cartifactId\u003ecool-library\u003c/artifactId\u003e\n          \u003cversion\u003e2.0.2\u003c/version\u003e\n          \u003cscope\u003eprovided\u003c/scope\u003e\n        \u003c/dependency\u003e\n      \u003c/dependencies\u003e\n    \u003c/project\u003e\n    ```\n\n1. Add an eea-generator.properties file in the same directory where you specify the relevant packages of the library.\n\n   ```properties\n   packages.include=package1,package2\n   ```\n\n   E.g.\n\n   ```properties\n   packages.include=org.example.cool-library.api,org.example.cool-library.spi\n   ```\n\n   The following options are available:\n   |name|description|default|\n   |-|-|-|\n   |`packages.include`| The comma separated packages to recursively scan for class files| n/a\n   |`classes.exclude`| A comma separated list of regex patterns that are matched against fully qualified class names to exclude them from scanning| n/a\n   |`action`| The default action (`validate` or `generate` to perform during `mvn compile`) | `validate`\n   |`output.dir`| Path to the root directory containing the .eea files. Used for validation and generation.| `src/main/resources`\n   |`input.dirs`| Comma separated additional paths of root directories containing .eea files to read null annotations from on `generate`.| n/a\n   |`omitRedundantAnnotatedSignatures`| If `true` lines with annotated signatures are not written to the file if they don't contain any null annotations | `false`\n\n   These options can also be specified in the command line as system properties like `-Deea-generator.\u003cOPTION_NAME\u003e=`,\n   e.g. `-Deea-generator.omitRedundantAnnotatedSignatures=true`\n\n1. In the parent project's pom.xml file reference the module in the `\u003cmodules\u003e` section.\n\n1. Run the generator in the parent project to create the EEA files\n\n   ```bash\n   mvn compile -Deea-generator.action=generate -am -pl \u003cMODULE_NAME\u003e\n   ```\n\n   E.g.\n\n   ```bash\n   mvn compile -Deea-generator.action=generate -am -pl libs/eea-cool-library-2\n   ```\n\n1. Manually add missing null/non-null annotations in the generated EEA files under `src/main/resources`\n\n\n## \u003ca name=\"acknowledgement\"\u003e\u003c/a\u003eAcknowledgement\n\n**No NPE!** was created by [Sebastian Thomschke](https://sebthom.de) and is sponsored by [Vegard IT GmbH](https://www.vegardit.com).\n\nCreation of this project was inspired by https://github.com/lastnpe/eclipse-null-eea-augments/ but a different approach in\ngenerating/packaging/validating of EEA files/archives has been taken.\n\n**No NPE!** would not have been possible in its current form without the following technologies and learning resources:\n\n**Technologies/Libraries**\n- [ClassGraph](https://github.com/classgraph/classgraph) - fast Java classpath scanner\n- [gmavenplus-plugin](https://groovy.github.io/GMavenPlus/) - Maven plugin to execute arbitrary Groovy code during Maven lifecycle phases\n- [exec-maven-plugin](https://www.mojohaus.org/exec-maven-plugin/) - toolchain aware Maven plugin to execute custom Java code during Maven lifecycle phases\n- [AssertJ](https://github.com/assertj/assertj) - strongly-typed assertions for unit testing\n\n**Tutorials**\n- Null Analysis/External Annotations https://wiki.eclipse.org/JDT_Core/Null_Analysis/External_Annotations\n- Using external null annotations https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_external_null_annotations.htm\n- Type Signature Syntax https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.isv/reference/api/org/eclipse/jdt/core/Signature.html\n- 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\n- Field Descriptors https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.3.2\n\n\n## \u003ca name=\"license\"\u003e\u003c/a\u003eLicense\n\nAll files are released under the [Eclipse Public License 2.0](LICENSE.txt).\n\nIndividual files contain the following tag instead of the full license text:\n```\nSPDX-License-Identifier: EPL-2.0\n```\n\nThis enables machine processing of license information based on the SPDX License Identifiers that are available here: https://spdx.org/licenses/.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvegardit%2Fno-npe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvegardit%2Fno-npe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvegardit%2Fno-npe/lists"}