{"id":23051026,"url":"https://github.com/xzel23/cabe","last_synced_at":"2026-01-25T19:18:59.014Z","repository":{"id":55061268,"uuid":"425756458","full_name":"xzel23/cabe","owner":"xzel23","description":"Inject null-checks into Java-code","archived":false,"fork":false,"pushed_at":"2024-11-29T13:46:52.000Z","size":1174,"stargazers_count":12,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-12-12T06:50:22.482Z","etag":null,"topics":["bytecode","instrumentation","java","jspecify","null-check","null-safe","nullability"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xzel23.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2021-11-08T08:32:40.000Z","updated_at":"2024-12-01T18:34:17.000Z","dependencies_parsed_at":"2023-12-19T14:26:10.706Z","dependency_job_id":"748c263c-df03-472d-a0a0-a12fb41a600a","html_url":"https://github.com/xzel23/cabe","commit_stats":null,"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xzel23%2Fcabe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xzel23%2Fcabe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xzel23%2Fcabe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xzel23%2Fcabe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xzel23","download_url":"https://codeload.github.com/xzel23/cabe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229890093,"owners_count":18140042,"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":["bytecode","instrumentation","java","jspecify","null-check","null-safe","nullability"],"created_at":"2024-12-15T23:44:16.653Z","updated_at":"2026-01-25T19:18:59.006Z","avatar_url":"https://github.com/xzel23.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Cabe [![MIT License](https://img.shields.io/badge/license-MIT-blue)](LICENSE) [![Language](https://img.shields.io/badge/language-Java-blue.svg?style=flat-square)](https://github.com/topics/java)\n====\n\nA bytecode instrumentation tool that inserts null checks based on JSpecify annotations.\n\n## TLDR\n\nAdd this to the Gradle build file of your project that uses JSpecify annotations to add automatic null-checks to the public API of your project and assertion based\nnull checks to the private API:\n\n```kotlin\nplugins {\n    id(\"com.dua3.cabe\") version \"3.3.0\"\n}\n```\n\n## Introduction\n\nCabe helps implement the [Fail-Fast Principle](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) by automatically adding runtime checks for annotated method parameters. This provides several benefits:\n\n- **Early Detection**: Violations of nullability contracts are detected immediately at the point of violation\n- **Improved Debugging**: Clear error messages that identify the exact parameter that violated the contract\n- **Reduced Boilerplate**: No need to manually write null checks for annotated parameters\n- **Consistent Enforcement**: Ensures that nullability contracts are enforced consistently across your codebase\n\n## Usage\n\n### Gradle\n\n1. Add the plugin to your build script:\n\n```kotlin\nplugins {\n    id(\"java\")\n    id(\"com.dua3.cabe\") version \"3.3.0\"\n}\n```\n\n2. Add JSpecify dependency:\n\n```kotlin\ndependencies {\n    implementation(\"org.jspecify:jspecify:1.0.0\")\n}\n```\n\n3. Add JSpecify annotations to your code.\n\n### Maven\n\n1. Add the plugin to your POM:\n\n```xml\n\u003cbuild\u003e\n  \u003cplugins\u003e\n    \u003cplugin\u003e\n      \u003cgroupId\u003ecom.dua3.cabe\u003c/groupId\u003e\n      \u003cartifactId\u003ecabe-maven-plugin\u003c/artifactId\u003e\n      \u003cversion\u003e3.3.0\u003c/version\u003e\n      \u003cexecutions\u003e\n        \u003cexecution\u003e\n          \u003cgoals\u003e\n            \u003cgoal\u003ecabe\u003c/goal\u003e\n          \u003c/goals\u003e\n        \u003c/execution\u003e\n      \u003c/executions\u003e\n    \u003c/plugin\u003e\n  \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n2. Configure the compiler to use a separate output directory:\n\n```xml\n\u003cplugin\u003e\n  \u003cgroupId\u003eorg.apache.maven.plugins\u003c/groupId\u003e\n  \u003cartifactId\u003emaven-compiler-plugin\u003c/artifactId\u003e\n  \u003cversion\u003e3.13.0\u003c/version\u003e\n  \u003cexecutions\u003e\n    \u003cexecution\u003e\n      \u003cid\u003edefault-compile\u003c/id\u003e\n      \u003cconfiguration\u003e\n        \u003ccompilerArguments\u003e\n          \u003cd\u003e${project.build.directory}/unprocessed-classes\u003c/d\u003e\n        \u003c/compilerArguments\u003e\n      \u003c/configuration\u003e\n    \u003c/execution\u003e\n  \u003c/executions\u003e\n\u003c/plugin\u003e\n```\n\n3. Configure the Cabe plugin:\n\n```xml\n\u003cplugin\u003e\n  \u003cgroupId\u003ecom.dua3.cabe\u003c/groupId\u003e\n  \u003cartifactId\u003ecabe-maven-plugin\u003c/artifactId\u003e\n  \u003cversion\u003e3.3.0\u003c/version\u003e\n  \u003cconfiguration\u003e\n    \u003cinputDirectory\u003e${project.build.directory}/unprocessed-classes\u003c/inputDirectory\u003e\n    \u003cverbosity\u003e1\u003c/verbosity\u003e\n    \u003cconfigurationString\u003eSTANDARD\u003c/configurationString\u003e\n  \u003c/configuration\u003e\n  \u003cexecutions\u003e\n    \u003cexecution\u003e\n      \u003cgoals\u003e\n        \u003cgoal\u003ecabe\u003c/goal\u003e\n      \u003c/goals\u003e\n    \u003c/execution\u003e\n  \u003c/executions\u003e\n\u003c/plugin\u003e\n```\n\n4. Add JSpecify dependency:\n\n```xml\n\u003cdependencies\u003e\n  \u003cdependency\u003e\n    \u003cgroupId\u003eorg.jspecify\u003c/groupId\u003e\n    \u003cartifactId\u003ejspecify\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n  \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n5. Add JSpecify annotations to your code.\n\n## Building from Source\n\nTo build Cabe from source, use the provided `build.sh` script:\n\n```bash\n./build.sh\n```\n\nThis script automatically:\n1. Builds the project\n2. Runs processor and plugin tests\n3. Publishes artifacts to the local Maven repository\n4. Tests the Gradle plugin\n5. Builds example projects\n\nThe script ensures that all components work correctly together and is the recommended way to build the project.\n\n## Documentation\n\nFor detailed documentation, including configuration options, advanced usage, and examples, please refer to:\n\n- [Cabe Documentation](https://xzel23.github.io/cabe/cabe.html)\n- [JSpecify Project](https://jspecify.dev/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxzel23%2Fcabe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxzel23%2Fcabe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxzel23%2Fcabe/lists"}