OpenFilesHandler does not receive fileopen events when app started by script

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      A bundled application uses `java.awt.Desktop#setOpenFilesHandler`. The application is launched by a shell script.

      The file type is correctly associated with the app in the OS.

      However, when files of the handled type are double clicked, the app never receives the `openFiles` event, and the provided `OpenFilesHandler` is never invoked. It does not matter whether the app is running already or not.

      The expectation is that the handler is invoked. However, all that happens is that the app is raised.

      The bug seems similar to what was reported in https://bugreport.java.com/bugdatabase/JDK-8043852 but does not use the fazed-out `com.apple.eawt` package.

      It also seems similar to https://bugs.openjdk.org/browse/JDK-8360120 albeit a different event, but otherwise really similar. Perhaps a similar fix like https://github.com/openjdk/jdk/pull/25967 is needed.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      To reproduce, make a directory for the app.

      ```
      $ mkdir -p /Applications/Main.app/Contents/Resources/Java
      $ mkdir -p /Applications/Main.app/Contents/MacOS
      ```

      and place the following three files in their indicated directories. Make sure `/Applications/Main.app/Contents/MacOS/run.sh` is executable
      ```
      $ cd /Applications/Main.app/Contents/MacOS
      $ chmod 755 run.sh
      ```

       Then compile `/Applications/Main.app/Contents/Resources/Java/Main.java`

      ```
      $ cd /Applications/Main.app/Contents/Resources/Java
      $ javac Main.java
      ```

      Now run the application

      ```
      $ cd ~
      $ open -a Main
      ```

      Create a dummy file

      ```
      $ touch Main.foo
      ```

      Wait 5 to 10 seconds, then open the dummy file

      ```
      $ open Main.foo
      ```

      Standard out and error are piped to `/Applications/Main.app/Contents/Main.log`

      ---------- BEGIN SOURCE ----------
      --- /Applications/Main.app/Contents/Resources/Java/Main.java ----
      // Compile to Main.class in the same directory
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.SwingUtilities;
      import java.awt.BorderLayout;
      import java.awt.Color;
      import java.awt.desktop.OpenFilesEvent;
      import java.awt.Desktop;
      import java.util.Map;
      import java.util.Iterator;

      public class Main {
          JFrame frame;
          JLabel label;
          
          public Main() {
      System.out.println("Defining the frame");
              frame = new JFrame("Main");
              label = new JLabel("Hello world!");
              label.setFont(label.getFont().deriveFont(24f));
              frame.getContentPane().add(label, BorderLayout.CENTER);
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          }
          public void info() {
      Map<String,String> map = Map.of("Operating system", "os.name",
      "OS Version", "os.version",
      "Architecture", "os.arch",
      "Java version", "java.version",
      "Java home", "java.home");
      Iterator<Map.Entry<String,String>> iter =
      map.entrySet().iterator();

      while (iter.hasNext()) {
      Map.Entry<String,String> entry = iter.next();
      System.out.println(String.format("%-20s", entry.getKey())+": "+
      System.getProperty(entry.getValue()));
      }


          }
          public void gotFile(OpenFilesEvent e) {
              System.out.println("Open called with " + e.getFiles().size()+" files");
              label.setText("Fired open files: " + e.getFiles().size());
              label.setOpaque(true);
              label.setBackground(new Color((int)(Math.random() * 0x1000000)));
              frame.pack();
          }
          public void bind_later() {
      System.out.println("Bind with invokeLater");
              Desktop.getDesktop().setOpenFileHandler(e -> {
                      SwingUtilities.invokeLater(() -> { gotFile(e); }); });
          }
          public void bind() {
      System.out.println("Bind");
              Desktop.getDesktop().setOpenFileHandler(e -> {
                      gotFile(e);});
          }
          public void show() {
      System.out.println("Show the GUI");
              frame.pack();
              frame.setVisible(true);
          }
          public void run1()
          {
      System.out.println("Run version 1");
              show();
              bind_later();
          }
          public void run2()
          {
      System.out.println("Run version 2");
              bind();
              show();
          }
          public static void main(String[] args) {
      System.out.println("Running Main");

      int type = 2;
      if (args.length > 0) type = Integer.parseInt(args[0]);


      Main m = new Main();
      m.info();
              if (type == 1) SwingUtilities.invokeLater(() -> { m.run1(); });
              else SwingUtilities.invokeLater(() -> { m.run2(); });
          }
      }
      // EOF

      --- /Applications/Main.app/Contents/Info.plist ---
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
        <dict>
          <key>CFBundleName</key>
          <string>Main</string>
          <key>CFBundleIdentifier</key>
          <string>foo.Main</string>
          <key>CFBundleDisplayName</key>
          <string>Main</string>
          <key>CFBundleExecutable</key>
          <string>run.sh</string>
          <key>CFBundleVersion</key>
          <string>1.0</string>
          <key>CFBundleShortVersionString</key>
          <string>1.0</string>
          <key>CFBundleDevelopmentRegion</key>
          <string>English</string>
          <key>CFBundlePackageType</key>
          <string>APPL</string>
          <key>CFBundleDocumentTypes</key>
          <array>
            <dict>
              <key>CFBundleTypeName</key>
      <string>Foo file</string>
      <key>CFBundleTypeExtensions</key>
              <array>
                <string>foo</string>
              </array>
      <key>CFBundleTypeRole</key>
      <string>Editor</string>
            </dict>
          </array>
        </dict>
      </plist>
      <!-- EOF -->

      --- /Applications/Main.app/Contents/MacOS/run.sh ---
      #!/usr/bin/env bash

      base=$(realpath `dirname $0`/..)
      java=/opt/homebrew/opt/openjdk/bin/java
      name=Main
      if test "x$JAVA" != "x" ; then
          java=$JAVA
      fi

      exec ${java} -cp ${base}/Resources/Java ${name} $@ 2>/dev/stdout | tee ${base}/${name}.log

      # EOF
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Perhaps a similar fix like https://github.com/openjdk/jdk/pull/25967 is needed.

      FREQUENCY :
      ALWAYS

        1. Info.plist
          1.0 kB
          Andrew Wang
        2. Main.java
          2 kB
          Andrew Wang
        3. Main.log
          0.4 kB
          Andrew Wang
        4. run.sh
          0.2 kB
          Andrew Wang

            Assignee:
            Damon Nguyen
            Reporter:
            Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: