Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is JavaFX's WebView is flashing red and green?

I'm just starting out with JavaFX, and I wanted to put a WebView into a Window:

public static class HelloJavaFXWeb extends Application {
    @Override public void start(Stage stage) throws Exception {
        final Group root = new Group();
        Scene scene = new Scene(root, Color.DODGERBLUE);
        WebView webView = new WebView();
        webView.getEngine().load("http://www.google.com");
        root.getChildren().add(webView);

        stage.setTitle("HelloWorld in JavaFX 2.0");
        stage.setScene(scene);
        stage.show();
    }
}

Application.launch(HelloJavaFXWeb.class);

It looks ever so simple, but for some reason the draw regions are being highlighted with red and green when moving the mouse around. How can I disable the flashing colors?

moving mouse over the WebView

Update: the problem is with Groovy/Gradle interaction

Here's an extremely minimal repro
(put all this in a build.gradle and run gradle tasks --no-daemon):

buildscript {
    dependencies {
        def jvm = org.gradle.internal.jvm.Jvm.current()
        if (jvm.javaVersion.isJava7()) {
            classpath files("${jvm.jre.homeDir}/lib/jfxrt.jar")
        }
    }
}

import javafx.application.*;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

class HelloJavaFXWeb extends Application {
    @Override public void start(Stage stage) throws Exception {
        final Group root = new Group();
        Scene scene = new Scene(root, Color.DODGERBLUE);
        WebView webView = new WebView();
        webView.getEngine().load("http://www.google.com");
        root.getChildren().add(webView);

        stage.setTitle("HelloWorld in JavaFX 2.0");
        stage.setScene(scene);
        stage.show();
    }
}

Application.launch(HelloJavaFXWeb.class);

I just noticed that it outputs some logging after termination
(this was hidden before, probably because I used a Gradle daemon which swallowed it):

=========== Performance Statistics =============
Time/Invocations count:
com.sun.webpane.perf.WCFontPerfLogger.*: ...
com.sun.webpane.perf.WCGraphicsPerfLogger.*: ...

I'm using jdk1.7.0_80_x64/jre/lib/jfxrt.jar on Windows 7 x64 Ultimate.

Tried the following Java versions I had on my computer:

+-----------------+-----------+---------+
|     version     | flashing  | logging |
+-----------------+-----------+---------+
| jdk1.7.0_05_x86 |      no JavaFX      |
| jdk1.7.0_80_x64 | yes       | yes     |
| jdk1.7.0_80_x86 | yes       | no      |
| jre1.7.0_80_x86 | yes       | no      |
| jre1.7.0_80_x64 | yes       | no      |
| jre1.8.0_45_x86 | no        | no      |
| jre1.8.0_45_x64 | no        | no      |
+-----------------+-----------+---------+
like image 675
TWiStErRob Avatar asked Oct 31 '22 01:10

TWiStErRob


1 Answers

After some hours of going deep into jfxrt.jar, trial and error and with the help of @NwDx here's a summary of what's going on.

The Gradle build system messes with the JUL root logger and sets the default logging level to FINER from the original INFO. This activates a lot of internal mechanisms inside the JavaFX runtime. Most notably:

  • Clip region debug is dependent on a JUL Logger
  • PerfLoggers are dependent on some JUL Logger levels
  • lot of other unnecessary logging, probably to /dev/null

If you're careless you can use: LogManager.getLogManager().reset() to fix everything. More careful patients may continue reading.

Clip Region Debug

There's some visual debugging code guarded by a log.isLoggable(Level.FINE) in com.sun.webpane.sg.prism.WCGraphicsPrismContext.

It is a known bug filed here: https://bugs.openjdk.java.net/browse/JDK-8096483 Looking at the fix version: anything before 1.8.0u40 is susceptible to this unwanted visual debugging (see table in question). In 1.8.0u40+ you can -Dcom.sun.webkit.debugDrawClipShape=true to enable this "feature".

To be on the safe side it's worth disabling the logging for that class either by configuring JUL or:

String name = com.sun.webpane.sg.prism.WCGraphicsPrismContext.class.getName();
java.util.logging.Logger.getLogger(name).setLevel(java.util.logging.Level.OFF);

PerfLogger logging

As mentioned in the question there's some diagnostic info being spit out to stdout. PerfLogger checks the FINE level as well. The source of those messages are the following:

  • com.sun.webpane.perf.WCGraphicsPerfLogger
  • com.sun.webpane.perf.WCFontPerfLogger
  • com.sun.webpane.platform.Invoker named Locks
  • TextBreakIteratorJava in jfxwebkit.dll is named XXXX via the LOG_PERF_RECORD
    ... someone took the example literally, whyyy? :(

The easiest way to disable this is:

java.util.logging.Logger.getLogger('com.sun.webpane.perf').setLevel(Level.OFF)

because the package name is hardcoded or the Logger instances are in that package.

Everyhing else

It's probably worth making the log level higher (INFO-OFF) for all com.sun.* and javafx.* packages to prevent further weirdness or performance degradation.

For any further info see our chat.

like image 51
TWiStErRob Avatar answered Nov 08 '22 16:11

TWiStErRob