0

I am trying to build an app as a learning experience. I am getting a null pointer exception, but it is happening the second time the code is being called.

So my code calls this as part of it's startup.

// Sanity checks
sanity = new SanityChecks();
logger.info("Checking sanity...");
try {
    sanity.doBasicChecks();
    logger.info("It all looks sane.");
}
catch( final Exception ex){
    logger.error("Something is wrong, we are not sane.  Aborting...", ex);
    stop();
}

Other classes are:

package nz.co.great_ape.tempusFugit;

import com.almworks.sqlite4java.SQLite;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * Checks to see if all is ok for standard usage of tempusFugit.
 *
 * Checks for valid paths, existing database etc, if not assumes that
 * this is the first time tempusFugit has been run for this user and
 * tries to set up the basic files and data.
 *
 * @author Rob Brown-Bayliss
 *         Created on 2/11/14
 */
public class SanityChecks {


    public static final Logger logger = LoggerFactory.getLogger(AppConsts.LOGGER_NAME);

    public SanityChecks() {
        // todo
        // todo
        SQLite.setLibraryPath(AppConsts.HOME_DIR);   // TODO:  Why is this required?  can we not place the native libs somewhere else or in the jar?
        // todo
        // todo
    }

    /**
     * Performs basic checks to see if it is ok to run the app.  If not it will attempt to
     * set up for first time use.
     *
     * @return true if all is ok
     */
    public boolean doBasicChecks() {
        logger.info("Starting basic checks...");
        if (!HomeDirExists()) {
            return false;
        }
        if (!DatabaseExists()) {
            logger.info("Trying to create a new database.");
            DatabaseUpgrade dug = new DatabaseUpgrade();
            if (!dug.upGrade()) {
                return false;
            }
            logger.info("Created a new database.");
            // At this point a usable database should exist and it should be current
        }
        if (!DatabaseVersionCorrect()) {
//          //  If the database is old we will upgrade it to the current version.
//          DatabaseUpgrade dug = new DatabaseUpgrade();
//          if (!dug.upGrade()) {
//              return false;
//          }
            logger.info("is this it?.");
        }
        //  At this point all basic checks have passed and we are good to go...
        logger.info("Basic checks are complete.  All is good in the universe...");
        return true;
    }

    /**
     * Checks if the app home directory exists, if not it tries to create it.
     *
     * @return true if exists or was able to create the directory
     */
    private boolean HomeDirExists() {
        if (!Files.isDirectory(Paths.get(AppConsts.HOME_DIR))) {
            try {
                Files.createDirectory(Paths.get(AppConsts.HOME_DIR));
            }
            catch (IOException io) {
                logger.error("The directory " + AppConsts.HOME_DIR + " does not exist and could not be created.  This is not the best but we can survive.", io);
                return false;
            }
        }
        logger.info("The directory " + AppConsts.HOME_DIR + " exists.  This is good.");
        return true;
    }

    /**
     * Checks if the SQLite database exists, if not it tries to create it.
     * or was able to create the database
     *
     * @return true if the database exists
     */
    private boolean DatabaseExists() {
        if (Files.notExists(Paths.get(AppConsts.TF_DATABASE))) {
            logger.error("The database " + AppConsts.TF_DATABASE + " does not exist.  This is bad.");
            return false;
        }
        logger.info("The database " + AppConsts.TF_DATABASE + " exists.  This is good.");
        return true;
    }

    /**
     * Checks if the SQLite database is correct for this version.
     *
     * @return true if correct version
     */
    private boolean DatabaseVersionCorrect() {
        Integer expectedVersion = AppConsts.TF_DATABASE_VERSION;
        logger.info("Checking the database version is correct.  Looking for version "+ expectedVersion + "." );
        DatabaseUpgrade dug = new DatabaseUpgrade();
        logger.info("Checking the database version is correct.  Looking for version "+ expectedVersion + "." );
        Integer currentVersion = dug.getVersion();
        if (currentVersion < expectedVersion) {
            logger.info("Expected version " + expectedVersion + ", but database is version " + currentVersion + ".  This is bad.");
            return false;
        }
        logger.info("The database version is correct.  This is good.");
        return true;
    }

}

