Lombok: @NonNull implementation using checker methods instead of if statements

Created on 22 Sep 2016  路  20Comments  路  Source: projectlombok/lombok

Lombok generates an if statement in constructors for each field annotated with @NonNull.
Code coverage tools detect this as code branches to test.

It would be cool if Lombok offered an alternative implementation using a checker method like Java 8's Objects.requireNonNull(Object) or Guava's Preconditions.checkNotNull(Object).

lombok.nonNull.impl=[ if | jdk | guava ]

Or maybe just generate a vanilla private implementation of such a method ?

Most helpful comment

I'm very interested in this issue since @NonNull causes the only remaining code coverage issues in my application.

@rspilker: Would you accept a PR for this? For Java 7+ the default could be Objects.requireNonNull(Object) or we could make it configurable via a configuration property.

All 20 comments

Thinking about it now, no one cares about how you implement it, as long as it generates as few branches as possible. Objects.requireNonNull is provided by the JDK, I would go with this implementation.

Because of inlining limits, I'd prefer the implementation having the shortest bytecode. Code coverage tools should be able to ignore such branches, but I'm afraid, they are not.

As not everyone uses Guava, it can't be the only implementation. No idea about Lombok compatibility with Java <=6 and how many people still use it. I'd personally be happy with either.

It's true that Lombok may provide Java 6~7 compatibility.

Anyway it seems like JaCoCo 0.7.10+ and 0.8+ will be able to ignore Lombok generated methods altogether, making this issue obsolete :
http://www.eclemma.org/jacoco/trunk/doc/changes.html

I'll give it a try and close this issue.

@michaeltecourt Do you mean "Methods annotated with @lombok.Generated ...."? This wont always help as there's no generated method, just the added null-check for e.g., void myOwnMethod(@NonNull String s) {}.

JaCoCo would have to recognize and ignore the null-check, when @lombok.NonNull is present an the argument.

Yes I was speaking about @lombok.Generated methods, and I didn't have @NonNull on method arguments in mind, you're right :)
I only thought about the constructor/builder null checks when attributes are annotated. At least these ones will be skipped by JaCoCo.

I just rolled out Jacoco 0.8 with the newly released Sonar Java plugin 5.1 in my project. Filtering of @lombok.Generated code works perfectly. The only remaining Lombok code that is marked as uncovered are the branches generated by @NonNull.

Using Objects.requireNonNull(Object) when on Java 7+ would solve this.

Is there an update on this? I still see branches from @NonNull uncovered.

I'm very interested in this issue since @NonNull causes the only remaining code coverage issues in my application.

@rspilker: Would you accept a PR for this? For Java 7+ the default could be Objects.requireNonNull(Object) or we could make it configurable via a configuration property.

I'm very interested in this issue since @NonNull causes the only remaining code coverage issues in my application.

++

We would also be happy to see this improved.

Besides that, thanks for bringing the lombok library to us!

This would also avoid warnings about dead code and redundant null checks in Eclipse.
I'm really looking forward to seeing this implemented.

We have a plan to address this.

Currently implementing it. The javac works.

The are planning to "abuse" the current config key and add two more values:

  • Jdk: adds a call to java.util.Objects.requireNonNull(arg, "arg is marked non-null but is null")
  • Guava: adds a call to com.google.common.base.Preconditions.checkNotNull(arg, "arg is marked non-null but is null")

Currently, we scan the first lines in a method until all preconditions are checked. if (arg == null), assert arg != null were considered to be null checks.

We're expanding this to invocations to any checkNotNull or requireNonNull where the first argument is an identifier. Or any assignment where the right-hand side is such method invocation.

We still need to update some documentation.

We did create tests but did not execute exhaustive testing of the generated code. Would someone be willing to give it a try in both Eclipse and javac (maven build would be fine, you can use the snapshot repo).

This indeed works as expected for me, here's what I did.

Download the latest lombok.jar from here, and put it into the Eclipse folder as lombok.jar, with the respective path to that jar set in eclipse.ini via -javaagent:/path/to/eclipse/lombok.jar

Restarting Eclipse (it is Spring Tool Suite for me) correctly showed this then via Help > About

image

Next, I edited lombok.config in the root folder of my multi-module Spring Boot maven project to include the following key-value pair:
lombok.nonNull.exceptionType=GUAVA

After rerunning a single unit test, the respective method definitions with parameters annotated as @NonNullstill were not fully covered, but after I added @NonNull annotation to another method in the class, and rerun the tests, all was fine (maybe some caching going on somewhere, no idea).

Anyway, seems to work - thanks a lot for the fix!

Great work! I just enabled lombok.nonNull.exceptionType=JDK and my code coverage increased by nearly 3%. 馃憤

Heh, this open-forever issue is very optimistically marked 'soon'. Fortunately, this has been part of lombok for quite a while now :)

Reopening specifically for the issue of: Fix the documentation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lombokissues picture lombokissues  路  34Comments

krzyk picture krzyk  路  88Comments

xiaolongzuo picture xiaolongzuo  路  32Comments

lombokissues picture lombokissues  路  42Comments

lombokissues picture lombokissues  路  46Comments