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

Breaking change: Application.launch() does no longer return

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • fx2.0
    • javafx
    • JavaFX beta b36

      From build 36 on Application.launch() does no longer return until the application is running. This introduces a breaking change, specifically for my JFX-Clojure Lib.
      In the current situation some developers who don't use Java as their JVM languages are forced to write Java code in order to be able to work with JFX.
      The reason for that is that other than in Swing one can not simply create an instance of some class at runtime (JFrame) and work with that, but one has to extend the Application class.
      (In the case of Clojure there would also the solution to generate such a class, but this still needs to be compiled ahead of time and thus is still not dynamic.)

      In practice Clojure users could use my lib, which can solve this problem (but only by jumping through hoops). However, people who just would like to try out JFX from Clojure without some libs will be very disappointed that it won't work out of the box. In a dynamic language what we want to do is to create an instance of a class at runtime, which is a stage in the case of a JFX app. Until b36 I had a proxy class with a static launchApplication method which takes a clojure.lang.IFn (a Clojure function). This launchApplication method set a private static variable to store my fn and then it called Application.launch(new String[0]);
      In the start() method I invoked the Clojure function, given as an argument to launchApplication: fn.invoke(primaryStage);
      This worked, but is broken by b36, because it does no longer return. In principle this is not such a big deal, because I updated my code to now run Application.launch() in a separate thread. But this still introduced a leaky abstraction, because now an application developer is responsible to take care in his init function fn to store the primaryStage. While Application.launch() was returning this was not required because my lib code would simply return that object.

      I remembered the posting of Richard, Jasper and Jonathan: http://fxexperience.com/2011/05/javafx-2-0-beta-is-available/
      They asked that "[...] if you have use cases that our APIs prohibit (as opposed to API we just need to add) please please please! file these in JIRA! The reason we've released the beta is to get exactly this kind of feedback."

      So, here is my feedback :-)

      To solve this issue I see several options. One of them would be that you introduce a static method to the Application class which returns the primary Stage. This would eliminate for users of Clojure or Ruby the need to write their own proxy classes in Java. Also the official website provides a Ruby example where a proxy class is used: http://download.oracle.com/javafx/2.0/jruby/jfxpub-jruby.htm
      I did not try that example, but I am not certain that this official example still is working.
      Another solution would be to call a static method of the Application class that takes a Runnable/Callable which would do what the start() method currently is doing. A Callable would be nicer, because that functions should return its primary Stage. Those are just two ideas, but maybe you have something in mind that would work better.

            kcr Kevin Rushforth
            athiemejfx Andre Thieme (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: