Runtime verification of notnull

I have some suggestions for runtime verification of notnull.

I think it should be a compiler option but it should also be an annotation per
class or method.

@NullChecked public void method(@NotNull String x) { .. }

Also, the assertion message should definitely say the name of the parameter, and
the parameter index should start from 1, not 0.

11 comments

@NullChecked public void method(@NotNull String x) { .. }


Hmm, even though I have no particular strong feelings about this, I think such a compiler
instruction should not be part of the source code. We don't want to end up with this
proprietary "#pragma something" stuff, do we?

I think it's similar to the assert statement as there's also no @ReallyAssert annotation
that enables assertions even if the JVM hasn't been started with -ea. Just a thought.

Sascha

0

Sascha Weinreuter wrote:

>> @NullChecked public void method(@NotNull String x) { .. }


Hmm, even though I have no particular strong feelings about this, I
think such a compiler instruction should not be part of the source code.
We don't want to end up with this proprietary "#pragma something" stuff,
do we?

I think it's similar to the assert statement as there's also no
@ReallyAssert annotation that enables assertions even if the JVM hasn't
been started with -ea. Just a thought.


Sascha, I think either all annotations should be checked at runtime, and thus
controlled by -ea, or there should be a way to specify that they're checked at
runtime. To me it is unacceptable that the semantics of my program, including
whether my classes follow their specified contract or not, depends on a checkbox.

I think maybe a better solution would be to automatically insert null checks as
assertions, and provide a checkbox to allow them to be actual runtime checks
regardless of assertion status.

Nullness is very important to me and I think it needs to be treated with
priority and strictness.

0

Keith,

I have already implemented @NotNull runtime assertions in Demetra. The
generation is indeed controlled by the compiler option. Enabling assertions
with -ea only is on my radar, and will be implemented really soon. Still I
don't see the reason to clutter the code with additional @NullChecked
annotations.

Eugene.

P.S. the checks are inserted not only to check the parameter notnullness but
return values of the @NotNull marked methods as well.
P.P.S. We have already caught several potential NPEs, and even more method
return @NotNull contract violations with the help of runtime verification.

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dm81d3$o0v$1@is.intellij.net...

I have some suggestions for runtime verification of notnull.

>

I think it should be a compiler option but it should also be an annotation

per

class or method.

>

@NullChecked public void method(@NotNull String x) { .. }

>

Also, the assertion message should definitely say the name of the

parameter, and

the parameter index should start from 1, not 0.



0

Eugene Vigdorchik (JetBrains) wrote:
> Keith,
>
> I have already implemented @NotNull runtime assertions in Demetra. The
> generation is indeed controlled by the compiler option. Enabling assertions
> with -ea only is on my radar, and will be implemented really soon. Still I
> don't see the reason to clutter the code with additional @NullChecked
> annotations.

I think @NullChecked is a small price to pay for concise, declarative nullness
constraints. I think @NullChecked for an entire class or package is much less
clutter than "if (x == null) { throw new IllegalArgumentException("Argument 'x'
cannot be null"); }" for every nonnull parameter.

Can you imagine if the security classes in the JDK were developed using only
assert-based constraint checks? The JDK would probably not be secure from
attacks except in -ea mode. I think all of the world's code could be more secure
and function more correctly in the presence of such annotations which are
converted to solid (non-assert) runtime checks.

Eugene.

P.S. the checks are inserted not only to check the parameter notnullness but
return values of the @NotNull marked methods as well.


How about notnull local variables?

0

Now, I'm starting to doubt if we understand each other correctly:
When I talk of not null assertions, I mean those will be inserted
automatically by idea instrumenting your classes.
And yes, to my mind such automatic insertion is indeed a part of @NotNull
contract.


"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dma6qu$s29$1@is.intellij.net...

Eugene Vigdorchik (JetBrains) wrote:
> Keith,
>
> I have already implemented @NotNull runtime assertions in Demetra. The
> generation is indeed controlled by the compiler option. Enabling

