{"id":27595712,"url":"https://github.com/harmonysoft-tech/traute","last_synced_at":"2025-04-22T12:17:13.548Z","repository":{"id":57743174,"uuid":"106991939","full_name":"harmonysoft-tech/traute","owner":"harmonysoft-tech","description":"Enhances java sources compilation in a way to insert null-checks into generated *.class files","archived":false,"fork":false,"pushed_at":"2019-03-30T21:39:29.000Z","size":2621,"stargazers_count":28,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-22T12:16:49.640Z","etag":null,"topics":["instrumentation","java","java-8","javac","javacompiler","notnull"],"latest_commit_sha":null,"homepage":"http://traute.oss.harmonysoft.tech/","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/harmonysoft-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-15T07:20:55.000Z","updated_at":"2024-10-28T12:19:14.000Z","dependencies_parsed_at":"2022-09-12T08:04:24.197Z","dependency_job_id":null,"html_url":"https://github.com/harmonysoft-tech/traute","commit_stats":null,"previous_names":["harmonhsoft-tech/traute","harmonysoft-tech/traute"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Ftraute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Ftraute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Ftraute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/harmonysoft-tech%2Ftraute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/harmonysoft-tech","download_url":"https://codeload.github.com/harmonysoft-tech/traute/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250237842,"owners_count":21397403,"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":["instrumentation","java","java-8","javac","javacompiler","notnull"],"created_at":"2025-04-22T12:17:12.477Z","updated_at":"2025-04-22T12:17:13.529Z","avatar_url":"https://github.com/harmonysoft-tech.png","language":"Java","funding_links":["https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=3GJDPN3TH8T48\u0026lc=RU\u0026item_name=Traute\u0026currency_code=USD\u0026bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/denis-zhdanov/traute.svg?branch=master)](https://travis-ci.org/denis-zhdanov/traute)\n[![Maven Central](https://img.shields.io/maven-metadata/v/http/central.maven.org/maven2/tech/harmonysoft/traute-javac/maven-metadata.xml.svg)](https://img.shields.io/maven-metadata/v/http/central.maven.org/maven2/tech/harmonysoft/traute-javac/maven-metadata.xml.svg)\n\n## TL;DR\n\n*Traute* is a *javac* plugin which makes bytecode for source code below  \n\n```java\n@NotNull\npublic Integer service(@NotNull Integer i) {\n    return adjust(i);\n}\n```  \n\nlook like if it's compiled from this:  \n\n```java\n@NotNull\npublic Integer service(@NotNull Integer i) {\n    if (i == null) {\n        throw new NullPointerException(\"Argument 'i' of type Integer (#0 out of 1, zero-based) is marked by @NotNull but got null for it\");\n    }\n    Integer tmpVar1 = adjust(i);\n    if (tmpVar1 == null) {\n        throw new NullPointerException(\"Detected an attempt to return null from method MyClass.service() marked by @NotNull\");\n    }\n    return tmpVar1;\n}\n```  \n\nCouple of notes:\n* this is default behavior, the plugin provides a number of [configuration options](core/javac/README.md#7-settings) like an ability to define exception to throw, customize its text etc\n* explicitly marking all target method parameters/return types by *@NotNull* might be tedious, so, the plugin can be configured to consider them to be not-*null* by default - see the [NotNullByDefault](core/javac/README.md#72-notnullbydefault-annotations) and [Nullable](core/javac/README.md#73-nullable-annotations)\n\n## Table of Contents\n\n* [1. License](#1-license)\n* [2. Rationale](#2-rationale)\n* [3. Alternatives](#3-alternatives)\n* [4. Name Choice](#4-name-choice)\n* [5. Usage](#5-usage)\n  * [5.1. Command Line](#51-command-line)\n  * [5.2. Gradle](#52-gradle)\n  * [5.3. Maven](#53-maven)\n  * [5.4. Ant](#54-ant)\n* [6. Releases](#6-releases)\n* [7. How to Contribute](#7-how-to-contribute)\n* [8. Contributors](#8-contributors)\n* [9. Evolution](#9-evolution)\n* [10. Feedback](#10-feedback)\n* [11. Acknowledgments](#11-acknowledgments)\n\n## 1. License\n\nSee the [LICENSE](LICENSE.md) file for license rights and limitations (MIT).\n\n## 2. Rationale\n\nNull references are [considered](https://en.wikipedia.org/wiki/Null_pointer#History) to be one of the most expensive mistakes in IT design. It's not surprising that there are numerous efforts to solve it. Here are a couple of examples from the *Java* world:\n* [*Kotlin*](https://kotlinlang.org/) fights them at the [language level](https://kotlinlang.org/docs/reference/null-safety.html)\n* many tools try to report it as early as possible, for example, here [*IntelliJ IDEA*](https://www.jetbrains.com/idea/) warns us about a possible *NPE*: \n\n  \u003cimg src=\"/docs/img/warning-intellij.png\" height=\"100px\"\u003e\n\n* production code often looks like below:\n\n  ```java\n  import static com.google.common.base.Preconditions.checkNotNull;\n\n  ...\n\n  public void service(Input input) {\n    checkNotNull(input, \"'input' argument must not be null\");\n    // Process the input\n  }\n  ```\n\n*Kotlin* really solves the problem but *Java* is still a very popular language, so, we have to deal with nullable values. Current tool allows to automate such 'enforce nullability contract' checks generation.\n\n## 3. Alternatives\n\nI found the only alternative which provides similar functionality - [*Project Lombok*](https://projectlombok.org/features/NonNull). Here are pros and cons for using it:\n* only [*lombok.NonNull*](https://projectlombok.org/api/lombok/NonNull.html) annotation is supported - there might be problems with *IDE* highlighting possible *NPE*s in source code\n* the feature is implemented through a custom [*Annotaton Processing Tool*](https://docs.oracle.com/javase/7/docs/technotes/guides/apt/index.html), which means that there are two set of *\\*.class* files after the compilation - one from original code and another one with the tool-added instrumentations. Compiler plugin-based approach is more natural for such task as it's completely transparent for the further assembly construction\n* *Lombok* doesn't support [NotNullByDefault](core/javac/README.md#72-notnullbydefault-annotations)\n* a solution offered by the current project [works only for the javac8](core/javac/README.md#5-limitations), *Lombok* might operate with *javac6* and *javac7* (as *APT API* is available starting from *java6*, however, I have not verified that)\n* *Lombok* is more mature and popular at the moment\n\n## 4. Name Choice\n\nI really like German - how it sounds, language rules, everything, so, wanted to use a german word.  \n\n*Traute* sounds nice and has a good [meaning](http://dictionary.reverso.net/german-english/Traute) - *Trust*. Users trust the tool and the tool enforces trust in application :wink:\n\n## 5. Usage\n\n### 5.1. Command Line\n\nThe core functionality is a [*Javac* plugin](core/javac/README.md) which adds *null*-checks into the generated *\\*.class* files. It's possible to [use the plugin directly](core/javac/README.md#6-usage) from a command line, however, there are a number of adapters for popular build systems\n\n### 5.2. Gradle\n\nThere is a [dedicated Traute plugin](facade/gradle/README.md#3-usage) for the [Gradle](https://gradle.org/) build system\n\n### 5.3. Maven\n\n[This page](facade/maven/README.md#3-usage) contains instructions on how to use *Traute* from [Maven](http://maven.apache.org/)\n\n### 5.4. Ant\n\n[This page](facade/ant/README.md#3-sample) contains instructions on how to use *Traute* from [Ant](https://ant.apache.org/)\n\n## 6. Releases\n\n[Release Notes](RELEASE.md)\n\n*Javac Plugin*  \n\u003ca href='https://bintray.com/bintray/jcenter/tech.harmonysoft%3Atraute-javac?source=watch' alt='Get automatic notifications about new \"tech.harmonysoft:traute-javac\" versions'\u003e\u003cimg src='https://www.bintray.com/docs/images/bintray_badge_color.png'\u003e\u003c/a\u003e\n\n*Gradle Plugin*  \n\n\u003ca href='https://bintray.com/denis-zhdanov/harmonysoft.tech/traute-gradle?source=watch' alt='Get automatic notifications about new \"traute-gradle\" versions'\u003e\u003cimg src='https://www.bintray.com/docs/images/bintray_badge_color.png'\u003e\u003c/a\u003e\n\nYou can also subscribe for the new versions notification through [twitter](https://twitter.com/traute_java) and [facebook](https://www.facebook.com/java.traute/).\n\n## 7. How to Contribute\n\n* [report a problem/ask for enhancement](https://github.com/denis-zhdanov/traute/issues)\n* [submit a pull request](https://github.com/denis-zhdanov/traute/pulls)\n* help me to make small presents to my wife in order to persuade her that spending free time on *OSS* might be not the worst idea :yum: [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=3GJDPN3TH8T48\u0026lc=RU\u0026item_name=Traute\u0026currency_code=USD\u0026bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)\n\n## 8. Contributors\n\n* [Denis Zhdanov](https://github.com/denis-zhdanov)\n\n## 9. Evolution\n\nAs the project is basically a [*Javac* plugin](core/javac/README.md) and convenient build system-specific adapters to it, new features should be added to the core part. Please check the [corresponding chapter](core/javac/README.md#8-evolution).\n\n## 10. Feedback\n\nPlease use any of the channels below to provide your feedback, it's really valuable for me:\n* [email](mailto:traute.java@gmail.com)\n* [twitter](https://twitter.com/traute_java)\n* [facebook](https://www.facebook.com/java.traute/)\n\n## 11. Acknowledgments\n\n\u003cimg src=\"/docs/img/intellij.png\" height=\"70px\"\u003e\n\n[JetBrains](https://www.jetbrains.com/) helps open source projects by offering free licenses to their awesome products. \n\n![yourkit](https://www.yourkit.com/images/yklogo.png) \n\nYourKit supports open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of \u003ca href=\"https://www.yourkit.com/java/profiler/\"\u003eYourKit Java Profiler\u003c/a\u003e\nand \u003ca href=\"https://www.yourkit.com/.net/profiler/\"\u003eYourKit .NET Profiler\u003c/a\u003e,\ninnovative and intelligent tools for profiling Java and .NET applications.  \n\n![jprofiler](https://www.ej-technologies.com/images/product_banners/jprofiler_large.png)  \n\nEJ Technologies supports open source projects by offering a [JProfiler Java profiler](https://www.ej-technologies.com/products/jprofiler/overview.html) license.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharmonysoft-tech%2Ftraute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fharmonysoft-tech%2Ftraute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fharmonysoft-tech%2Ftraute/lists"}