Hi IntelliJ gives me a warning "java.lang.NullPoin...
# getting-started
n
Hi IntelliJ gives me a warning "java.lang.NullPointerException" on a line which invokes a constructor of a class. What can I check in that class code that can be the cause of the warning?
v
Maybe set an exception breakpoint for NPE and then investigate where it comes from? Actually with Java 15 NPEs got much more helpful in telling the actual variable the was
null
when the NPE happened to easily identify the code where it happened in that line. But I have no idea whether that also works with Kotlin.
n
But I have no runtime exception this is a IDE warning during code analysis ... During tests (automatic or manual) I have never experienced that npe ....
(the class constructor actually raises an exception but this is not a NPE:
Copy code
class RenderService(private val outputPath: String) {
    var loadingDuration: Duration = Duration.ZERO
    var renderingDuration: Duration = Duration.ZERO
    var savingDuration: Duration = Duration.ZERO
    private val mavTemplateBytes: ByteArray

    init {
        val template: InputStream = getFileContentFromResources("templates/MAV.pdf")
            ?: throw RuntimeException("Failed to load template")
        mavTemplateBytes = template.readAllBytes()
    }
v
IDE warning? Interesting. Never seen it like that. How does that look like? Mind sharing a screenshot?
n
I don't know if it is the exact term ,. you see it in "problems"
sure I try
intellij_ide_problems.jpg
it is the third line, the first two are my current work in progress 🙂
This warning comes out when committing from the IDE. At the moment I simply ignore it, but I fear there is something to fix ...
v
IIrc I've seen such entries when getting an NPE during actual execution. Maybe you had an NPE in that line but in the meantime moved or fixed it?
Ah, ok, then maybe it is a bug in IntelliJ or the Kotlin plugin?
n
Uhm no I don't think so
v
Maybe have a look at the IntelliJ log file to see whether it is also written to there and hopefully with stacktrace
n
Okk I will try to find the idea log thanks nice idea actually i didn't consider a possible ide bug but who knows ...
v
Help -> Show Log in Explorer
n
there is nothing that seems related to this message ...
🙁 1
c
this chunk of code has some suspect null handling:
Copy code
val template: InputStream = getFileContentFromResources("templates/MAV.pdf")
            ?: throw RuntimeException("Failed to load
By defining the type as
InputStream
(non-null) you’re coercing a null value into that from getFileContentFromResource. Make that nullable (InputStream?) and let the smart cast handle subsequent uses.
n
Thanks I'll try
v
But shouldn't it be smart enough to see that there is elvis operator and unconditional exception?
c
hard to say w/o seeing the signature of getFileContentFromResource
n
Copy code
private fun getFileContentFromResources(name: String) =
    RenderService::class.java.classLoader.getResourceAsStream(name)
the warning disappeared ..
but the code isn't changed
i've changed other lines but that part is still like this
Copy code
class RenderService(private val outputPath: String) {
    var loadingDuration: Duration = Duration.ZERO
    var renderingDuration: Duration = Duration.ZERO
    var savingDuration: Duration = Duration.ZERO
    private val mavTemplateBytes: ByteArray

    init {
        val template: InputStream = getFileContentFromResources("templates/MAV.pdf")
            ?: throw RuntimeException("Failed to load template")

        mavTemplateBytes = template.readAllBytes()
    }
🤔
perhaps, in cases like this, I should try invalidate cache and restart, like in the old times ..
c
Could be, though there is a need to adjust for platform types (those returned from Java calls) - Kotlin doesn’t know they nullability of those types and assumes they are non-null; generally need to pay attention to the API contracts. In that specific call it should be InputStream? to allow Kotlin to handle the maybe-null of it.
n
I started with InputStream? but doing so I had to propagate a lot of check in the code .. I preferred to failing fast with that exception and then follow as if was not null (don't know if it's clear what i mean)
if template is nullable then mavTemplateBytes too, and so on ..
c
smart casting should help there.
n
ByteArray! interesting ...
I knew the double bang not the single bang operator,. sorry I am quite new to kotlin 🙂 thanks a lot for suggestion
c
that’s not the operator - that’s IntelliJ overlays showing the inferred types.
!
is non-nullable,
?
is nullable. No need to define types on those vals, they are inferred.
Here’s the actual code:
Copy code
test("foo") {
            val template = getFileContentFromResources("whatever")
            val template2 = getFileContentFromResources("whatever") ?: error("whoops")
            val foo = template2.readAllBytes()
        }
v
!
is not non-nullable
It is "platform type" which means "I (Kotlin) don't know whether it is nullable or not as there are no recognized nullability annotations on the Java code"
And if the entry vanished, maybe it was from previously executing the code. When I force added a not-null assertion on a null property and executed, the NPE that were thrown was also shown in the problems view, but as error, not warning.
n
I don't see it in my ide, is it ultimate feature?
v
Fixing the code did not make it go away, just reexecuting and not getting it anymore
You don't see what?
n
yes i suspected something like that
the single bang
c
I don’t see it in my ide, is it ultimate feature?
Not sure. It’s local variable type hints.
v
I don't think it is ultimate feature
n
hovering on the variable name I see the type (inferred)
v
Should be a feature of the Kotlin plugin if I'm not wrong
n
ah I will check
c
if you Option-Enter (Ctrl-Enter iirc for Windows) on the variable name it presents an options to show / hide local variable type hints.
n
ah thank you it was disabled
nevertheless I see InputStream (without the bang)
🤷 1
v
image.png
n
thanks I've enabled now
c
the bang is removed because the elvis operator resolve the null-ambiguity from the platform call.
it’s there on the ByteArray as Kotlin doesn’t know the nullability of that call (the JavaDoc for readAllBytes doesn’t say it returns null - could add ?: error(“…”) to be clear)
n
type_hint.jpg
Ook I got it