为什么通过双击启动jar文件时没有权限从磁盘读取,但如果从终端启动则没有权限? [英] Why does a jar file have no permissions to read from disk when started via double-click - but not if started from the Terminal?

查看:117
本文介绍了为什么通过双击启动jar文件时没有权限从磁盘读取,但如果从终端启动则没有权限?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在装有新安装的Big Sur和AdoptOpenJDK 11的MacBook Pro(2015)上,我开发了一个用于教育目的的Java程序,该程序使用JFileChooser.我没有使用任何特定于IDE的代码.由于该程序的其余部分无关紧要,因此这是一个最小示例,它对我也产生相同的问题(注意:这里仅作为示例,单击按钮将打开文件选择器",选择一个文件,然后单击确定"将更改按钮的文本显示为确定"):

  import javax.swing.*;导入java.awt.event.*;公共类测试扩展 JFrame 实现 ActionListener {私人JFileChooser jf;私人JButton jb;公共Test(){setSize(480,320);jf =新的JFileChooser();jf.setDialogType(JFileChooser.OPEN_DIALOG);jb =新的JButton(点击我");jb.addActionListener(this);添加(jb);setVisible(true);}公共无效actionPerformed(ActionEvent e){如果(e.getSource().equals(jb)){jf.setVisible(true);最终的int结果= jf.showOpenDialog(null);如果(结果== JFileChooser.APPROVE_OPTION){jb.setText(OK");}}}公共静态void main(String [] args){新的Test();}} 

如果我通过终端 ( java Test 或使用 java -jar Test.jar 编译为jar)启动程序,则一切正常.我可以打开文件选择器",它会在磁盘上显示我的文件和文件夹.

如果我通过双击启动 jar ,该程序也会启动,但是如果我打开文件选择器我看不到磁盘上的任何文件,并且因此我无法加载数据并将其保存到磁盘.

由于我的Mac上只有这些问题(Windows 10或Lubuntu Linux上没有),由于我的Mac上的Java设置错误,这可能是一个非常具体的问题.但是,当我为Mac安装了Big Sur和AdoptOpenJDK 11的新副本而没有进行任何更改时,我想知道是否会对想要运行我的程序的其他人(老师和学生)发生此问题.

那么可能是什么问题,以及如何解决(对我本人以及其他人而言)?

我已经通过活动监视器确定了双击的jar装有JavaLauncher(但是我无法在磁盘上找到它,也无法更改其任何系统设置).

我也在这里搜索类似的问题.但是这些大多与将文件保存在错误的路径上有关.

很高兴找到一个解决方案.谢谢您的回答!

解决方案

自从Catalina(Big之前的一个版本)以来,Mac一直处于愚蠢的边界(因为大量评论者嘲笑这种功能"为愚蠢")Sur),每个应用尝试触摸磁盘时都会弹出提示,并征求用户的许可.每个主文件夹(桌面,文档等,最终是整个磁盘)都有自己的弹出窗口.

当您双击一个jar文件时,该jar文件将作为其自己的应用程序"运行,并获得其自己的弹出窗口.大概您一次拒绝了它,或者可能是有些问题,并且那些弹出窗口没有显示.

相反,在终端中运行 java 时,如此产生的Java进程最终会背负终端应用程序的权限(如果不希望这样做,请运行 openfoo.jar ,它要求OS X运行jar,而不是 java -jar foo.jar ).当您开始启动Terminal的那一刻,您已经可以弹出一个完整的磁盘访问权限时,您可能对此说了是",因此,由Terminal生成的shell生成的所有Java都可以正常工作.

有一个简单的修复程序和一个硬性修复程序.硬修复是完全mac-osx-ize"您的应用程序.为此,您需要使用OpenJDK发行版中的 jlink jpackage .它们就在 javac java 可执行文件的旁边.您需要进行模块化以正确使用这些工具.

更难解决的原因是因为Java桌面应用程序的正式发行模型已更改.过去(到Java 8为止)的想法是:最终用户与Oracle达成协议:他们从oracle下载Java运行时("JRE").Oracle将对其进行维护(将运行更新程序,否则,如果JRE存在安全漏洞,并且他们不告诉您有关情况,则负责),然后将使用此JRE运行Java应用程序.您(桌面Java应用程序的开发人员)分发jar文件.

这不再起作用.

这就是为什么没有没有 JRE9(azul和其他一些方面仍在制造它们)的原因;这是为了为那些尚未准备好升级其发行策略的用户维持过时的发行模型.从Java9开始,Oracle不再提供JRE.新模型与几乎所有严肃的Java桌面应用程序已经在做的事情相匹配: You (应用程序的制造商)分发了可以运行您的应用程序的JVM,而不是oracle.这样,您不必向用户解释在何处下载JRE(安装程序将执行此操作),并且您确切知道要向他们交付的JRE版本,而不必为他们拥有的任何版本都可以运行您的JRE东西.

这是 jlink jpackage 的全部内容.这样,您最终得到一个 .app 文件,然后就可以适合普通的Mac应用程序:如果用户拒绝磁盘访问,并且他们后来改变了主意,则可以将.app拖动到适当的位置.像其他Mac应用程序一样,在其系统偏好设置"窗口的安全小部件中列出.(是的,大多数用户都不知道该怎么做.Apple弄乱了这一部分,Java不能采取任何措施来修复OS X的易用性.)

简单的方法?恩,请遵循您当前的发行模型.还可能告诉他们如何启动Terminal并从那里运行 java -您已经在要求他们从AdoptOpenJDK安装,或多或少会迫使他们注意保持最新状态:已经将您的最终用户视为高级用户,他们知道如何管理自己的系统并安装复杂的软件.最好再多花点时间,向他们介绍Terminal.app.

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!

解决方案

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.

这篇关于为什么通过双击启动jar文件时没有权限从磁盘读取,但如果从终端启动则没有权限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