Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8209180

Media fails to load source from custom image, with jrt: URL

XMLWordPrintable

    • x86_64
    • windows_7

      ADDITIONAL SYSTEM INFORMATION :
      Windows 7 64-bit
      OpenJDK 10.0.2
      JavaFX SDK 11 11-ea+21

      A DESCRIPTION OF THE PROBLEM :
      In a modular JavaFX application developed with OpenJDK 10.0.2 and JavaFX SDK 11-ea+21, the FXML contains a MediaView that contains a MediaPlayer that contains a Media object whose source attribute is specified as a relative path. The application runs as expected when executed inside the IDE, and when executed on the command line as a modular jar. However, when a custom image is created out of the modular jar, the resulting application fails to load the FXML file.

      My debugging shows that the source parameter used to construct the Media instance is a jrt URL: jrt:/demo/assets/TextInMotion-Sample-576p.mp4, and there is no provision in the Media class to support jrt URLs.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Build the project with
      $ gradle clean build
      Run the modular jar with
      $ gradle run
      Construct a custom image with
      $ jlink --output demo --module-path C:/cygwin64/home/90019249/opt/javafx-jmods-11\;build/libs --add-modules demo --launcher demo=demo/foo.Main
      Run the custom image with
      $ demo/bin/demo

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The application runs as expected in both runs
      ACTUAL -
      The application runs as expected when ran as a modular jar.
      The application fails to start with the following exception when ran from the custom image:

      Exception in Application start method
      Exception in thread "main" 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:564)
              at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:941)
      Caused by: java.lang.RuntimeException: Exception in Application start method
              at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
              at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
              at java.base/java.lang.Thread.run(Thread.java:844)
      Caused by: javafx.fxml.LoadException:
      /demo/fxml/View.fxml:14

              at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
              at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
              at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
              at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
              at demo/foo.Main.start(Main.java:15)
              at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
              at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
              at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
              at java.base/java.security.AccessController.doPrivileged(Native Method)
              at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
              at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
              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)
              ... 1 more
      Caused by: java.lang.RuntimeException: Cannot create instance of javafx.scene.media.Media with given set of properties: [source]
              at javafx.fxml/com.sun.javafx.fxml.builder.ProxyBuilder.build(ProxyBuilder.java:272)
              at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:771)
              at javafx.fxml/javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2838)
              at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2557)
              ... 12 more


      ---------- BEGIN SOURCE ----------
      The test case project contains 6 files:
      build.gradle
      src/main/java/foo/Main.java
      src/main/java/foo/View.java
      src/main/java/module-info.java
      src/main/resources/assets/TextInMotion-Sample-576p.mp4
      src/main/resources/fxml/View.fxml

      // ****** build.gradle ****** //
      plugins {
          id 'java'
          id 'application'
      }

      ext {
          javafxHome = "$System.env.JAVAFX_HOME"
      }

      mainClassName = 'foo.Main'
      applicationDefaultJvmArgs = ['-p', "${javafxHome}/lib;build/libs", '--module', 'demo/foo.Main', '-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005']
      sourceCompatibility = '10'
      targetCompatibility = '10'

      compileJava {
          options.encoding = 'UTF-8'
          options.compilerArgs += ['-p', "${javafxHome}/lib", '--add-modules', 'javafx.graphics,javafx.fxml,javafx.media']
      }

      repositories {
          flatDir {
              dirs "${javafxHome}/lib"
          }
      }

      dependencies {
          implementation "org.openjfx:javafx.base",
              "org.openjfx:javafx.graphics",
              "org.openjfx:javafx.controls",
              "org.openjfx:javafx.fxml",
              "org.openjfx:javafx.media"
      }

      // ****** src/main/java/foo/Main.java ****** //
      package foo;

      import javafx.application.Application;
      import javafx.fxml.FXMLLoader;
      import javafx.scene.Parent;
      import javafx.scene.Scene;
      import javafx.stage.Stage;

      import java.net.URL;

      public class Main extends Application {
          public void start(Stage primaryStage) throws Exception {
              URL location = Main.class.getResource("/fxml/View.fxml");
              FXMLLoader fxmlLoader = new FXMLLoader(location);
              Parent root = fxmlLoader.load();
              Scene scene = new Scene(root, 1024, 576);
              primaryStage.setScene(scene);
              primaryStage.setTitle("FXML Demo");
              primaryStage.show();
          }
      }

      // ****** src/main/java/foo/View.java ****** //
      package foo;

      import javafx.scene.input.MouseEvent;
      import javafx.scene.media.MediaPlayer;

      public class View {
          public MediaPlayer mediaPlayer;

          public void play(MouseEvent mouseEvent) {
              System.out.println("Playing source:" + mediaPlayer.getMedia().getSource());
              mediaPlayer.play();
          }
      }

      // ****** src/main/java/module-info.java ****** //
      module demo {
          requires javafx.base;
          requires javafx.graphics;
          requires javafx.controls;
          requires javafx.fxml;
          requires javafx.media;

          exports foo to javafx.graphics, javafx.fxml;

          opens foo to javafx.fxml;
      }

      // ****** src/main/resources/assets/TextInMotion-Sample-576p.mp4 ****** //
      Obtained from https://d2qguwbxlx1sbt.cloudfront.net/TextInMotion-Sample-576p.mp4

      // ****** src/main/resources/fxml/View.fxml ****** //
      <?xml version="1.0" encoding="UTF-8"?>

      <?import javafx.scene.layout.AnchorPane?>
      <?import javafx.scene.media.Media?>
      <?import javafx.scene.media.MediaPlayer?>
      <?import javafx.scene.media.MediaView?>
      <AnchorPane prefHeight="576.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/8.0.121"
                  xmlns:fx="http://javafx.com/fxml/1" fx:controller="foo.View">
          <MediaView fitHeight="576.0" fitWidth="1024.0" onMouseClicked="#play">
              <mediaPlayer>
                  <MediaPlayer fx:id="mediaPlayer">
                      <media>
                          <Media source="@../assets/TextInMotion-Sample-576p.mp4"/>
                      </media>
                  </MediaPlayer>
              </mediaPlayer>
          </MediaView>
      </AnchorPane>

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      The work around is to leave the media file outside of the custom image and load it using a file: an http: or an https: URL. But that goes counter to the purpose of building a custom image.

      FREQUENCY : always


            almatvee Alexander Matveev
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: