Repository: jabref/jabref
Issue: NPE when saving new database with entries  (DatabaseChangeMonitor is null)

Create a  new database
Copy/Paste some bibtex entry
Hit CTRL +S

```
17:07:25.852 [AWT-EventQueue-0] ERROR org.jabref.gui.BasePanel - runCommand error: null
java.lang.NullPointerException: null
	at org.jabref.gui.BasePanel.isUpdatedExternally(BasePanel.java:1823) ~[bin/:?]
	at org.jabref.gui.exporter.SaveDatabaseAction.checkExternalModification(SaveDatabaseAction.java:403) ~[bin/:?]
	at org.jabref.gui.exporter.SaveDatabaseAction.init(SaveDatabaseAction.java:90) ~[bin/:?]
	at org.jabref.gui.BasePanel.runWorker(BasePanel.java:250) ~[bin/:?]
	at org.jabref.gui.exporter.SaveDatabaseAction.runCommand(SaveDatabaseAction.java:285) ~[bin/:?]
	at org.jabref.gui.exporter.SaveDatabaseAction.saveAs(SaveDatabaseAction.java:331) ~[bin/:?]
	at org.jabref.gui.exporter.SaveDatabaseAction.saveAs(SaveDatabaseAction.java:305) ~[bin/:?]
	at org.jabref.gui.exporter.SaveDatabaseAction.init(SaveDatabaseAction.java:100) ~[bin/:?]
	at org.jabref.gui.BasePanel.runWorker(BasePanel.java:250) ~[bin/:?]
	at org.jabref.gui.BasePanel.runCommand(BasePanel.java:1025) [bin/:?]
	at org.jabref.gui.JabRefFrame$GeneralAction.actionPerformed(JabRefFrame.java:2052) [bin/:?]
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) [?:1.8.0_152]
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) [?:1.8.0_152]
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) [?:1.8.0_152]
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) [?:1.8.0_152]
	at javax.swing.AbstractButton.doClick(AbstractButton.java:376) [?:1.8.0_152]
	at javax.swing.AbstractButton.doClick(AbstractButton.java:356) [?:1.8.0_152]
	at javax.swing.plaf.basic.BasicMenuItemUI$Actions.actionPerformed(BasicMenuItemUI.java:811) [?:1.8.0_152]
	at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1663) [?:1.8.0_152]
	at javax.swing.JComponent.processKeyBinding(JComponent.java:2882) [?:1.8.0_152]
	at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(JMenuBar.java:699) [?:1.8.0_152]
	at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(JMenuBar.java:706) [?:1.8.0_152]
	at javax.swing.JMenuBar.processBindingForKeyStrokeRecursive(JMenuBar.java:706) [?:1.8.0_152]
	at javax.swing.JMenuBar.processKeyBinding(JMenuBar.java:677) [?:1.8.0_152]
	at javax.swing.KeyboardManager.fireBinding(KeyboardManager.java:307) [?:1.8.0_152]
	at javax.swing.KeyboardManager.fireKeyboardAction(KeyboardManager.java:293) [?:1.8.0_152]
	at javax.swing.JComponent.processKeyBindingsForAllComponents(JComponent.java:2974) [?:1.8.0_152]
	at javax.swing.JComponent.processKeyBindings(JComponent.java:2966) [?:1.8.0_152]
	at javax.swing.JComponent.processKeyEvent(JComponent.java:2845) [?:1.8.0_152]
	at java.awt.Component.processEvent(Component.java:6310) [?:1.8.0_152]
	at java.awt.Container.processEvent(Container.java:2237) [?:1.8.0_152]
	at java.awt.Component.dispatchEventImpl(Component.java:4889) [?:1.8.0_152]
	at java.awt.Container.dispatchEventImpl(Container.java:2295) [?:1.8.0_152]
	at java.awt.Component.dispatchEvent(Component.java:4711) [?:1.8.0_152]
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954) [?:1.8.0_152]
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806) [?:1.8.0_152]
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074) [?:1.8.0_152]
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945) [?:1.8.0_152]
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771) [?:1.8.0_152]
	at java.awt.Component.dispatchEventImpl(Component.java:4760) [?:1.8.0_152]
	at java.awt.Container.dispatchEventImpl(Container.java:2295) [?:1.8.0_152]
	at java.awt.Window.dispatchEventImpl(Window.java:2746) [?:1.8.0_152]
	at java.awt.Component.dispatchEvent(Component.java:4711) [?:1.8.0_152]
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758) [?:1.8.0_152]
	at java.awt.EventQueue.access$500(EventQueue.java:97) [?:1.8.0_152]
	at java.awt.EventQueue$3.run(EventQueue.java:709) [?:1.8.0_152]
	at java.awt.EventQueue$3.run(EventQueue.java:703) [?:1.8.0_152]
	at java.security.AccessController.doPrivileged(Native Method) [?:1.8.0_152]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) [?:1.8.0_152]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90) [?:1.8.0_152]
	at java.awt.EventQueue$4.run(EventQueue.java:731) [?:1.8.0_152]
	at java.awt.EventQueue$4.run(EventQueue.java:729) [?:1.8.0_152]
	at java.security.AccessController.doPrivileged(Native Method) [?:1.8.0_152]
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) [?:1.8.0_152]
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728) [?:1.8.0_152]
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) [?:1.8.0_152]
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) [?:1.8.0_152]
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) [?:1.8.0_152]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) [?:1.8.0_152]
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) [?:1.8.0_152]
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) [?:1.8.0_152]

```

