0

I'm implementing JavaFX application with web crawler ui4j. I get a null pointer exception in a controller class. I couldn't figure out how to instantiate objects which are interface classes in the initializing method.

I've already read documentation, didn't find anything something similar. Could someone provide me some educational staff about it, it's highly appreciated.

public class AppController implements Initializable {

    @FXML
    private Label wronglabel;
    @FXML
    private CheckBox savein;

    @FXML
    private Button signin;

    @FXML
    private TextField email;

    @FXML
    private PasswordField pass;

    @FXML
    private URL url;

    @FXML
    private ResourceBundle rb;
    @FXML
    private Preferences preferences;
    @FXML
    private BrowserEngine webkit;
    @FXML
    private PageConfiguration configuration;
    @FXML
    private Page page;
    @FXML
    private Document document;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO Auto-generated method stub

    email = new TextField();
    pass = new PasswordField();
    preferences = Preferences.userNodeForPackage(AppController.class);
     BrowserEngine webkit = BrowserFactory.getWebKit();
     PageConfiguration configuration = new PageConfiguration();
     configuration.setSelectorEngine(SelectorType.SIZZLE);
     configuration.setUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");

        Page page = webkit.navigate("https://www.amazon.com/ap/signin?clientContext=132-0119732-2425437&openid.return_to=https%3A%2F%2Frelay.amazon.com%2F&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=amzn_relay_desktop_us&openid.mode=checkid_setup&marketPlaceId=ATVPDKIKX0DER&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&pageId=amzn_relay_desktop_us&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.pape.max_auth_age=86400&siteState=clientContext%3D136-7029875-0274320%2CsourceUrl%3Dhttps%253A%252F%252Frelay.amazon.com%252F%2Csignature%3Dnull", configuration);
        page.show();

        Document document = page.getDocument();

        if(preferences!=null) {
            if(preferences.get("username",null)!=null &&!preferences.get("username",null).isEmpty()) {
                email.setText(preferences.get("username",null));
                pass.setText(preferences.get("password", null));
            }
        }
    }


    public void signIn(ActionEvent event) throws Exception {
        String username = email.getText();
        String password = pass.getText();
        if(savein.isSelected()) {
        preferences.put("username", email.getText());
        preferences.put("password", pass.getText());
        }
        else {
            preferences.put("username", "");
            preferences.put("password", "");
        }




        document
            .query("#ap_email")//ERROR STARTS HERE
            .setValue(username);//NULLPOINTER EXCEPTION

        document
            .query("#ap_password")//NULLPOINTER EXCEPTION
            .setValue(password);//NULLPOINTER EXCEPTION

        document
            .query("#signInSubmit").click();//NULLPOINTER EXCEPTION

        Thread.sleep(10000);

        page.close();

        webkit.shutdown();


    }

StackTrace:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
    at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8890)
    at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3862)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2590)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:389)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:411)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
    at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    ... 46 more
Caused by: java.lang.NullPointerException
    at com.notificsound.amazon2.AppController.signIn(AppController.java:96)
    ... 57 more

If I run code without the initializing method, it runs well. Otherwise, when I press a button signIn method it gets NullPointerException. So I think it's a problem in instantiating document objects, from the ui4j package.

Matt
  • 3,052
  • 1
  • 17
  • 30
Vinceere
  • 1
  • 2
  • Regardless of other issues in your code: Do not block the JavaFX application thread using longrunning operations like `Thread.sleep`. They'll freeze the GUI until they're done. The NPE could be caused by `document` or the result of `query` being `null`. Have you checked, which one of those is the case here? – fabian Jun 05 '19 at 22:53
  • @fabian Yeah, it's caused by document, because if I run without initialization method in the controller, or in other application it gives me results. – Vinceere Jun 06 '19 at 10:13

1 Answers1

0

I have tried your code and changed it to the following piece of code and tested it.


import io.webfolder.ui4j.api.browser.*;
import io.webfolder.ui4j.api.dom.Document;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;

public class AppController implements Initializable {

    @FXML
    private Label wronglabel;
    @FXML
    private CheckBox savein;

    @FXML
    private Button signin;

    @FXML
    private TextField email;

    @FXML
    private PasswordField pass;

    //remove @FXML from these
    private Page page;
    private Preferences preferences;
    private BrowserEngine webkit;
    private Document document;


    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO Auto-generated method stub
        email = new TextField();
        pass = new PasswordField();
        preferences = Preferences.userNodeForPackage(AppController.class);


        BrowserEngine webkit = BrowserFactory.getWebKit();
        PageConfiguration configuration = new PageConfiguration();
        configuration.setSelectorEngine(SelectorType.SIZZLE);
        configuration.setUserAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");

        page = webkit.navigate("https://www.amazon.com/ap/signin?clientContext=132-0119732-2425437&openid.return_to=https%3A%2F%2Frelay.amazon.com%2F&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.assoc_handle=amzn_relay_desktop_us&openid.mode=checkid_setup&marketPlaceId=ATVPDKIKX0DER&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&pageId=amzn_relay_desktop_us&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.pape.max_auth_age=86400&siteState=clientContext%3D136-7029875-0274320%2CsourceUrl%3Dhttps%253A%252F%252Frelay.amazon.com%252F%2Csignature%3Dnull", configuration);
        page.show();

        //this returns null, which I think is a problem with the api
        document = page.getDocument();

        //i have also tried this and it too gives null
        page.addDocumentListener(documentLoadEvent -> {
            document = page.getDocument();
            if (document == null) System.out.println("IS NULL");
        });

        if (preferences != null) {
            if (preferences.get("username", null) != null && !preferences.get("username", null).isEmpty()) {
                email.setText(preferences.get("username", null));
                pass.setText(preferences.get("password", null));
            }
        }
    }

    @FXML
    public void signIn(ActionEvent event) throws Exception {
        String username = email.getText();
        String password = pass.getText();
        if (savein.isSelected()) {
            preferences.put("username", email.getText());
            preferences.put("password", pass.getText());
        } else {
            preferences.put("username", "");
            preferences.put("password", "");
        }


        //exception was because document had not been instantiated properly
        document.query("#ap_email")
                .setValue(username);

        document
                .query("#ap_password")
                .setValue(password);

        document
                .query("#signInSubmit").click();

        Thread.sleep(10000);

        page.close();

        webkit.shutdown();
    }
}

The issue is the document object is not instantiated properly. The one inside initialize is not the same one being accessed by signIn.

EDIT

The function page.getDocument() returns null even though the page is loaded. Also, the below code as well gives null.

page.addDocumentListener(documentLoadEvent -> {
            if (documentLoadEvent.getDocument()==null ) System.out.println("IS NULL");
        });

As I have stated in my comment, it might be a bug in the API.

Vinyl
  • 333
  • 1
  • 7
  • It didn't help. Problem is here document.query(#ap_email").setValue(username); This gives NullPointerException. – Vinceere Jun 06 '19 at 07:26
  • I have edited the answer to a new one. I have tried your code and it is even launching the login page for amazon. Please try it. – Vinyl Jun 06 '19 at 12:15
  • Thanks for the try, but you didn't get the question. It opens login form in the window, but when I press, sign in button in JavaFX UI, it gives null pointer exception, because document.query(#ap_email").setValue(username) is null. I don't need this window at all, it's only for a test, in headless mode there will be no window. – Vinceere Jun 06 '19 at 16:56
  • I have now understood what you mean. I have tried it out and it appears that ```page.getDocument()``` returns null, even though page has been loaded. I have tried using ```ui4j.jar``` versions ```2.1.0, 3.1.0 and 4.0.0``` and all return null. I have also tried ```page.addDocumentListener(documentLoadEvent -> { document = page.getDocument();if(document==null) System.out.println("IS NULL");});``` and this too is null. My conclusion is that it might be a bug in ui4j. My advice is you use any other web crawler if possible. – Vinyl Jun 06 '19 at 18:12