JDK-8134922 : Resource files are not loaded by the WebEngine when bundled in a jar file
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 8u60
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-09-01
  • Updated: 2015-11-05
  • Resolved: 2015-11-05
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
Windows 7 Ultimate 64 bit SP1



A DESCRIPTION OF THE PROBLEM :
WebEngine does not load a resource file ( javascript, css, image) when this file is referenced from within a html file and when the resource files are packaged in a jar file. 

For example this html file that references a javascript file foo.js and loads an image file test.png :

<===== main.html ======>
<html>
    <head>
        <script type="text/javascript" src="foo.js"></script>
    </head>

    <body>
        This is my editor
        <p>
        <img src="test.png" alt="test1"/>
    </body>
</html>
<=======End of main.html ==============>

The javascript file foo.js in the root folder

<=====foo.js ==============>
var foo;

function foo()
{
}
<=========End of foo.js ======>

Let have an image file test.png


Here the java class test:

<================ TestWebEngine.java ===========>

import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class TestWebEngine extends Application
{
    private WebView mWebView;
    
    @Override 
    public void start(Stage stage)
    {
        mWebView = new WebView();
        WebEngine webEngine = mWebView.getEngine();
        
        setupChangeListeners();
        webEngine.load(getClass().getResource("main.html").toExternalForm());
        JSObject win = (JSObject) mWebView.getEngine().executeScript( "window" );
        win.setMember( "console", new Console() );
        
        stage.setScene(new Scene(mWebView, 1280, 900));
        stage.show();
    }
    
    private void setupChangeListeners()
    {
        ChangeListener<Worker.State> webEngineLoadListener = createWebEngineLoadListener();
        ReadOnlyObjectProperty<State> webEngineLoadStateProperty = 
            mWebView.getEngine().getLoadWorker().stateProperty();
        webEngineLoadStateProperty.addListener( webEngineLoadListener );
    }
    
    private ChangeListener<State> createWebEngineLoadListener()
    {
        return new ChangeListener<Worker.State>()
        {
            @Override
            public void changed( ObservableValue<? extends State> loadStateProperty,
                                 State oldLoadState,
                                 State newLoadState )
            {
                switch( newLoadState )
                {
                    case SUCCEEDED:
                        handleLoadComplete();
                        break;
                    default:
                        return;
                }
            }
        };
    }
    
    private void handleLoadComplete()
    {
        System.out.println( "main.html loaded - checking if foo() is defined" );
        executeScript( "console.log(\'foo =\' + foo );" );
    }

    private Object executeScript( String script )
    {
        return mWebView.getEngine().executeScript( script );
    }

    public static class Console
    {
        public static final String MEMBER_NAME = "console"; //$NON-NLS-1$
        
        public void log( Object message )
        {
            System.out.println( message );
        }
    }
    
    public static void main(String[] args)
    {
        launch(args);
    }
} 

<============End TestWebEngine.java===============>


REGRESSION.  Last worked in version 8u40

ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Bundle the provided java class and the resource files in a jar file,
run java -jar file.jar

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The web page is loaded from the html file
The image is loaded from png.test
The foo.js is loaded and the foo() function is defined
ACTUAL -
The web page is loaded from the html file
The image is not loaded
The javascript file is not loaded and the foo() function is not defined

REPRODUCIBILITY :
This bug can be reproduced always.


Comments
Fixed as part of JDK-8136466 http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/d4f8c9496683
05-10-2015

On a somewhat related note, we will need to make a similar modification for Jigsaw in JDK 9 to support the "jrt:" protocol.
01-10-2015

I tested this on Mac OS X, and verified that the test program works in 8u45, fails in 8u60 and 9, and works with your patch applied. +1 to push into 9-dev and 8u-dev
01-10-2015

Since this is a duplicate of JDK-8136466, then it can be closed as a duplicate.
01-10-2015

Sub resource which is exported from JAR not loaded in webview
22-09-2015