Changed files:
src/main/java/org/jabref/gui/BasePanel.java

diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java
index d536845048..c6668e2164 100644
--- a/src/main/java/org/jabref/gui/BasePanel.java
+++ b/src/main/java/org/jabref/gui/BasePanel.java
@@ -198,7 +198,7 @@ public class BasePanel extends JPanel implements ClipboardOwner {
     // the query the user searches when this BasePanel is active
     private Optional<SearchQuery> currentSearchQuery = Optional.empty();
 
-    private DatabaseChangeMonitor changeMonitor;
+    private Optional<DatabaseChangeMonitor> changeMonitor = Optional.empty();
 
     public BasePanel(JabRefFrame frame, BibDatabaseContext bibDatabaseContext) {
         Objects.requireNonNull(frame);
@@ -228,7 +228,7 @@ public class BasePanel extends JPanel implements ClipboardOwner {
         Optional<File> file = bibDatabaseContext.getDatabaseFile();
         if (file.isPresent()) {
             // Register so we get notifications about outside changes to the file.
-            changeMonitor = new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), this);
+            changeMonitor = Optional.of(new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), this));
         } else {
             if (bibDatabaseContext.getDatabase().hasEntries()) {
                 // if the database is not empty and no file is assigned,
@@ -1796,7 +1796,7 @@ public class BasePanel extends JPanel implements ClipboardOwner {
      * Perform necessary cleanup when this BasePanel is closed.
      */
     public void cleanUp() {
-        changeMonitor.unregister();
+        changeMonitor.ifPresent(DatabaseChangeMonitor::unregister);
 
         // Check if there is a FileUpdatePanel for this BasePanel being shown. If so,
         // remove it:
@@ -1823,11 +1823,11 @@ public class BasePanel extends JPanel implements ClipboardOwner {
     }
 
     public boolean isUpdatedExternally() {
-        return changeMonitor.hasBeenModifiedExternally();
+        return changeMonitor.map(DatabaseChangeMonitor::hasBeenModifiedExternally).orElse(false);
     }
 
     public void markExternalChangesAsResolved() {
-        changeMonitor.markExternalChangesAsResolved();
+        changeMonitor.ifPresent(DatabaseChangeMonitor::markExternalChangesAsResolved);
     }
 
     public SidePaneManager getSidePaneManager() {
@@ -1975,16 +1975,16 @@ public class BasePanel extends JPanel implements ClipboardOwner {
     }
 
     public void resetChangeMonitor() {
-        changeMonitor.unregister();
-        changeMonitor = new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), this);
+        changeMonitor.ifPresent(DatabaseChangeMonitor::unregister);
+        changeMonitor = Optional.of(new DatabaseChangeMonitor(bibDatabaseContext, Globals.getFileUpdateMonitor(), this));
     }
 
     public void updateTimeStamp() {
-        changeMonitor.markAsSaved();
+        changeMonitor.ifPresent(DatabaseChangeMonitor::markAsSaved);
     }
 
     public Path getTempFile() {
-        return changeMonitor.getTempFile();
+        return changeMonitor.map(DatabaseChangeMonitor::getTempFile).orElse(null);
     }
 
     private static class SearchAndOpenFile {