And:

package nz.co.great_ape.tempusFugit;

import com.almworks.sqlite4java.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * Setup the database for current version tempusFugit.  This will upgrade an
 * existing database or create a new empty database if required.
 *
 * @author Rob Brown-Bayliss
 *         Created on 4/11/14
 */
public class
        DatabaseUpgrade {

    public static final Logger logger = LoggerFactory.getLogger(AppConsts.LOGGER_NAME);

    private SQLiteConnection dbConn = null;
    private SQLiteQueue      sQueue = null;
    private int currentVersion;

    public DatabaseUpgrade() {

    }

    /**
     * Attempts to upgrade the existing database to the current version, or if
     * there is no existing database then create one suitable for the current app version.
     *
     * @return true if there is a current and usable database
     */
    public boolean upGrade() {
        logger.info("    Started an upgrade on the database, if the database does not exist it will be created at the current version, ");
        logger.info("    if it exists but is an older version it will be upgraded to the current version.");
        if (openDatabase()) {
            currentVersion = getVersion();
            if (currentVersion == AppConsts.FAIL) {
                logger.info("Database version is unknown.  The file will be deleted and a new database created.  We can survive this.");
                // TODO:  Ask user if we should delete the old one or make a backup?
                closeDatabase();
                deleteDatabase();
                openDatabase();
            }
            if (currentVersion != AppConsts.TF_DATABASE_VERSION) {
                logger.info("Current Database version is " + currentVersion);
                // TODO:  Backup current database.
                if (currentVersion < 1) {
                    if (!makeVersionOne()) {
                        logger.error("Unable to upgrade the database.  This is VERY bad.");
                        return false;
                    }
                }
                currentVersion = 1;
            }
            closeDatabase();  // good practice
        }
        logger.info("The database is the current version.  This is good.");
        return true;
    }

    /**
     * Turns a blank SQLite database into a tempusFugit version 1 database by
     * adding the required tables and data.
     */
    private boolean makeVersionOne() {
        logger.info("Attempting to upgrade to version 1.");
        String CT_SQL = "CREATE TABLE IF NOT EXISTS dbVersion (id INTEGER PRIMARY KEY AUTOINCREMENT, version INTEGER NOT NULL UNIQUE, ";
        CT_SQL = CT_SQL + "upgraded INTEGER(4) NOT NULL DEFAULT (strftime('%s','now'))); ";
        String IN_SQL = "INSERT INTO dbVersion(version) values (1); ";
        try {
            execSQL("BEGIN TRANSACTION; ");
            execSQL(CT_SQL);  // create the table
            execSQL(IN_SQL);  // insert the record
            execSQL("COMMIT; ");
        }
        catch (Exception ex) {
            logger.error("Attempted upgrade of " + AppConsts.TF_DATABASE + " to version 1 has failed.  This is VERY bad.", ex);
            return false;
        }
        logger.info("The database has been upgraded to version 1.  This is good.");
        return true;
    }

    private Integer execSQL(String SQL) {
        return sQueue.execute(new SQLiteJob<Integer>() {
            protected Integer job(SQLiteConnection con) throws SQLiteException {
                SQLiteStatement st = null;
                try {
                    st = con.prepare(SQL);
                    st.step();
                    return AppConsts.SUCCESS;
                }
                catch (Exception ex) {
                    logger.error("Tried to execute SQL: " + SQL, ex);
                    return AppConsts.FAIL;
                }
                finally {
                    if (st != null) {
                        st.dispose();
                    }
                }
            }
        }).complete();
    }

    /**
     * Gets the current database version
     *
     * @return version as an int
     */
    public int getVersion() {
        return sQueue.execute(new SQLiteJob<Integer>() {
            protected Integer job(SQLiteConnection con) throws SQLiteException {
                SQLiteStatement st = null;
                try {
                    st = con.prepare("SELECT version, upgraded FROM dbVersion ORDER BY upgraded DESC LIMIT 1;");
                    st.step();
                    return st.columnInt(0);
                }
                catch (Exception ex) {
                    logger.error("The database version of " + AppConsts.TF_DATABASE + " is unknown.  This is bad.", ex);
                    return AppConsts.FAIL;
                }
                finally {
                    if (st != null) {
                        st.dispose();
                    }
                }
            }
        }).complete();
    }

    /**
     * Opens an existing SQLite database or creates a new blank database
     * if none exists.
     *
     * @return false if there is a problem.  // TODO: Is it possible to have a problem?
     */
    private boolean openDatabase() {
        try {
            dbConn = new SQLiteConnection(new File(AppConsts.TF_DATABASE));
            dbConn.open(true);
            sQueue = new SQLiteQueue(new File(AppConsts.TF_DATABASE));
            sQueue.start();
            return true;
        }
        catch (Exception ex) {
            logger.error("The database " + AppConsts.TF_DATABASE + " could not be opened or created.  This is VERY bad.", ex);
            return false;
        }
    }

    /**
     * Closes an open database.
     *
     * @return false if there is a problem.  // TODO: Is it possible to have a problem?
     */
    private boolean closeDatabase() {
        try {
            if (dbConn != null) {
                dbConn.dispose();
            }
            return true;
        }
        catch (Exception ex) {
            logger.error("The database " + AppConsts.TF_DATABASE + " could not be closed.", ex);
            return false;
        }
    }

    /**
     * Deletes an existing database.
     *
     * @return false if there is a problem.  // TODO: Is it possible to have a problem?
     */
    private boolean deleteDatabase() {
        try {
            Files.delete(Paths.get(AppConsts.TF_DATABASE));
            logger.info("The database " + AppConsts.TF_DATABASE + " has been deleted.");
            return true;
        }
        catch (Exception ex) {
            logger.error("The database " + AppConsts.TF_DATABASE + " could not be deleted.", ex);
            return false;
        }
    }
}


Plus the constants:

package nz.co.great_ape.tempusFugit;

/**
 * Constants used by tempusFugit
 *
 * @author Rob Brown-Bayliss
 *         Created on 31/10/14
 */
public class AppConsts {

    // Application
    public static final String APP_NAME       = "Tempus Fugit";
    public static final String VERSION_NUMBER = "0.0.1";

    // Debug Mode On-Off
    public static final boolean DEBUG_MODE = true;

    // Data files and paths
    public static final String FS        = System.getProperty("file.separator");
    public static final String HOME_DIR  = System.getProperty("user.home") + FS + ".tempusFugit";  // This is the tempusFugit home, not the users home.
    public static final String USER_NAME = System.getProperty("user.name");

    public static final String LOGGER_NAME = "nz.co.great_ape.tempusFugit";
    public static final String LOG_FILE    = HOME_DIR + FS + "tempusFugit.log";

    // Database
    public static final String TF_DATABASE = HOME_DIR + FS + "tfData.sql";
    public static final int TF_DATABASE_VERSION = 1;  //  This is the current version of the database

    // Error codes
    public static final int UNKNOWN = -1;
    public static final int FAIL    = 0;
    public static final int SUCCESS = 1;

}

What I don't know is why the call if (!DatabaseVersionCorrect()) crashes with a null pointer.

Can anyone help here?

This is the stack trace

/usr/lib/jvm/java-8-oracle/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:49764,suspend=y,server=n -javaagent:/home/rob/Projects/IntelliJ/plugins/Groovy/lib/agent/gragent.jar -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/java-8-oracle/jre/lib/jsse.jar:/usr/lib/jvm/java-8-oracle/jre/lib/management-agent.jar:/usr/lib/jvm/java-8-oracle/jre/lib/deploy.jar:/usr/lib/jvm/java-8-oracle/jre/lib/javaws.jar:/usr/lib/jvm/java-8-oracle/jre/lib/plugin.jar:/usr/lib/jvm/java-8-oracle/jre/lib/resources.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfr.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jfxswt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/rt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/jce.jar:/usr/lib/jvm/java-8-oracle/jre/lib/charsets.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-8-oracle/jre/lib/ext/cldrdata.jar:/home/rob/Projects/tempusFugit/build/classes/main:/home/rob/Projects/tempusFugit/build/resources/main:/home/rob/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.7/2b8019b6249bb05d81d3a3094e468753e2b21311/slf4j-api-1.7.7.jar:/home/rob/.gradle/caches/modules-2/files-2.1/com.almworks.sqlite4java/sqlite4java/1.0.392/d6234e08ff4e1607ff5321da2579571f05ff778d/sqlite4java-1.0.392.jar:/home/rob/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-classic/1.1.2/b316e9737eea25e9ddd6d88eaeee76878045c6b2/logback-classic-1.1.2.jar:/home/rob/.gradle/caches/modules-2/files-2.1/ch.qos.logback/logback-core/1.1.2/2d23694879c2c12f125dac5076bdfd5d771cc4cb/logback-core-1.1.2.jar:/home/rob/Projects/IntelliJ/lib/idea_rt.jar nz.co.great_ape.tempusFugit.MainApp

