Review Request: 8001533: Java launcher must launch JavaFX applications

Kevin Rushforth kevin.rushforth at oracle.com
Sat Nov 17 00:05:09 UTC 2012


Hi Dave,

I hadn't yet given much thought to retiring the JavaFX-Application-Class 
attribute, but I agree that it could be considered legacy if we do make 
the change to the javafxpackager to drop it.

I just talked with Mandy about a couple of launcher questions that she 
had relating to the main class. During the course of answering her 
questions, a couple of other questions and thoughts came up regarding 
launching via the Main-Class versus the JavaFX-Main-Class if both are 
present. I wanted to discuss these before I provide my feedback on the 
webrev itself.

There are three primary scenarios to consider when executing an 
application from a jar file. I put the most interesting one first:

1) An existing JavaFX application, packaged either using the 
javafxpackager tool or the underlying <jf:jar> task from javafx-ant.jar, 
which is used by the packager. The jar file produced by the current 
version of this tool will always have both of the following entries in 
its MANIFEST:

JavaFX-Application-Class: mypkg.MyApp
Main-Class: com/javafx/main/Main

where "mypkg.MyApp" is the actual name of a public class that extends 
"javafx.application.Application". The packager inserts the 
"com/javafx/main/Main.class" file into the jar file. That class does not 
exists in the JavaFX runtime jar file, jfxrt.jar (which is currently in 
JRE/lib and is moving to JRE/lib/ext).

When this jar file is launched today with "java -jar myjar.jar" the java 
launcher does the usual thing with this jar file and calls the 
main(String[]) method of the com.javafx.main.Main class, which will do 
the following:

A) Locate the javafx runtime and construct a URLClassLoader with that 
jar and the deploy jars on the classpath. Locating the JavaFX runtime 
jar is no longer necessary, but adding the deploy.jar is still needed 
unless we want to regress from current behavior. As an aside, Mandy 
found a potential bug by code inspection in the way the JavaFX main 
launcher class constructs the class loader -- it uses "null" as the 
parent rather than ClassLoader.getSystemClassLoader(), which may be the 
root cause of RT-20988 <http://javafx-jira.kenai.com/browse/RT-20988>.

B) Read the manifest for the JavaFX-Main-Class, the 
JavaFX-Preloader-Class, and the JavaFX-Class-Path (which the 
javafxpackager supports to allow a developer to specify additional 
dependent jar files).

C) Sets up a network proxy unless the JavaFX-Feature-Proxy manifest 
entry is set to something other than "auto" (auto is the default).

D)  Call into the platform LauncherImpl.launchApplication method, 
passing in the application class, the preloader class (if specified in 
the jar manifest), and the command line arguments.

So here is the dilemma. When coming up with the requirements for the 
launcher, we had defined that the JavaFX-Application-Class should be 
called in this case for existing FX applications, taking precedence over 
the Main-Class. I still believe that is the best choice, but it isn't 
without drawbacks (see below). If the new JDK8 java launcher were to 
call into the main method of the class specified by Main-Class, ignoring 
the JavaFX-Main-Class, then we would not get any benefit out of the new 
launcher for existing applications. The main method of the FX Main 
launcher class included in the jar will use whatever the current 
mechanism is for locating the JavaFX classes, which seems undesirable 
since it adds those jars to a new URLClassLoader that it creates rather 
than just using the existing class loader. Further, we would be stuck 
with any bugs that we might find in that old, "statically linked" Main 
FX launcher, such as the bug that Mandy found.

However, while we no longer need or want the "locate jfxrt.jar and add 
it to the classpath" part of what the existing Main class does, it does 
do a couple other things that are useful. If the new java launcher calls 
directly into the JavaFX runtime LauncherImpl.launchApplication method, 
bypassing the main method of the packaged Main class, we will have no 
good way -- and probably not enough information -- to know whether or 
not to set up the proxy configuration and add additional jars onto the 
classpath (deploy.jar and any jar files specified by JavaFX-Class-Path 
at a minimum). Currently you don't support the JavaFX-Preloader-Class 
either, but that is more easily solvable.

Either way, it seems like we will have some compatibility issues and 
functionality concerns. I think this is solvable, perhaps by defining a 
new variant of LauncherImpl.launchApplication that accepts more 
arguments (like a map of the manifest entries), but I wanted to raise 
the issue.


The other two cases are much easier:

2) A Java application using some JavaFX that is packaged by just jar-ing 
up the class files and setting a main class via the "Main-Class" jar 
attribute in the MANIFEST, and without a "JavaFX-Main-Class" aattribute. 
Running "java -jar myapp.jar" will just launch an run the app by calling 
into the "public static void main(String[])" method.

With the modified JDK8 launcher, the only question is this: if the 
specified Main-Class both extends javafx.application.Application *and* 
has a main method, which one should take precedence? I can see arguments 
for either one. For consistency with applets and webstart applications, 
it seems that launching it as an FX application will provide the most 
consistent experience. This is what your webrev will do which seems good.

Note that the same concern about lack of support for 
JavaFX-Preloader-Class, etc, exists in this case as in scenario #1.


3) A JavaFX application, packaged manually or by a modified version of 
the JavaFX packager, without a Main-Class (no such modification has been 
specified, but could be considered once the java launcher is modified to 
recognize JavaFX classes as an alternative to dropping 
JavaFX-Application-Class and just using the MainClass). In this example, 
the MANIFEST of the jar file would have the JavaFX-Application-Class to 
specify the subclass of javafx.application.Application that should be 
launched. If this case is supported, it would be simple and would do 
what we want, but might not actually occur depending on other decisions 
that are made.


Mandy can chime in with her thoughts on this, but it seems that we need 
to answer the questions in scenario #1 before proceeding. Do you think 
it might be better to wait until these can be resolved even it means 
missing M5 (the move of jfxrt.jar to lib/ext won't happen for M5 
anyway...it is scheduled for M6)? Or do you think they can be resolved 
with minor changes to the existing functionality?

-- Kevin



David DeHaven wrote:
>>> I cleaned it up quite a bit, I think it looks a lot better now:
>>> http://cr.openjdk.java.net/~ddehaven/8001533/webrev.1/
>>>
>>> The comments still need some attention, I'll get that first thing on the morrow.
>>>
>>> -DrD-
>>>
>>>       
>> I haven't done a detailed code review but I'm wondering about preferring JavaFX-Application-Class over Main-Class. I realize there may be some history here, perhaps with the javafxpackager tool, but I'm just concerned that the JAR File specification specifies the Main-Class attribute, now it will be usurped and ignored if this custom attribute is present.
>>     
>
> JavaFX-Application-Class is for backwards compatibility with existing applications, my understanding is it's being deprecated. Moving forward JavaFX applications will only use Main-Class. Kevin can correct me if I'm wrong :)
>
> Am I wrong in thinking there should be no impact on profile support if it's being deprecated?
>
> -DrD-
>
>   



More information about the core-libs-dev mailing list