Override Java method return type nullability

I’d like to override specific method of Java class (from Spring):

protected Message<?> doReceive(long timeout) { /* ... */ }

This method might return null (it lacks @Nullable annotation though).
There is how it looks in Kotlin:

override fun doReceive(timeout: Long): Message<*> {
    val received = super.doReceive(timeout)
    /* some logic */
    return received
}

Compiler doesn’t allow return type of override fun to be Message<*>?, however to maintain logic of how this sub-class is used by Spring, sometimes (when super-class method returns null) null value should be returned from this method.
Currently, it throws IllegalStateException on such super.doReceive calls

What can be done to achieve it? There is no easy way to modify Java source.

1 Like

I created the same topic earlier.

Short idea - work with these methods described in Platform Type spec.

1 Like

I checked this page before. There is no solution to the issue - compiler still doesn’t allow to make return type of overridden method nullable.
Things are even more complicated by the fact, that Kotlin class, inherited from Java class, then used in Java code.
receivedType

1 Like

I ve managed to get received type to be Message<*>! by disabling -Xjsr305=strict

Update:
Now it compiles, but throws Caused by: java.lang.IllegalStateException: received must not be null on return received in runtime

1 Like

Good news, after disabling -Xjsr305=strict (which, AFAIK was set up by Spring Initializr as default),
I’m able to change signature of overridden method:

override fun doReceive(timeout: Long): Message<*>? {
    val received = super.doReceive(timeout)
    /* some logic */
    return received
}

Now received is platform-type Message<*>! and it works. However disabling strict mode is questionable solution.

Spring uses @Nullable for everything nullable, and uses @NonNullApi to indicate that everything else is not nullable. -Xjsr305=strict is what makes Kotlin read the latter. If you see anything from Spring which is incorrectly typed as not null in Kotlin, then it is probably a bug. In this particular case, is this the method in question? Which version of Spring Integration are you using? As far as I can see, the @Nullable annotation was added in v5.0.8

1 Like

I use QueueChannel, which is subclass of AbstractPollableChannel, v5.1.4
QueueChannel itself doesn’t have @Nullable on its doReceive, whilst in @Nullable description it is said that

Methods override should repeat parent @Nullable annotations unless they behave differently.

Sounds like a bug in Spring Integration core. I guess I should raise pull request that adds @Nullable in QueueChannel.

Just delete the type of the function and it should work.

Doesn’t work that way.

As told previously, it already works without -Xjsr305=strict

Sorry, I thought you where delegating the method to a Java one so that it would have inferred a T! type or similar.