Connected to the target VM, address: '127.0.0.1:49764', transport: 'socket' 10:43:43.371 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Time flies... 10:43:43.379 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - https://www.youtube.com/watch?v=ESto79osxOY 10:43:43.379 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Tempus Fugit Version: 0.0.1 10:43:43.379 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - javafx.runtime.version: 8.0.25-b17 10:43:43.380 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - logged on as: rob 10:43:43.383 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Checking sanity... 10:43:43.383 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Starting basic checks... 10:43:43.393 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - The directory /home/rob/.tempusFugit exists. This is good. 10:43:43.394 [JavaFX Application Thread] ERROR nz.co.great_ape.tempusFugit - The database /home/rob/.tempusFugit/tfData.sql does not exist. This is bad. 10:43:43.394 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Trying to create a new database. 10:43:43.397 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Started an upgrade on the database, if the database does not exist it will be created at the current version, 10:43:43.397 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - if it exists but is an older version it will be upgraded to the current version. Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[1]: instantiated [/home/rob/.tempusFugit/tfData.sql] Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] Internal: loaded sqlite4java-linux-amd64-1.0.392 from /home/rob/.tempusFugit/libsqlite4java-linux-amd64-1.0.392.so Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] Internal: loaded sqlite 3.8.7, wrapper 1.3 Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[1]: opened Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[2]: instantiated [/home/rob/.tempusFugit/tfData.sql] Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[2]: opened Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[1]: connection closed Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[3]: instantiated [/home/rob/.tempusFugit/tfData.sql] Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[3]: opened 10:43:43.507 [SQLiteQueue[tfData.sql]] ERROR nz.co.great_ape.tempusFugit - The database version of /home/rob/.tempusFugit/tfData.sql is unknown. This is bad. com.almworks.sqlite4java.SQLiteException: [1] DB[2] prepare() SELECT version, upgraded FROM dbVersion ORDER BY upgraded DESC LIMIT 1; [no such table: dbVersion] at com.almworks.sqlite4java.SQLiteConnection.throwResult(SQLiteConnection.java:1436) ~[sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteConnection.prepare(SQLiteConnection.java:580) ~[sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteConnection.prepare(SQLiteConnection.java:635) ~[sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteConnection.prepare(SQLiteConnection.java:622) ~[sqlite4java-1.0.392.jar:392] at nz.co.great_ape.tempusFugit.DatabaseUpgrade$2.job(DatabaseUpgrade.java:121) [main/:na] at nz.co.great_ape.tempusFugit.DatabaseUpgrade$2.job(DatabaseUpgrade.java:117) [main/:na] at com.almworks.sqlite4java.SQLiteJob.execute(SQLiteJob.java:372) [sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteQueue.executeJob(SQLiteQueue.java:534) [sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteQueue.queueFunction(SQLiteQueue.java:667) [sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteQueue.runQueue(SQLiteQueue.java:623) [sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteQueue.access$000(SQLiteQueue.java:77) [sqlite4java-1.0.392.jar:392] at com.almworks.sqlite4java.SQLiteQueue$1.run(SQLiteQueue.java:205) [sqlite4java-1.0.392.jar:392] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25] 10:43:43.508 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Database version is unknown. The file will be deleted and a new database created. We can survive this. 10:43:43.509 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - The database /home/rob/.tempusFugit/tfData.sql has been deleted. 10:43:43.510 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Current Database version is 0 10:43:43.510 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Attempting to upgrade to version 1. Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[4]: instantiated [/home/rob/.tempusFugit/tfData.sql] Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[4]: opened Nov 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB[3]: connection closed 10:43:43.640 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - The database has been upgraded to version 1. This is good. 10:43:43.640 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - The database is the current version. This is good. 10:43:43.640 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Created a new database. 10:43:43.640 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Checking the database version is correct. Looking for version 1. 10:43:43.640 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Checking the database version is correct. Looking for version 1. 10:43:43.641 [JavaFX Application Thread] ERROR nz.co.great_ape.tempusFugit - Something is wrong, we are not sane. Aborting... java.lang.NullPointerException: null at nz.co.great_ape.tempusFugit.DatabaseUpgrade.getVersion(DatabaseUpgrade.java:117) ~[main/:na] at nz.co.great_ape.tempusFugit.SanityChecks.DatabaseVersionCorrect(SanityChecks.java:111) ~[main/:na] at nz.co.great_ape.tempusFugit.SanityChecks.doBasicChecks(SanityChecks.java:54) ~[main/:na] at nz.co.great_ape.tempusFugit.MainApp.start(MainApp.java:78) ~[main/:na] at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821) [jfxrt.jar:na] at com.sun.javafx.application.LauncherImpl$$Lambda$56/1015064561.run(Unknown Source) [jfxrt.jar:na] at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323) [jfxrt.jar:na] at com.sun.javafx.application.PlatformImpl$$Lambda$50/591723622.run(Unknown Source) [jfxrt.jar:na] at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292) [jfxrt.jar:na] at com.sun.javafx.application.PlatformImpl$$Lambda$52/1657335803.run(Unknown Source) [jfxrt.jar:na] at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_25] at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291) [jfxrt.jar:na] at com.sun.javafx.application.PlatformImpl$$Lambda$51/1166726978.run(Unknown Source) [jfxrt.jar:na] at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) [jfxrt.jar:na] at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) [jfxrt.jar:na] at com.sun.glass.ui.gtk.GtkApplication.lambda$null$45(GtkApplication.java:126) [jfxrt.jar:na] at com.sun.glass.ui.gtk.GtkApplication$$Lambda$42/1167116739.run(Unknown Source) [jfxrt.jar:na] at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25] 10:43:43.641 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Game Over... 10:43:44.563 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - Game Over...

3
  • Post the entire error/stack trace. Commented Nov 29, 2014 at 6:11
  • Please paste only relevant code and stack trace. Commented Nov 29, 2014 at 6:13
  • Sorry, I forgot the trace, but I think all the parts of the code are there. Commented Nov 29, 2014 at 21:47

1 Answer 1

1

The problem is te fact that you call

DatabaseUpgrade dug = new DatabaseUpgrade();
logger.info(...);
Integer currentVersion = dug.getVersion(); 

But your dbConn and sQueue in DatabaseUpgrade are still null. Since you didn't called the private openDatabase() method which initializes your varaibles. So When you call getVersion() your sQueue.execute(...) blowups because you cannot call a method on a null object.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for that. Yes a dumb newbie mistake. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.