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

Launcher causes lingering busy cursor

    XMLWordPrintable

Details

    • b27
    • x86_64
    • windows_10

    Backports

      Description

        ADDITIONAL SYSTEM INFORMATION :
        Windows 10.
        Java 17.

        A DESCRIPTION OF THE PROBLEM :
        Normally, when an application is launched from the desktop or start menu on Windows, the system turns the mouse cursor into a busy indicator (e.g. an hourglass or circle) while the application is launching and restores the regular cursor once the application has finished launching.

        This works as expected for Java applications launched using "javaw.exe".

        However, when a Java application is packaged with jpackage and launched using the exe launcher that jpackage creates, the busy cursor lingers for several seconds after the application's window shows up on screen.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Take any small Java application, one that launches quickly.
        2. Package it on Windows using jpackage with the "--win-shortcut" option.
        3. Install the packaged application.
        4. Launch the packaged application from the desktop using the shortcut.

        Below is a WSH script which, when executed with "cscript build.js" and assuming HelloSwing.java contains some simple Swing application, performs the first 3 steps and additionally creates the shortcut "ExpectedBehavior.lnk" for comparison (which launches the same JAR using "javaw").

            var shell = WSH.CreateObject("WScript.Shell")
            var shellapp = WSH.CreateObject("Shell.Application");
            var fs = WSH.CreateObject("Scripting.FileSystemObject")

            function main() {
              withTempDir(function(tempdir) {
                build(tempdir)
                package(tempdir)
              })

              install("HelloSwing-1.0.msi")

              createSystemJavaAppShortcut()
            }

            function build(appdir) {
              run("javac HelloSwing.java")
              var jarPath = joinPath(appdir, "hello.jar")
              run("jar cfe " + quote(jarPath) + " HelloSwing HelloSwing.class")
            }

            function package(appdir) {
              var cmd = "jpackage"
              cmd += " -i " + quote(appdir)
              cmd += " --main-jar hello.jar"
              cmd += " --type msi --win-per-user-install --win-shortcut"
              cmd += " --add-modules java.base,java.desktop"
              run(cmd)
            }

            function install(msiPath) {
              run("msiexec /i " + quote(msiPath) + " /norestart")
            }

            function createSystemJavaAppShortcut() {
              var exePath = getDesktopShortcutPath("HelloSwing.lnk")
              var installDir = fs.GetParentFolderName(exePath)
              var desktopPath = shell.SpecialFolders("Desktop")
              var shortcutPath = joinPath(desktopPath, "ExpectedBehavior.lnk")
              var jarPath = joinPath(installDir, "app", "hello.jar")
              var shortcut = shell.CreateShortcut(shortcutPath)
              shortcut.TargetPath = "javaw"
              shortcut.Arguments = "-jar " + quote(jarPath)
              shortcut.Save()
            }

            function getDesktopShortcutPath(name) {
                var desktop = shellapp.Namespace(0)
                var shortcut = desktop.ParseName(name).GetLink
                return shortcut.Path
            }

            function withTempDir(func) {
              var path = joinPath(fs.GetSpecialFolder(2), fs.GetTempName())
              fs.CreateFolder(path)
              try {
                func(path)
              }
              finally {
                try {
                  fs.DeleteFolder(path)
                }
                catch (ex) {
                  print("Failed to delete temp directory.")
                }
              }
            }

            function joinPath() {
              var parts = Array.prototype.slice.call(arguments, 0, arguments.length - 1)
              var last = arguments[arguments.length - 1]
              if (parts.length === 0)
                return last
              else
                return fs.BuildPath(joinPath.apply(null, parts), last)
            }

            function quote(s) {
               return "\"" + s + "\""
            }

            function run(command) {
              print("Running command: " + command)
              var result = shell.Run("cmd /c " + command, 0, true)
              if (result !== 0) throw new Error("Command failed: " + command)
            }

            function print() {
              var args = Array.prototype.slice.call(arguments)
              WScript.Echo(args.join(" "))
            }

            try {
              main()
            }
            catch (ex) {
              throw ex
            }


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        It should behave as it does when launched using "javaw.exe": The busy cursor should appear briefly while the application is launching. The regular mouse cursor should be restored when the application window is displayed.
        ACTUAL -
        The busy cursor remains for several seconds after the application window has shown up on screen.

        ---------- BEGIN SOURCE ----------
        import javax.swing.*;

        import static javax.swing.BorderFactory.createEmptyBorder;
        import static javax.swing.WindowConstants.*;

        public class HelloSwing {
            public static void main(String[] args) {
                SwingUtilities.invokeLater(() -> {
                    var label = new JLabel("Hello Swing!");
                    label.setBorder(createEmptyBorder(30, 30, 30, 30));
                    var frame = new JFrame("Hello Swing!");
                    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
                    frame.add(label);
                    frame.pack();
                    frame.setVisible(true);
                });
            }
        }

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

        FREQUENCY : always


        Attachments

          1. test.zip
            1 kB
          2. build.js
            3 kB

          Issue Links

            Activity

              People

                asemenyuk Alexey Semenyuk
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                10 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: