JCEF functions only work second time in Netbeans RCP Project

Having problems with building or using the JCEF Java binding? Ask your questions here.

JCEF functions only work second time in Netbeans RCP Project

Postby Daki » Fri Oct 02, 2020 2:29 am

I recently integrated jcef in a Netbeans (RCP) Application Project (Java: JDK11).

The Browser Window is shown in a Netbeans TopComponent and generally works just fine.

However I have several rather small, but nasty Bugs that I noticed which are always following the same pattern:
Whatever Code I execute that concerns the jcef Browser always only works when I execute it a second time and is all but ignored the first time around.
However there are no error messages or logs or any thing like that and the code seems to be executed when I go through it with the debugging tool.
I currently believe the problem might lie in Netbeans RCP and jcef working together.

I searched for similar problems on this forum but came up with nothing useful.


Three examples:

1. Implementing a return button: This just checks whether the CefBrowser Instance returns true for browser.canGoBack(). If it returns true a Button is activated. And whilst the return from canGoBack() is correct all the time, it activates the Button just after the second time that this function returns true. From there on out it works just fine.
2. Implementing a "go to" function: This function just takes you to a specified other website than the startpage. Again works fine from the 2nd time onwards, but the first time the code is simply ignored. (although I confirmed via Debugger that the code is executed without errors even the first time around)
3. Implementing a Login Dialog: If the browser notices that Authentication is required, this opens up a Dialog where the user can enter BASIC Credentials. And again the dialog gets opened, the credentials are returned correctly (confirmed via Log), are handed over to the appropriate function and it works for the second try but not the first. (credentials were identical) Indeed I confirmed via Wireshark, that the first time that callback.Continue(ad.getUsername(), ad.getPassword()); is executed, nothing at all is actually send to the server....

Code for the third example:

Code: Select all
cefClient_.addRequestHandler(new CefRequestHandlerAdapter() {
            @Override
            public boolean getAuthCredentials(CefBrowser browser, String origin_url, boolean isProxy, String host,
                    int port, String realm, String scheme, CefAuthCallback callback) {
               
                AuthenticationDialog ad = new AuthenticationDialog();               
                ad.authenticate(); // Shows Login Dialog
                LOGGER.log(Level.INFO, String.format("--->%s:%s", ad.getUsername(), ad.getPassword())); //This confirms that the variables are indeed correct even the first time around
                callback.Continue(ad.getUsername(), ad.getPassword());
                return true;
            }
        });


Sadly I don't have any clue anymore what could possibly cause these problems.

If anyone of you has had these same problems or has any idea as to how to fix them or even where to start looking for a fix I would very much appreciate your comments.

Thanks in advance!
Daki
Newbie
 
Posts: 2
Joined: Fri Oct 02, 2020 1:59 am

Re: JCEF functions only work second time in Netbeans RCP Pro

Postby magreenblatt » Fri Oct 02, 2020 11:33 am

Have you tried debugging the JCEF and native layers to see what’s happening with your first call?
magreenblatt
Site Admin
 
Posts: 11088
Joined: Fri May 29, 2009 6:57 pm

Re: JCEF functions only work second time in Netbeans RCP Pro

Postby Daki » Mon Oct 12, 2020 4:34 am

Thanks for the tip!

I found the answer(s) to the afore mentioned questions. In case someone else will stumble upon similar issues in the future I'm going to shortly summarize what fixed it for me.

Apparently most of the problems I faced arose from threading problems. It seems like when you execute a command on the jcef browser while it's thread is still working on something, your command will not be executed, but there also won't be any error messages or other unwanted behaviour.

Example for the second problem:
When the `go(url)` command was executed the browser had not finished loading the initial home page completely yet. That's why the command was ignored.
To fix this I added a simple String variable that will save the URL that someone wants to load until the browser has finished loading the previous page.
Only then will this url be loaded in the browser and consequently be deleted from the variable.
This could of course also be done with something like a list, but I can't think of a scenario where that would be useful.
Checking weither browser is done loading should be done in the overridden method `onLoadingStateChange` of the `CefLoadHandlerAdapter`.
Code: Select all
    client_.addLoadHandler(new CefLoadHandlerAdapter() {
            @Override
            public void onLoadingStateChange(CefBrowser browser, boolean isLoading,
                    boolean canGoBack, boolean canGoForward) {
                if (!isLoading) {
                    browser_ready = true;
                    if (goOnReady != null) {
                        goURL(goOnReady);
                    }
                }
            }
        });

A similar issue was present with the first example from the original question.
Activating the "Back" button within the afore mentioned `onLoadingStateChange` via the `canGoBack` variable did the trick for me in the end.


Now the third example (the login dialog showing twice) turned out to be a problem that was was also present in the official detailed example code from the jcef github page.
This problem seems like it might be a threading problem again, but I'm not sure this time.
As a workaround I implemented the following solution:
- add class variables for username and password
- if these variables are empty start the login dialog within the `getAuthCredentials` method (see original question) and save the given username and password in these class variables.
- then execute `browser.reload();`
- the browser will then go through authentication again, but this time the variables won't be empty and you can hand them to `callback.Continue(username, password);` thus only showing one login dialog to the user.

This process is also very quick so the user want be able to notice the reload.
Daki
Newbie
 
Posts: 2
Joined: Fri Oct 02, 2020 1:59 am


Return to JCEF Forum

Who is online

Users browsing this forum: No registered users and 3 guests