This discussion is archived
1 2 3 Previous Next 39 Replies Latest reply: Jan 4, 2013 2:12 PM by ryan29 Go to original post RSS
  • 15. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    swpalmer Newbie
    Currently Being Moderated
    Created RT-23291 to track that one.
  • 16. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    ryan29 Explorer
    Currently Being Moderated
    >
    I had thought while getting the bundling working on earlier JREs that the jfxrt.jar was sneaky and attempted to load the native libraries by trying a path relative to where the jar lived. I.e. the absolute version of ../bin/xxxx.dll using System.load and only if that failed did it fall back to a more general System.loadLibrary - maybe I have it backwards?>
    I'm pretty sure that's how it worked. I even made a special note about it in my comments when I was getting things working. I was using this configuration with JavaFX 2.0.2.

    http://forums.gradle.org/gradle/topics/is_anyone_using_gradle_to_build_javafx_2_0_projects

    This is a useful blog post on the way those paths work. The below code should give you a decent idea of the search order for native libraries. Paste it at the top of your main method temporarily and run your app.

    http://fahdshariff.blogspot.ca/2011/08/changing-java-library-path-at-runtime.html
    //print user.dir which is the working dir
    System.out.println("relative library paths start from:");
    System.out.println(" " + System.getProperty("user.dir"));
    System.out.println();
    
    //this comes from sun.boot.library.path
    final Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths");
    sysPathsField.setAccessible(true);
    
    //this comes from java.library.path
    final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths");
    usrPathsField.setAccessible(true);
    
    //get array of paths
    final String[] sysPaths = (String[]) sysPathsField.get(null);
    final String[] usrPaths = (String[]) usrPathsField.get(null);
    
    //print sys path
    System.out.println("sys_paths include:");
    for(String s : sysPaths) {
         System.out.println(" " + s);
    }
    
    System.out.println();
    
    //print usr path
    System.out.println("usr_paths includes:");
    for(String s : usrPaths) {
         System.out.println(" " + s);
    }
    And here's an extra snippet from Classloader.loadLibrary
    for (int i = 0 ; i < sys_paths.length ; i++) {
         File libfile = new File(sys_paths, System.mapLibraryName(name));
         if (loadLibrary0(fromClass, libfile)) {
              return;
         }
    }
    if (loader != null) {
         for (int i = 0 ; i < usr_paths.length ; i++) {
              File libfile = new File(usr_paths[i], System.mapLibraryName(name));
              if (loadLibrary0(fromClass, libfile)) {
                   return;
              }
         }
    }
    I think the problem you're having is that +sun.boot.library.path+ gets searched before +java.library.path+ and +sun.boot.library.path+ includes the +bin+ directory of the JRE which now has the JavaFX native libraries in it.  I don't think using +java.library.path+ is going to work any more.
    
    However, the layout of your distribution directory..
    
    {quote:title=swpalmer wrote:}
    Java/bin/*.dll (all the DLLs from the JavaFX 2.1 runtime)
    Java/lib/jfxrt.jar
    MyApp.jar
    {quote}
    
    .. should still work unless jfxrt.jar no longer searches +../bin/*+ (relative to itself) when loading native libraries.  Keep in mind it's impossible to know for sure how libraries are loaded without access to the source and the assumption that libraries get loaded from +../bin/*+ first is based on my own (limited) testing.
    
    Edited by: ryan29 on Jul 7, 2012 12:46 AM - Fixed links.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
  • 17. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    jsmith Guru
    Currently Being Moderated
    In Jira http://javafx-jira.kenai.com/browse/RT-16435 "Maven support (loading DDLs)"
    Kevin Rushforth added a comment - Aug, 30 2011 11:02 AM
    The native library loader will first look in ../lib/ -- failing that it will use System.loadLibrary which looks in java.library.path
    I guess it changed and no longer works that way.
  • 18. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    swpalmer Newbie
    Currently Being Moderated
    My actual app is a little more complicated, lots of "plugin modules" I think Maven has bundled another copy of jfxrt.jar with my UI module and it may be loading from that jar first thus breaking the relative path search order for loading the native libraries.. If that's it then this isn't a real issue. I need to fix that part of my build and try again.
  • 19. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    swpalmer Newbie
    Currently Being Moderated
    It turns out this was my issue. Another copy of jfxrt.jar was loaded first and it wasn't in the correct relative position to the bin folder to get the loadLibrary hackery to work.
    I'm closing issue RT-23291.
  • 20. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    899259 Newbie
    Currently Being Moderated
    @jsmith

    I just read your Ant post for the first time. It was excellent. So my apologies for the rant on Ant. I was misinformed.

    I'm deeply relieved to see that the other related issues, detailed in this thread, are being seriously addressed in time for the 2.2 release.

    Should Oracle fix webstart and make JavaFx packaging and deployment a no-brainer, I think JavaFx will win a lot of new fans.
  • 21. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    gimbal2 Guru
    Currently Being Moderated
    javawerks wrote:
    Should Oracle fix webstart and make JavaFx packaging and deployment a no-brainer, I think JavaFx will win a lot of new fans.
    I'd not get my hopes up. The market seems to have settled on Javascript, dubiously covered under the lie that is "html 5", being the answer to all problems in the world. Which I find extremely funny since not a few years ago everyone was deadly frightened of it and had to install javascript blockers.
  • 22. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    899259 Newbie
    Currently Being Moderated
    @gimbal2

    Having done Java and Swing since '97; yes, I would agree that one should temper one's hopes.:)

    That said, I sense, given the movement away from Java in recent years ( not from the JVM, though ), that Oracle fully understands this year and next are huge. Oracle must deliver. Excuses will no longer be tolerated, accept by those companies who dare not, grow not and will soon come to pass.

    FWIW, last year, I accidentally got trapped into one of those Html5 apps (JS, CSS3, Node.js, Socket.io...you name it JS file). It was an amazing experience.;)

    Here's to hoping! Cheers!
  • 23. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    ryan29 Explorer
    Currently Being Moderated
    Getting back to the original problem, is there a way I can get the bundled jfxrt.jar on the classpath without using an absolute path?

    I may be misunderstanding how some of the JavaFX stuff works, so please correct me if any of the following feedback is based on incorrect assumptions.

    The JavaFX packaging tools seem like they could be convenient, but I don't necessarily want to use them. This is especially true during the development phase of a project. My development workflow shouldn't have to include running the JavaFX packaging tool and starting my application via the custom bootstrapping code it generates. It interacts poorly with existing tooling like starting my application with a debugger, starting my application with a profiler, automatically building installers for my application, etc.. And really, we're talking about adding a single JAR to the classpath as of 7u6.

    As of 7u6, there's no reason developing, running, and deploying a JavaFX application needs to be any different than a normal Java application. The custom bootstrapping code generated by the JavaFX packaging tool needs to become an option for packaging an application. As a developer I should be able to ignore it. Building and running a JavaFX application should work seamlessly with existing build tools such as the Maven exec plugin, the Maven assembly plugin, the Gradle java plugin, the Gradle application plugin, etc.. The very most I should be required to do as a developer is add a JVM argument to indicate I'm using JavaFX.

    I know most of the existing implementation was a necessary evil before JavaFX was co-bundled into the JRE properly, so hopefully seamless integration into the existing Java ecosystem has been the plan all along and things will improve now that the co-bundling is done.
  • 24. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    gimbal2 Guru
    Currently Being Moderated
    Update 6 is not final yet. The only thing to do is wait and see what is the truth once it is properly packaged up and released to the public. Perhaps all the things you say should be true will be true. At this point you'll be inventing workarounds for something which is still being hammered on as we speak.
  • 25. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    swpalmer Newbie
    Currently Being Moderated
    There is the javafxpackager tool.. but it doesn't fit well into tool chains other than Ant.
    There is some magic launcher that it injects into the jar that does the right thing... I still need to experiment with it. NetBeans 7.2 will build your jar properly with the launcher embedded if you make a JavaFX project. If you have a Swing project that uses JFXPanel as I do, then you have to hack something in.

    I'm still trying to figure out javafpackager. It seems to duplicate a lot of functionality (e.g. "jar" and "jarsigner") and add some bits for everything from HTML/JNLP generation to converting CSS files to a binary form.

    I still think it would make more sense to have left the existing tools to do their job and have javafxpackager act on jar files so you would effectively run it between the "jar" command and "jarsigner" command.

    See:

    http://docs.oracle.com/javafx/2/deployment/packager.htm
  • 26. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    ryan29 Explorer
    Currently Being Moderated
    >
    I still think it would make more sense to have left the existing tools to do their job and have javafxpackager act on jar files so you would effectively run it between the "jar" command and "jarsigner" command.
    >
    I remember seeing JavaFX specific entries in the JAR manifest when I was playing with it. I agree with you that it's weird. It also breaks existing tooling. For example, the Maven assembly plugin and the Gradle application plugin aren't going to work with JARs generated by the JavaFX packaging tool, are they?

    To me, it seems like the javafxpackager plugs in right at the top of the build toolchain and takes over the whole build process. Am I wrong?
  • 27. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    jsmith Guru
    Currently Being Moderated
    the Maven assembly plugin . . . aren't going to work with JARs generated by the JavaFX packaging tool, are they?
    The maven assembly plugin is pretty configurable and is able to be made to get around this, but, yeah it is a bit of a pain.
    it seems like the javafxpackager plugs in right at the top of the build toolchain and takes over the whole build process. Am I wrong?
    I created RT-23387 "Allow JavaFX packaging tools to embed launchers in existing jars" to help address this concern.
    There is some magic launcher that it injects into the jar that does the right thing...
    The custom bootstrapping code generated by the JavaFX packaging tool needs to become an option for packaging an application. As a developer I should be able to ignore it.
    The three things which the custom bootstrapping code (currently) provides are:
    1) checking for the JavaFX runtime.
    2) guiding the user through any necessary installations.
    3) setting the system proxy for Java.

    If you don't care about these then you don't need a javafx tool packaged jar.
    For me, these things are only important when packaging for deployment, but not during development.
    So I use the javafx sdk tools for deployment packaging, but for development just use an intellij IDE project build and run which does not include those tasks.

    Also of interest in understanding the javafx deployment tools and how they may fit into existing build processes is the info at:
    https://blogs.oracle.com/talkingjavadeployment/entry/packaging_swing_apps_with_integrated
  • 28. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    ryan29 Explorer
    Currently Being Moderated
    >
    The three things which the custom bootstrapping code (currently) provides are:
    1) checking for the JavaFX runtime.
    2) guiding the user through any necessary installations.
    3) setting the system proxy for Java.

    If you don't care about these then you don't need a javafx tool packaged jar.
    >
    That's good to know and makes me less hesitant to ignore jfxpackager and do my own thing.

    The one thing I still don't understand is how jfxrt.jar is getting on the classpath. I'm guessing there must be a custom ClassLoader somewhere in the web start / bootstrapping plumbing that does it. If that's the case and the custom ClassLoader is, to give an overly simplified example, checking for JRE > 7u6 and adding ${java.home}/lib/jfxrt.jar to the classpath, that's going to make it more difficult for me to launch a JavaFX program 'by hand'.

    To get jfxrt.jar on the classpath manually, I see five possibilities:

    1) Know the absolute path of the JRE.
    2) Bundle a private JRE so jfxrt.jar can be referenced relative to the working directory.
    3) Use OS specific environment variables to launch the application.
    4) Write a custom ClassLoader to add ${java.home}/lib/jfxrt.jar to the classpath.
    5) I'm overlooking a simple solution that's obvious to everyone else.

    The second option is 'good enough' for me, but I'd much rather pass a JVM argument that says, "hey, set up up the bundled JavaFX runtime for me too please." That way I don't have to strong arm jfxrt.jar onto the classpath or worry about configuring something improperly due to a lack of understanding of how it all works.
  • 29. Re: JDK 7u6 JavaFX integration - Is jfxrt.jar supposed to be on the classpath?
    ryan29 Explorer
    Currently Being Moderated
    Today I played around with creating a Gradle config to work with the bundled jfxrt.jar in 7u6. It doesn't use any of the built in tooling. It works at development time. I can compile and run an application using the bundled jfxrt.jar. I also know I could make it work with an installer (Install4J) that uses a private, bundled JRE (with a bit of hacking) since the classpath can be built from relative paths during installation.

    Here is the build config that I would use right now:
    repositories {
        // the flatDir repository is used to resolve the jfxrt.jar file
        // that's bundled with the currently used jdk
        flatDir dirs: System.getProperty("java.home") + "/lib/"
    }
    
    apply plugin: 'java'
    
    configurations {
        // the provided configuration is used to configure dependencies that
        // will NOT be bundled with the application
        provided
    
        sourceSets {
            main {
                compileClasspath += configurations.provided
            }
        }
    }
    
    apply plugin: 'application'
    mainClassName = "Main"
    
    // Add the dependencies from provided to the runtime classpath before
    // running the application.  This is a dirty hack to get jfxrt.jar onto
    // the classpath.  It only works because it's possible to determine the
    // location of the JRE via the java.home system property prior to
    // running the application.
    //
    // As far as I know, there's no way to tell the 'java' command to use
    // a resource from a path relative to itself.  For example, it's not
    // possible to use something like:
    //
    //  java -cp ${java.home}/lib/jfxrt.jar Main
    //
    // That probably wouldn't be a good thing to do anyway.
    //
    // Other tasks provided by the application plugin will not work.
    // Specifically, the installApp task won't work unless it is patched
    // to make a special exception for jfxrt.jar (unlikely to happen).
    // Any other tasks that depend on the installApp task, such as the
    // dist task are also broken.  This includes my own custom Install4J
    // tasks since I layered them on top of the existing tooling provided
    // by the application plugin.
    run.classpath.add(configurations.provided)
    
    dependencies {
        // This resolves to JAVA_HOME/lib/jfxrt.jar.  It will be expanded
        // to an absolute path.
        provided ':jfxrt:'
    }
    Here is the build config I would use if we could pass the JRE an argument to enable JavaFX (include the appropriate .jars on the classpath automatically). It's still not ideal, but it solves some problems for me. Mainly, I don't have to worry about how the JavaFX libraries are being dealt with at runtime, so there's no chance I can screw it up.

    NOTE: -XX:+EnableJavaFX is not a real option. I'm only using it as an example since it was suggested earlier in this thread that a JVM argument could make things easier for those of use that don't want to use jfxpackager.
    repositories {
        // the flatDir repository is used to resolve the jfxrt.jar file
        // that's bundled with the currently used jdk
        flatDir dirs: System.getProperty("java.home") + "/lib/"
    }
    
    apply plugin: 'java'
    
    configurations {
        // the provided configuration is used to configure dependencies that
        // will NOT be bundled with the application
        provided
    
        sourceSets {
            main {
                compileClasspath += configurations.provided
            }
        }
    }
    
    apply plugin: 'application'
    mainClassName = "Main"
    
    // All existing tooling must account for jvm args anyway, so this would
    // get passed through all existing tooling without any changes to the
    // existing tooling.
    run.jvmArgs += "-XX:+EnableJavaFX"
    
    dependencies {
        // This resolves to JAVA_HOME/lib/jfxrt.jar.  It will be expanded
        // to an absolute path.
        provided ':jfxrt:'
    }
    This is the build config I would use if we could pass both the compiler and the runtime an argument to enable JavaFX.
    apply plugin: 'java'
    
    // Tell the compiler we want to use the bundled JavaFX libs
    compileJava.options.compilerArgs = [[value: "-XX:+EnableJavaFX"]]
    
    apply plugin: 'application'
    mainClassName = "Main"
    
    // Tell the 'java' command we want to use the bundled JavaFX libs
    run.jvmArgs += "-XX:+EnableJavaFX"
    This is the build config I would use if existing Gradle plugins were modified to pass those arguments (compiler + runtime) based on an 'enableJavaFX' switch.
    apply plugin: 'java'
    apply plugin: 'application'
    mainClassName = "Main"
    
    // I don't know if this would actually apply to the variable for both plugins, but
    // I think it would.
    enableJavaFX = true
    Edited by: ryan29 on 19-Jul-2012 19:14

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points