1

Gradle provides the following class in its API: https://docs.gradle.org/5.6.4/javadoc/org/gradle/api/tasks/ScalaRuntime.html

This class has a simple constructor which accepts a Project instance. However, in my case I don't have a Project on hand, but I still want to use other methods of this class which don't really depend on this value, so I decided to pass a null value to the constructor:

val scalaRuntime = ScalaRuntime(null)

However, the compiler fails with the following error:

Null can not be a value of a non-null type Project

I'm not sure what happens here, because clearly this is a Java class, not Kotlin, and there are no nullability annotations. How come Kotlin rejects this code? I'd assume that it would expect a value of type Project! (i.e. platform type), not a non-nullable type.

The only way to work around this now is to use reflection to invoke this constructor, which naturally works perfectly fine, so it's not like this constructor expects a truly non-nullable parameter.

What am I missing here? Why Kotlin assumes that the constructor argument is non-null?

Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296
  • I guessing here, but some of the methods are annotated with `@Nullable`, so Kotlin likely concludes that any methods without the annotation are non-nullable. – Andreas Feb 05 '20 at 06:42
  • @Andreas that's what I actually meant under "there are no nullability annotations" - there are indeed none: https://github.com/gradle/gradle/blob/v5.6.4/subprojects/scala/src/main/java/org/gradle/api/tasks/ScalaRuntime.java#L58 – Vladimir Matveev Feb 05 '20 at 08:17
  • 1
    @Andreas No, it's an annotation on the package. – Alexey Romanov Feb 05 '20 at 08:18

1 Answers1

3

The package org.gradle.api.tasks is annotated with @org.gradle.api.NonNullApi:

Marks a type or a whole package as providing a non-null API by default. All parameter and return types are assumed to be Nonnull unless specifically marked as Nullable. All types of an annotated package inherit the package rule. Subpackages do not inherit nullability rules and must be annotated.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • TIL that you can annotate packages o_O Thank you very much, this does answer the question. Just to make sure - do I understand correctly that there is no way to call this method with a null argument in Kotlin without reflection? – Vladimir Matveev Feb 05 '20 at 08:23
  • No, there isn't. But you can add a trivial Java wrapper calling it, and call that wrapper from Kotlin. – Alexey Romanov Feb 05 '20 at 08:28
  • Yeah, Java wrapper was the second thing I thought of. Thanks again! – Vladimir Matveev Feb 05 '20 at 08:37