assertions

> with -ea only is on my radar, and will be implemented really soon.

Still I

> don't see the reason to clutter the code with additional @NullChecked
> annotations.

>

I think @NullChecked is a small price to pay for concise, declarative

nullness

constraints. I think @NullChecked for an entire class or package is much

less

clutter than "if (x == null) { throw new

IllegalArgumentException("Argument 'x'

cannot be null"); }" for every nonnull parameter.

>

Can you imagine if the security classes in the JDK were developed using

only

assert-based constraint checks? The JDK would probably not be secure from
attacks except in -ea mode. I think all of the world's code could be more

secure

and function more correctly in the presence of such annotations which are
converted to solid (non-assert) runtime checks.

>

Eugene.

>

P.S. the checks are inserted not only to check the parameter notnullness

but

return values of the @NotNull marked methods as well.

>

How about notnull local variables?



0

I believe we understand each other correctly. The problem is that they are based
on assert, which is disabled by default, so contracts are not upheld by default.

Eugene Vigdorchik (JetBrains) wrote:

Now, I'm starting to doubt if we understand each other correctly:
When I talk of not null assertions, I mean those will be inserted
automatically by idea instrumenting your classes.
And yes, to my mind such automatic insertion is indeed a part of @NotNull
contract.


"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dma6qu$s29$1@is.intellij.net...

>>Eugene Vigdorchik (JetBrains) wrote:
>> > Keith,
>> >
>> > I have already implemented @NotNull runtime assertions in Demetra. The
>> > generation is indeed controlled by the compiler option. Enabling


assertions

>> > with -ea only is on my radar, and will be implemented really soon.


Still I

>> > don't see the reason to clutter the code with additional @NullChecked
>> > annotations.
>>
>>I think @NullChecked is a small price to pay for concise, declarative


nullness

>>constraints. I think @NullChecked for an entire class or package is much


less

>>clutter than "if (x == null) { throw new


IllegalArgumentException("Argument 'x'

>>cannot be null"); }" for every nonnull parameter.
>>
>>Can you imagine if the security classes in the JDK were developed using


only

>>assert-based constraint checks? The JDK would probably not be secure from
>>attacks except in -ea mode. I think all of the world's code could be more


secure

>>and function more correctly in the presence of such annotations which are
>>converted to solid (non-assert) runtime checks.
>>
>>
>>>Eugene.
>>>
>>>P.S. the checks are inserted not only to check the parameter notnullness


but

>>>return values of the @NotNull marked methods as well.
>>
>>How about notnull local variables?


0

As for now they are not based on assert, I just generate bytecode for
conditional throw AssertionError.
There was however a request to me made by Max to enable those only
with -ea.Still this could be a subject for discussion.

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dmaba2$lo1$1@is.intellij.net...

I believe we understand each other correctly. The problem is that they are

based

on assert, which is disabled by default, so contracts are not upheld by

default.
>

Eugene Vigdorchik (JetBrains) wrote:

Now, I'm starting to doubt if we understand each other correctly:
When I talk of not null assertions, I mean those will be inserted
automatically by idea instrumenting your classes.
And yes, to my mind such automatic insertion is indeed a part of

@NotNull

contract.

>
>

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dma6qu$s29$1@is.intellij.net...

>
>>Eugene Vigdorchik (JetBrains) wrote:
>> > Keith,
>> >
>> > I have already implemented @NotNull runtime assertions in Demetra.

The

>> > generation is indeed controlled by the compiler option. Enabling
>

assertions

>
>> > with -ea only is on my radar, and will be implemented really soon.
>

Still I

>
>> > don't see the reason to clutter the code with additional @NullChecked
>> > annotations.
>>
>>I think @NullChecked is a small price to pay for concise, declarative
>

nullness

>
>>constraints. I think @NullChecked for an entire class or package is

much

>

less

>
>>clutter than "if (x == null) { throw new
>

IllegalArgumentException("Argument 'x'

>
>>cannot be null"); }" for every nonnull parameter.
>>
>>Can you imagine if the security classes in the JDK were developed using
>

only

>
>>assert-based constraint checks? The JDK would probably not be secure

from

>>attacks except in -ea mode. I think all of the world's code could be

more

>

secure

>
>>and function more correctly in the presence of such annotations which

are

>>converted to solid (non-assert) runtime checks.
>>
>>
>>>Eugene.
>>>
>>>P.S. the checks are inserted not only to check the parameter

notnullness

>

but

>
>>>return values of the @NotNull marked methods as well.
>>
>>How about notnull local variables?
>
>
>



0

I assumed because of AssertionError that it was based on assertion. I think
IllegalArgumentException makes a lot more sense than AssertionError.

Eugene Vigdorchik (JetBrains) wrote:

As for now they are not based on assert, I just generate bytecode for
conditional throw AssertionError.
There was however a request to me made by Max to enable those only
with -ea.Still this could be a subject for discussion.

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dmaba2$lo1$1@is.intellij.net...

>>I believe we understand each other correctly. The problem is that they are


based

>>on assert, which is disabled by default, so contracts are not upheld by


default.

>>Eugene Vigdorchik (JetBrains) wrote:
>>
>>>Now, I'm starting to doubt if we understand each other correctly:
>>>When I talk of not null assertions, I mean those will be inserted
>>>automatically by idea instrumenting your classes.
>>>And yes, to my mind such automatic insertion is indeed a part of


@NotNull

>>>contract.
>>>
>>>
>>>"Keith Lea" <keith@cs.oswego.edu> wrote in message
>>>news:dma6qu$s29$1@is.intellij.net...
>>>
>>>
>>>>Eugene Vigdorchik (JetBrains) wrote:
>>>>
>>>>>Keith,
>>>>>
>>>>>I have already implemented @NotNull runtime assertions in Demetra.


The

>>>>>generation is indeed controlled by the compiler option. Enabling
>>>
>>>assertions
>>>
>>>
>>>>>with -ea only is on my radar, and will be implemented really soon.
>>>
>>>Still I
>>>
>>>
>>>>>don't see the reason to clutter the code with additional @NullChecked
>>>>>annotations.
>>>>
>>>>I think @NullChecked is a small price to pay for concise, declarative
>>>
>>>nullness
>>>
>>>
>>>>constraints. I think @NullChecked for an entire class or package is


much

>>>less
>>>
>>>
>>>>clutter than "if (x == null) { throw new
>>>
>>>IllegalArgumentException("Argument 'x'
>>>
>>>
>>>>cannot be null"); }" for every nonnull parameter.
>>>>
>>>>Can you imagine if the security classes in the JDK were developed using
>>>
>>>only
>>>
>>>
>>>>assert-based constraint checks? The JDK would probably not be secure


from

>>>>attacks except in -ea mode. I think all of the world's code could be


more

>>>secure
>>>
>>>
>>>>and function more correctly in the presence of such annotations which


are

>>>>converted to solid (non-assert) runtime checks.
>>>>
>>>>
>>>>
>>>>>Eugene.
>>>>>
>>>>>P.S. the checks are inserted not only to check the parameter


notnullness

>>>but
>>>
>>>
>>>>>return values of the @NotNull marked methods as well.
>>>>
>>>>How about notnull local variables?
>>>
>>>
>>>


0

Indeed it does for parameters, I'll rework this.
But for returning null from notnull methods AssertionError seems
appropriate.

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dmagrp$n0t$1@is.intellij.net...

I assumed because of AssertionError that it was based on assertion. I

think

IllegalArgumentException makes a lot more sense than AssertionError.

>

Eugene Vigdorchik (JetBrains) wrote:

As for now they are not based on assert, I just generate bytecode for
conditional throw AssertionError.
There was however a request to me made by Max to enable those only
with -ea.Still this could be a subject for discussion.

>

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dmaba2$lo1$1@is.intellij.net...

>
>>I believe we understand each other correctly. The problem is that they

are

>

based

>
>>on assert, which is disabled by default, so contracts are not upheld by
>

default.

>
>>Eugene Vigdorchik (JetBrains) wrote:
>>
>>>Now, I'm starting to doubt if we understand each other correctly:
>>>When I talk of not null assertions, I mean those will be inserted
>>>automatically by idea instrumenting your classes.
>>>And yes, to my mind such automatic insertion is indeed a part of
>

@NotNull

>
>>>contract.
>>>
>>>
>>>"Keith Lea" <keith@cs.oswego.edu> wrote in message
>>>news:dma6qu$s29$1@is.intellij.net...
>>>
>>>
>>>>Eugene Vigdorchik (JetBrains) wrote:
>>>>
>>>>>Keith,
>>>>>
>>>>>I have already implemented @NotNull runtime assertions in Demetra.
>

The

>
>>>>>generation is indeed controlled by the compiler option. Enabling
>>>
>>>assertions
>>>
>>>
>>>>>with -ea only is on my radar, and will be implemented really soon.
>>>
>>>Still I
>>>
>>>
>>>>>don't see the reason to clutter the code with additional @NullChecked
>>>>>annotations.
>>>>
>>>>I think @NullChecked is a small price to pay for concise, declarative
>>>
>>>nullness
>>>
>>>
>>>>constraints. I think @NullChecked for an entire class or package is
>

much

>
>>>less
>>>
>>>
>>>>clutter than "if (x == null) { throw new
>>>
>>>IllegalArgumentException("Argument 'x'
>>>
>>>
>>>>cannot be null"); }" for every nonnull parameter.
>>>>
>>>>Can you imagine if the security classes in the JDK were developed

using

>>>
>>>only
>>>
>>>
>>>>assert-based constraint checks? The JDK would probably not be secure
>

from

>
>>>>attacks except in -ea mode. I think all of the world's code could be
>

more

>
>>>secure
>>>
>>>
>>>>and function more correctly in the presence of such annotations which
>

are

>
>>>>converted to solid (non-assert) runtime checks.
>>>>
>>>>
>>>>
>>>>>Eugene.
>>>>>
>>>>>P.S. the checks are inserted not only to check the parameter
>

notnullness

>
>>>but
>>>
>>>
>>>>>return values of the @NotNull marked methods as well.
>>>>
>>>>How about notnull local variables?
>>>
>>>
>>>
>
>



0

I think IllegalStateException makes more sense for returning null and for
notnull local variable being null.

Eugene Vigdorchik (JetBrains) wrote:

Indeed it does for parameters, I'll rework this.
But for returning null from notnull methods AssertionError seems
appropriate.

"Keith Lea" <keith@cs.oswego.edu> wrote in message
news:dmagrp$n0t$1@is.intellij.net...

>>I assumed because of AssertionError that it was based on assertion. I


think

>>IllegalArgumentException makes a lot more sense than AssertionError.
>>
>>Eugene Vigdorchik (JetBrains) wrote:
>>
>>>As for now they are not based on assert, I just generate bytecode for
>>>conditional throw AssertionError.
>>>There was however a request to me made by Max to enable those only
>>>with -ea.Still this could be a subject for discussion.
>>>
>>>"Keith Lea" <keith@cs.oswego.edu> wrote in message
>>>news:dmaba2$lo1$1@is.intellij.net...
>>>
>>>
>>>>I believe we understand each other correctly. The problem is that they


are

>>>based
>>>
>>>
>>>>on assert, which is disabled by default, so contracts are not upheld by
>>>
>>>default.
>>>
>>>
>>>>Eugene Vigdorchik (JetBrains) wrote:
>>>>
>>>>
>>>>>Now, I'm starting to doubt if we understand each other correctly:
>>>>>When I talk of not null assertions, I mean those will be inserted
>>>>>automatically by idea instrumenting your classes.
>>>>>And yes, to my mind such automatic insertion is indeed a part of
>>>
>>>@NotNull
>>>
>>>
>>>>>contract.
>>>>>
>>>>>
>>>>>"Keith Lea" <keith@cs.oswego.edu> wrote in message
>>>>>news:dma6qu$s29$1@is.intellij.net...
>>>>>
>>>>>
>>>>>
>>>>>>Eugene Vigdorchik (JetBrains) wrote:
>>>>>>
>>>>>>
>>>>>>>Keith,
>>>>>>>
>>>>>>>I have already implemented @NotNull runtime assertions in Demetra.
>>>
>>>The
>>>
>>>
>>>>>>>generation is indeed controlled by the compiler option. Enabling
>>>>>
>>>>>assertions
>>>>>
>>>>>
>>>>>
>>>>>>>with -ea only is on my radar, and will be implemented really soon.
>>>>>
>>>>>Still I
>>>>>
>>>>>
>>>>>
>>>>>>>don't see the reason to clutter the code with additional @NullChecked
>>>>>>>annotations.
>>>>>>
>>>>>>I think @NullChecked is a small price to pay for concise, declarative
>>>>>
>>>>>nullness
>>>>>
>>>>>
>>>>>
>>>>>>constraints. I think @NullChecked for an entire class or package is
>>>
>>>much
>>>
>>>
>>>>>less
>>>>>
>>>>>
>>>>>
>>>>>>clutter than "if (x == null) { throw new
>>>>>
>>>>>IllegalArgumentException("Argument 'x'
>>>>>
>>>>>
>>>>>
>>>>>>cannot be null"); }" for every nonnull parameter.
>>>>>>
>>>>>>Can you imagine if the security classes in the JDK were developed


using

>>>>>only
>>>>>
>>>>>
>>>>>
>>>>>>assert-based constraint checks? The JDK would probably not be secure
>>>
>>>from
>>>
>>>
>>>>>>attacks except in -ea mode. I think all of the world's code could be
>>>
>>>more
>>>
>>>
>>>>>secure
>>>>>
>>>>>
>>>>>
>>>>>>and function more correctly in the presence of such annotations which
>>>
>>>are
>>>
>>>
>>>>>>converted to solid (non-assert) runtime checks.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>Eugene.
>>>>>>>
>>>>>>>P.S. the checks are inserted not only to check the parameter
>>>
>>>notnullness
>>>
>>>
>>>>>but
>>>>>
>>>>>
>>>>>
>>>>>>>return values of the @NotNull marked methods as well.
>>>>>>
>>>>>>How about notnull local variables?
>>>>>
>>>>>
>>>>>
>>>


0

Sascha, I think either all annotations should be checked at runtime, and
thus controlled by -ea, or there should be a way to specify that they're
checked at runtime. To me it is unacceptable that the semantics of my
program, including whether my classes follow their specified contract or
not, depends on a checkbox.

I think maybe a better solution would be to automatically insert null
checks as assertions, and provide a checkbox to allow them to be actual
runtime checks regardless of assertion status.

Nullness is very important to me and I think it needs to be treated with
priority and strictness.


I think, that assertions should be used only on non public context to
prove, that assumed condition realy don't be possible to reach, and so
true runtime checking is unnesessary overhead. Also, "fail fast" means,
that obvious null pointer exceptions are not nesessary to protect by
asserts, but state saving, ie. storing null parameter to member is true
reason to use assert. That way we are saved from ugly debug session.
That described approash assumes good unit tests with full coverage.

So, when assertions start to trap, it is time to verify made
assumptions, and maybe promote assertion to true runtime error handler
because original assumption are not any more valid.

Opposite have been previously more harder to prove, that writen 'if
null' tests are not any more needed, but @NotNull annotations with
inspections help life much :)

ps. that leads to idea of inspection which warns when asserting public
methods parameters.

0

Please sign in to leave a comment.