Я пытаюсь создать приложение в качестве учебного опыта. Я получаю исключение нулевого указателя, но это происходит во второй раз, когда вызывается код.Sqlite java и sqlite4java
Таким образом, мой код вызывает это как часть его запуска.
// 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();
}
Другие классы:
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;
}
}
И:
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;
}
То, что я не знаю, почему вызов, если происходит сбой с нулевым указателем (DatabaseVersionCorrect (!)).
Может кто поможет здесь?
Это трассировки стека
/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
подключен к целевому VM, адрес: '127.0.0.1:49764', транспорт: 'гнездо' 10: 43: 43,371 [JavaFX Применение Нить] INFO новозеландских .co.great_ape.tempusFugit - Time flies ... 10: 43: 43.379 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - https://www.youtube.com/watch?v=ESto79osxOY 10: 43: 43.379 [Тема приложения JavaFX] INFO nz.co.great_ape .tempusFugit - Tempus Fugit Версия: 0.0.1 10: 43: 43.379 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - javafx.runtime.version: 8.0.25-b17 10: 43: 43.380 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - зарегистрирован как: rob 10: 43: 43.383 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - Проверка работоспособности ... 10: 43: 43.383 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - Запуск основных проверок ... 10: 43: 43.393 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - Каталог/главная страница /rob/.tempusFugit существует. Это хорошо. 10: 43: 43.394 [Тема приложения JavaFX] ERROR nz.co.great_ape.tempusFugit - База данных /home/rob/.tempusFugit/tfData.sql не существует. Это плохо. 10: 43: 43.394 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - попытка создания новой базы данных. 10: 43: 43.397 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - началось обновление базы данных, если база данных не существует, она будет создана в текущей версии, 10: 43: 43.397 [JavaFX Application Thread] INFO nz.co.great_ape.tempusFugit - если он существует, но является более старой версией, он будет обновлен до текущей версии. 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [1]: экземпляр [/home/rob/.tempusFugit/tfData.sql] 30 ноября 2014 г. 10 : 43: 43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] Внутренний: загружен sqlite4java-linux-amd64-1.0.392 из /home/rob/.tempusFugit/libsqlite4java-linux-amd64-1.0.392. так 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] Внутренний: загруженный sqlite 3.8.7, обертка 1.3 30 ноября 2014 10:43:43 com.almworks .sqlite4java.Internal log INFO: [sqlite] DB [1]: открыт 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [2]: экземпляр [/] home/rob/.tempusFugit/tfData.sql] 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [2]: открыт 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [1]: соединение закрыто 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [3]: экземпляр [/home/rob/.tempusFugit/tfData.sql] 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO : [sqlite] DB [3]: открыт 10: 43: 43.507 [SQLiteQueue [tfData.sql]] ERROR nz.co.great_ape.tempusFugit - версия базы данных /home/rob/.tempusFugit/tfData.sql неизвестна , Это плохо. com.almworks.sqlite4java.SQLiteException: [1] DB [2] prepare() версия SELECT, обновлена FROM dbVersion ORDER BY обновлено DESC LIMIT 1; [нет такой таблицы: 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] в java .lang.Thread.run (Thread.java:745) [na: 1.8.0_25] 10: 43: 43.508 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - версия базы данных неизвестна. Файл будет удален и будет создана новая база данных. Мы можем это выжить. 10: 43: 43.509 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - База данных /home/rob/.tempusFugit/tfData.sql удалена. 10: 43: 43.510 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - Текущая версия базы данных 0 10: 43: 43.510 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - Попытка обновления до версии 1. 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [4]: экземпляр [/home/rob/.tempusFugit/tfData.sql] Ноябрь 30, 2014 10:43:43 AM com.almworks.sqlite4java.Internal log INFO: [sqlite] DB [4]: открыт 30 ноября 2014 10:43:43 com.almworks.sqlite4java.Internal log INFO: [ sqlite] DB [3]: соединение закрыто 10: 43: 43.640 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - база данных обновлена до версии 1. Это хорошо. 10: 43: 43.640 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - база данных является текущей версией. Это хорошо. 10: 43: 43.640 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - Создана новая база данных. 10: 43: 43.640 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - проверка версии базы данных верна. Поиск версии 1. 10: 43: 43.640 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusFugit - проверка версии базы данных верна. Поиск версии 1. 10: 43: 43.641 [Тема приложения JavaFX] ERROR nz.co.great_ape.tempusFugit - Что-то не так, мы не вменяем. 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 (Неизвестный источник) [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 (Неизвестный источник) [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 (Неизвестный источник) [jfxrt.jar: na] at java.security.AccessControll er.doPrivileged (собственный метод) [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 (Неизвестный источник) [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 (собственный метод) [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 (Неизвестный источник) [jfxrt.jar: na] на java.lang.Thread .run (Thread.java:745) [na: 1.8.0_25] 10: 43: 43.641 [Тема приложения JavaFX] INFO nz.co.great_ape.tempusF ugit - Game Over ... 10: 43: 44,563 [JavaFX Применение Нить] INFO nz.co.great_ape.tempusFugit - Game Over ...
Опубликовать всю трассировку ошибок/стека. –
Пожалуйста, вставьте только соответствующий код и трассировку стека. – SMA
Извините, я забыл след, но я думаю, что все части кода есть. – Rob