59

I have a function with following signature

public static String myFunction(@Nonnull String param)

When I call it with param as null, I get the following exception:

Caused by: java.lang.IllegalArgumentException: Argument for @Nonnull parameter 'param' of com/MyClass.myFunction must not be null
    at com.MyClass.$$$reportNull$$$0(MyClass.java) 

javax.annotation.Nonnull supposed not to be checked at runtime.

Who actually throws the exception and why?

P.S. I run Tomcat server in debug mode from IntelliJ IDEA 2016.3 with Oracle JDK 1.8.0_102

Dmitry
  • 1,056
  • 1
  • 8
  • 17
  • Actually @Jesper, those new annotations were made to this: check things at compile time. You can check my answer.."When you compile the code, including the NonNull module at the command line, the compiler prints a warning if it detects a potential problem" – Bruno Nov 28 '16 at 15:19
  • 2
    @BrunoDM - it is runtime exception – Dmitry Nov 28 '16 at 15:25

1 Answers1

87

When you compile your project in IntelliJ IDEA, it instruments the bytecode of compiled classes to add runtime checks for various flavors of @Nonnull annotations. This behavior is controlled by the option:

Settings | Build, Execution, Deployment | Compiler | [x] Add runtime assertions for not-null-annotated methods and parameters.

Screenshot of "Add runtime assertions for notnull-annotated methods and parameters.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
yole
  • 92,896
  • 20
  • 260
  • 197
  • 1
    In what version of IDEA this feature was added? – Dmitry Nov 28 '16 at 15:30
  • 4
    This feature was added back in IntelliJ IDEA 5.0, but at that time it only supported JetBrains' `@NotNull` annotations. The support for other annotations was added recently. – yole Nov 28 '16 at 15:52
  • 47
    So, it wonderfully will compile code different than the build tool chain. That is wrong on so many levels. This can cause unit tests to fail when run from IntelliJ but pass when run via maven, for example. Perhaps the user has a null check and specific exception thrown and the unit tests validates that exception and message, but then this gets in the way. – Scott Carey Dec 29 '16 at 21:31
  • 9
    I consider it a bug. The annotation does not imply run-time checking, any build that adds runtime-checks implicitly, violates the annotation contract that there will be no runtime check. Just what were they thinking? Even worse, they made this opt-out rather than opt-in. – tkruse Mar 07 '17 at 01:45
  • 12
    he guys, if you don't like this feature, just disable it. Dealing with null values is one of the biggest pain points I experience in Java. Thanks IntelliJ for giving a hand here. – linqu Mar 09 '17 at 10:07
  • Yeah, that's like complaining about the existence of project lombok, which also modifies the AST during compilation based on annotations, even though using it is voluntary. In fact, Java's own built-in annotation mechanism is just as likely to make tests succeed or fail depending on the compilation setup. – yeoman Mar 14 '17 at 12:27
  • If your only problem is that you want the same feature in your maven / gradle build... I guess that's possible? If not, it would be a shame, because having an extra line of checks for my tests in the IDE but not on my build server would be STUPID – yeoman Mar 14 '17 at 12:29
  • 5
    is it possible to get these runtime checks in maven (without lombok)? – Jatin Apr 11 '17 at 11:40
  • Lombok is not on by default, its such a horrible idea. It makes your code look broken and your IDE usually agrees with that. – teknopaul Aug 23 '17 at 18:58
  • For @Nonnull the Retention policy is set to Runtime, `@Retention(RetentionPolicy.RUNTIME)` Does it has to do something for this ? – prime Jan 08 '18 at 11:17
  • 2
    @Jatin try https://github.com/osundblad/intellij-annotations-instrumenter-maven-plugin to get the runtime null checks in Maven. It only works with JetBrains annotations by default. – seanf Aug 10 '20 at 13:36