1

I have this bit of code to check if my mongoDB connection is still active:

val isConnected: Boolean
            get() = if (instance!!.connection != null) {
                try {
                    instance!!.connection!!.getDatabase(instance!!.databaseName!!) != null
                } catch (e: Exception) {
                    Logger.handle("Error verifying mongoDB connection status", e)
                    false
                }
            } else false

I get a warning saying this condition is always true:

Condition 'instance!!.connection!!.getDatabase(instance!!.databaseName!!) != null' is always 'true'

I know that Kotlin has nullable types, but the getDatabase() method is referencing a Java method inside MongoClient. I'm using jdk-8u291 which doesn't have nullable return types for Java as far as I'm aware (excluding the @Nullable annotation). Here's the decompiled MongoClient::getDatabase() method:

public interface MongoClient extends Closeable {

    
    /**
     * Gets a {@link MongoDatabase} instance for the given database name.
     *
     * @param databaseName the name of the database to retrieve
     * @return a {@code MongoDatabase} representing the specified database
     * @throws IllegalArgumentException if databaseName is invalid
     * @see MongoNamespace#checkDatabaseNameValidity(String)
     */
    MongoDatabase getDatabase(String databaseName);

   // ...
}

Why is this condition marked as always "true" if the return type of the Java method is obviously nullable?

clem585
  • 53
  • 5
  • 1
    It sounds like you're using IntelliJ. If so, do yourself a favor and set the IDE to always automatically download source jars; it's nuts that it doesn't do so by default. – chrylis -cautiouslyoptimistic- Oct 27 '21 at 06:33
  • Maybe not that obvious. Maybe you will get exception if database is not found. Static code analisys might detect that – Antoniossss Oct 27 '21 at 06:33
  • I downloaded the sources+documentation and edited the post with the added information. It doesn't mention the possibility of the database being null, and the warning is still there. – clem585 Oct 27 '21 at 06:42

2 Answers2

2

this is because you are using the !! operator and everything that it returns is not null. If you want to check if something is null you have to use the ? operator:

instance?.connection != null

The !! operator checks if something is null and if it is null it will throw. Therefore if you use the instance after that operator it will not be null anymore.

You could also make use of the let function, something like:

val isConnected: Boolean
    get() = instance?.let {
            try {
                it.connection?.getDatabase(it.databasename) != null
            }  catch (e: Exception) {
                Logger.handle("Error verifying mongoDB connection status", e)
                false
            }
        } ?: false
Stephan
  • 15,704
  • 7
  • 48
  • 63
  • I thought the ? and !! operators affected the variable/type before it. In this case wouldn't the !! have to be after "getDatabase(it.databasename)" for the warning to be correct? The "connection?" would only mean that connection can be null, not the result of the getDatabase call? – clem585 Oct 27 '21 at 06:54
  • 1
    it checks the variable before it. The difference is between `instance!!.` and `instance?.` is that the `!!` throws and exception if instance is null, while the version with `?` returns null. – Stephan Oct 27 '21 at 06:58
  • But in the case where I want to let's say, throw an exception if instance/connection is null by using !!, and only want to check if the result of getDatabase is null, what should I do? – clem585 Oct 27 '21 at 07:04
  • 1
    If you want to throw the NullPointerException if instance/connection is null, simply remove the if-else condition from your original code and keep the try-catch as it is. – Arpit Shukla Oct 27 '21 at 07:28
1

Is because MongoDatabase getDatabase(String databaseName); is not marked with @Nullable. So that type is not nulable for Kotlin.

And since you are saying everything is not nullable !! then the result is not returned null by the shorthand ? which you are not using.

cutiko
  • 9,887
  • 3
  • 45
  • 59