Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception when "pulling changes" from local database #6959

Closed
1 task done
m-mauersberger opened this issue Sep 29, 2020 · 10 comments · Fixed by #7151
Closed
1 task done

Exception when "pulling changes" from local database #6959

m-mauersberger opened this issue Sep 29, 2020 · 10 comments · Fixed by #7151
Labels
bug Confirmed bugs or reports that are very likely to be bugs good first issue An issue intended for project-newcomers. Varies in difficulty. shared-database

Comments

@m-mauersberger
Copy link
Contributor

JabRef 5.2--2020-09-29--2d92025
Linux 4.12.14-lp151.28.67-default amd64
Java 15

Steps to reproduce the behavior:

  1. Load a local database.
  2. Click on "Pull changes from shared database"
  3. Exception has been thrown.
Log File
java.lang.NullPointerException: Cannot invoke "org.jabref.logic.shared.DatabaseSynchronizer.pullChanges()" because "<local1>" is null
      at org.jabref.gui.shared.PullChangesFromSharedAction.lambda$execute$0(Unknown Source) ~[org.jabref:?]
      at java.util.Optional.ifPresent(Unknown Source) ~[?:?]
      at org.jabref.gui.shared.PullChangesFromSharedAction.execute(Unknown Source) ~[org.jabref:?]
      at org.jabref.gui.actions.JabRefAction.lambda$new$2(Unknown Source) ~[org.jabref:?]
      at org.controlsfx.control.action.Action.handle(Unknown Source) ~[org.jabref.merged.module:?]
      at org.controlsfx.control.action.Action.handle(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at javafx.event.Event.fireEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at javafx.scene.control.MenuItem.fire(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.doSelect(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.scene.control.ContextMenuContent$MenuItemContainer.lambda$createChildren$12(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at javafx.event.Event.fireEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at javafx.scene.Scene$MouseHandler.process(Unknown Source) ~[org.jabref.merged.module:?]
      at javafx.scene.Scene.processMouseEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) ~[org.jabref.merged.module:?]
      at java.security.AccessController.doPrivileged(Unknown Source) ~[?:?]
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.glass.ui.View.handleMouseEvent(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.glass.ui.View.notifyMouse(Unknown Source) ~[org.jabref.merged.module:?]
      at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) ~[org.jabref.merged.module:?]
      at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(Unknown Source) ~[org.jabref.merged.module:?]
      at java.lang.Thread.run(Unknown Source) [?:?]
@Siedlerchr
Copy link
Member

The solution would be to create another BooleanExpression in the ActionHelper class, e..g needsSharedDatabase
filter there
And in the action you can then bind it, e..g:
this.executable.bind(ActionHelper.needsEntriesSelected(stateManager));

@Siedlerchr Siedlerchr added good first issue An issue intended for project-newcomers. Varies in difficulty. bug Confirmed bugs or reports that are very likely to be bugs labels Nov 22, 2020
@luis-valdez
Copy link
Contributor

Hi! Can I work on this?

@Siedlerchr
Copy link
Member

Sure. Go ahead, if you have any questions ask here or in our gitter channel

@luis-valdez
Copy link
Contributor

Hello I'm back. I think I have a solution almost worked out but I need a little help.

I added the binding in PullChangesFromSharedAction.java

    public PullChangesFromSharedAction(StateManager stateManager) {
        this.stateManager = stateManager;

        this.executable.bind(ActionHelper.needsDatabase(stateManager));
        this.executable.bind(ActionHelper.needsSharedDatabase(stateManager)); //new
    }

The problem is I'm still not sure how to make the validation in the ActionHelper.java. So far my approach is something like this:

    public static BooleanExpression needsSharedDatabase(StateManager stateManager){
        return stateManager.activeDatabaseProperty().isEqualTo("shared");
    }

The problem is that in the .isEqualTo I'm not sure with what I should compare it to detect when the user is not using a shared database.

I would really appreciate some help to make my first contribution!

@Siedlerchr
Copy link
Member

Idea is good so far, for checking if it's a shared database you better check the bibdatabasecontect e.g
databaseContext.getLocation() == DatabaseLocation.SHARED)

@calixtus
Copy link
Member

calixtus commented Dec 1, 2020

Bindings.createBooleanBinding is probably your friend here. Be aware that you can combine two Bindings with .and()

@luis-valdez
Copy link
Contributor

Update:

I came up with this solution:

    public static BooleanExpression needsSharedDatabase(StateManager stateManager) {
        BibDatabaseContext databaseContext = stateManager.activeDatabaseProperty().orElse(null).get();
        return Bindings.createBooleanBinding(() -> databaseContext != null && databaseContext.getLocation() == DatabaseLocation.SHARED);
    }

But now the problem is that the validation is only being done at the start when I run the program. I'm guessing It's related to the StateManager.java but I'm fairly new to JavaFX so I'll keep looking into it.

@Siedlerchr
Copy link
Member

Siedlerchr commented Dec 2, 2020

You need to add the check for the active database property in the booleanBinding itself. The Bindings are wrapper around Observables. Observables update whenever their values changes.
Some background info: https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm

I think something like this could work:
you may need to add some null checks

     var binding = Bindings.createBooleanBinding(()->
        stateManager.activeDatabaseProperty().getValue().filter(context->context.getLocation() == DatabaseLocation.SHARED).isPresent(),
        stateManager.activeDatabaseProperty());
  
        return BooleanExpression.booleanExpression(binding);

@luis-valdez
Copy link
Contributor

Thanks a lot @Siedlerchr I really appreciate your help. I'll look into it.

@calixtus
Copy link
Member

calixtus commented Dec 2, 2020

orElse(null) is always a bad idea...
Try using .isEmpty() inside the lambda expression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Confirmed bugs or reports that are very likely to be bugs good first issue An issue intended for project-newcomers. Varies in difficulty. shared-database
Projects
Archived in project
4 participants