11

On a MacBook Pro (2015) with fresh-installed Big Sur and AdoptOpenJDK 11 I developed a Java program for educational purpose that uses the JFileChooser. I did not use any IDE-specific code. As the rest of the program does not matter, here is a minimum-example that produces the same problem for me (Note: Here only as an example, clicking the button will open the File Chooser, choosing a file and clicking OK will change the button's text to 'OK'):

import javax.swing.*;
import java.awt.event.*;

public class Test extends JFrame implements ActionListener {

  private JFileChooser jf;
  private JButton jb;

  public Test() {
    setSize(480,320);    
    jf = new JFileChooser();
    jf.setDialogType(JFileChooser.OPEN_DIALOG);
    jb = new JButton("CLICK ME");
    jb.addActionListener(this);
    add(jb);
    setVisible(true);
  }

  public void actionPerformed(ActionEvent e) {
    if (e.getSource().equals(jb)) {
        jf.setVisible(true);
        final int result = jf.showOpenDialog(null);
        if (result == JFileChooser.APPROVE_OPTION) {
          jb.setText("OK");
        }
    }
  }

  public static void main(String[] args) {
      new Test();
  }
}

If I start the program via Terminal (java Test or compiled as a jar with java -jar Test.jar) everything works fine. I can open the File Chooser and it shows up my files and folders on my disk.

If I start the compiled jar via double-click, the program launches as well, but if I open the File Chooser I cannot see any files on my disk and hence I cannot load and save data to disk.

As I only have these problems on my Mac (not on Windows 10 or Lubuntu Linux) this might be a very specific problem due to false Java settings on my Mac. However, as I installed a fresh copy of Big Sur and AdoptOpenJDK 11 for Mac without changing anything, I wonder if this problem may occur for other people who want to run my program (teachers and students).

So what might be the problem and how to solve this (for me and potentially others)?

I already figured out with the activity monitor that the double-clicked jar is loaded with the JavaLauncher (but I cannot find it on disk and I cannot change any system settings for that).

I also searched for similar problems here. But these were mostly associated with saving files on wrong paths.

Would be nice to find a solution. Thank you for answering!

user14896726
  • 143
  • 1
  • 6

2 Answers2

16

I had the same problem - I wrote a java-for-all-desktops jar application years ago and it worked fine on all java version and all Mac OS, and Windows, until I put the jar file on Big Sur (OSX 11.2), at which point it couldn't read or write from/to the regular file system. On its own, it defaulted to reading and writing only to a tmp area in /private/var... instead of to the directory containing the jar file with the option of using jFileChooser to move around the real file system. It I explicitly set it to the start on Desktop then it could move to different directories but not see or access files.

After many hours of screwing around, I figured out how to fix it based on some of the above (Thanks!)... and the original poster got soooo close!

I found the program that launches JAR files when you double-click them in /System/Library/CoreServices/Jar Launcher.app

By going into System Preferences -> Security -> Privacy -> Full Disk Access, I was able to navigate to and add the above Jar Launcher.app to the list and then my jar file could be double-clicked and worked like always with full access to the file system :)

It was not needed to solve my problem, because, as you fine people stated above, java seems to inherit its access from either the terminal or the Jar Launcher, but if anyone needs to, you can also add java itself and any of its modules to the Full Disk Access list (as above). The easiest way to do this is to launch your jar from the terminal with java -jar YourProgram.jar , then, when the jar appears in the dock, right click on it and click Open in Finder. This will open the folder with the java executables. Then you can select them with the mouse and drag them right into the Full Disk Access list. I tried that along the way, but it was neither sufficient nor necessary to get the jars to work properly by double-clicking them. Enjoy!

Andyyy
  • 161
  • 1
  • 3
  • 1
    After weeks of trying to solve this problem, your answer here finally helped me. I can now run my jar files again, thank you! – dma May 16 '21 at 19:32
  • 1
    I was searching for the file named 'Jar Launcher.app' and was unable to find it and later saw i had file named as 'JavaLauncher.app' (On macOS 11.4 Big Sur)..and it worked...Thanks for finding this up – Jagdish Adusumalli Nov 08 '21 at 19:50
  • 1
    I was searching for the file named 'Jar Launcher.app' and was unable to find it and later saw i had file named as 'JavaLauncher.app' (On macOS 11.4 Big Sur)..and it worked...Thanks for finding this up – Jagdish Adusumalli Nov 08 '21 at 19:50
  • 1
    Thanks! I was not seeing my External SSD on Mac, even with java having the Full Disk Access permission. Then I added JavaLauncher.app to the list, and now it is able to list folders and files inside the SSD. – Teddy Jan 09 '22 at 10:15
  • Thanks. I even thought it was necessary to use terminal to launch Jar – Kien Vu Nov 30 '22 at 10:10
5

The mac has had a borderline silly (in that a ton of reviewers have derided this 'feature' as inane) security policy since Catalina (one version prior to Big Sur), where every app gets a popup-prompt the moment it tries to touch the disk, asking for permission from the user. Each major folder (Desktop, Documents, etc, eventually, whole disk) gets its own popup.

When you double click a jar file, the jar file runs 'as its own app' and gets its own popups. Presumably you denied it once, or possibly something is a little broken and those popups aren't showing.

In contrast, when running java in the terminal, the java process so spawned ends up piggybacking off of the permissions of the Terminal application (if you don't want that, run open foo.jar, which asks OS X to run the jar, and not java -jar foo.jar). The moment you so much as start Terminal you already get a popup for full disk access, you presumably said 'yes' to that, and thus, any javas spawned by the shell spawned by the Terminal work fine.

There is an easy fix and a hard fix. The hard fix is to fully 'mac-osx-ize' your application. To do this, you will need to use jlink and jpackage which are part of your OpenJDK distribution. They're right next to the javac and java executables. You'll need to modularize to properly use these tools.

The reason it's a harder fix is because the official distribution model of java desktop apps has changed. In the past (up to java 8), the idea was: The end user makes an arrangement with Oracle: They download a java runtime (a 'JRE') from oracle. Oracle will maintain it (will run updaters and otherwise take responsibility if that JRE has a security leak and they don't tell you about it), and this JRE will then be used to run java apps. You (the developer of a desktop java app) distribute jar files.

This is no longer how it works.

That's why there is no JRE9 (azul and a few other parties still make them; this is an attempt to maintain an obsolete distribution model for those who aren't ready to upgrade their distribution strategies. Oracle does not ship JREs anymore, not since java9, intentionally). The new model matches what almost all serious java desktop apps were already doing anyway: You (the maker of the app) distribute a JVM that can run your app, not oracle. This way, you don't have to explain to your users where to download a JRE (your installer will do this), and you know exactly what version of JRE you are shipping to them, instead of praying that whatever they have can run your stuff.

This is what jlink and jpackage are all about. This way you end up with an .app file, and this then fits normal mac apps: If a user denies disk access, and they change their mind later, they can just drag the .app into the appropriate list in the security widget of their System Preferences window like any other mac app. (And, yeah, most users don't know how to do that. Apple messed this part up, nothing java can do to fix this oversight in userfriendliness of OS X).

The easy way? Eh, commit to your current distribution model. Might as well tell them about how to start Terminal and run java from there - you're already asking them to install from AdoptOpenJDK and more or less forcing them to take care of keeping it up to date: You're already treating your end user as an advanced user who knows how to manage their own system and install complicated software. Might as well go the extra mile and tell them about Terminal.app.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • That might be the problem: Something is broken maybe, as there are no security popups when I start the application via double-click. Or maybe I once clicked "NO" (cannot remember, but might be). And of course I gave my OK to the Terminal in general. Hence, The argument to fully 'mac-osx-ize' the application in order to make it easy for end-users is good - and better than the argument of "too much disk space" for the app, as THIS could also happen to others. There are some tools out there, as you mentioned, or launch4j etc. for other systems etc. – user14896726 Dec 27 '20 at 20:08
  • Check your System Pref's security tab. There's an option for both 'Full Disk Access' as well as 'Files and Folders'. With some luck that jar is in there, and if not, you can drag it in one of these and check the checkbox. – rzwitserloot Dec 28 '20 at 01:01
  • That doesn‘t work for jars on my MacBook- only for applications – user14896726 Dec 29 '20 at 21:47
  • The original answer, however, from @rzwitserloot, making an app-file with jlink and jpackage did the trick. This worked perfectly. When opening the new app for the first time it asked me to grant access. I did it and it worked. Also: Easy for everyone else this way. – user14896726 Dec 29 '20 at 21:51
  • Meanwhile I always create deploy packages for Sharing my Applications with others- like exe or pkg using jpackage. It even works fine without using jlink and is really easy to use. Just one Terminal command line. This solves all problems. – user14896726 Apr 28 '22 at 05:45