JDK-7172752 : [macosx] JFileChooser should be enhanced to work in the OSX sandbox environment
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: os_x
  • CPU: x86
  • Submitted: 2012-05-30
  • Updated: 2012-06-13
  • Resolved: 2012-06-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8Resolved
Related Reports
Duplicate :  
Description
A DESCRIPTION OF THE REQUEST :
Creating a JFileChooser to display any directory on OSX won't work if the Java application is running in a sandbox environment.

In the Console log I get this crash report:


JavaAppLauncher(31676) deny file-read-data /Users/johndoe

Process:         JavaAppLauncher [31676]
Path:            /Users/johndoe/Documents/Projects/SwingTest.app/Contents/MacOS/JavaAppLauncher
Load Address:    0x1071b2000
Identifier:      JavaAppLauncher
Version:         ??? (???)
Code Type:       X86-64 (Native)
Parent Process:  launchd [122]

Date/Time:       2012-05-30 13:31:23.304 +0100
OS Version:      Mac OS X 10.7.4 (11E53)
Report Version:  7

Backtrace:
0   libsystem_kernel.dylib        	0x00007fff88af8afa __open_nocancel + 10
1   libsystem_c.dylib             	0x00007fff867e3033 __opendir2$INODE64 + 51
2   libjava.dylib                 	0x000000010804e736 Java_java_io_UnixFileSystem_list + 175
3                                 	0x0000000108095f90
4                                 	0x000000010808a333
5                                 	0x000000010808a333
6                                 	0x000000010808a333
7                                 	0x000000010808a333
8                                 	0x000000010808a333
9                                 	0x00000001080844f7
10  libjvm.dylib                  	0x00000001077355ff JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*) + 557
11  libjvm.dylib                  	0x0000000107735adc JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*) + 256
12  libjvm.dylib                  	0x0000000107735c16 JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Thread*) + 74
13  libjvm.dylib                  	0x000000010776881c _ZL12thread_entryP10JavaThreadP6Thread + 169
14  libjvm.dylib                  	0x0000000107920388 JavaThread::thread_main_inner() + 134
15  libjvm.dylib                  	0x0000000107921827 JavaThread::run() + 369
16  libjvm.dylib                  	0x000000010785e95d _ZL10java_startP6Thread + 173
17  libsystem_c.dylib             	0x00007fff867d68bf _pthread_start + 335
18  libsystem_c.dylib             	0x00007fff867d9b75 thread_start + 13

Binary Images:
       0x1074b1000 -        0x107b24ff7 +libjvm.dylib (??? - ???) <A37ACC18-F389-38E0-AE02-5DDC4DE9AAD7> /Users/johndoe/Documents/Projects/SwingTest.app/Contents/PlugIns/jdk1.7.0.jdk/Contents/Home/jre/lib/server/libjvm.dylib
       0x108042000 -        0x108063fef +libjava.dylib (??? - ???) <4BC578CB-D29C-36CD-851F-9D01A43BDF2F> /Users/johndoe/Documents/Projects/SwingTest.app/Contents/PlugIns/jdk1.7.0.jdk/Contents/Home/jre/lib/libjava.dylib
    0x7fff86788000 -     0x7fff86865fef  libsystem_c.dylib (763.13.0 - compatibility 1.0.0) <41B43515-2806-3FBC-ACF1-A16F35B7E290> /usr/lib/system/libsystem_c.dylib
    0x7fff88ae2000 -     0x7fff88b02fff  libsystem_kernel.dylib (1699.26.8 - compatibility 1.0.0) <1DDC0B0F-DB2A-34D6-895D-E5B2B5618946> /usr/lib/system/libsystem_kernel.dylib


JUSTIFICATION :
The enhancement is required because it is impossible on the Mac platform to have an application running in the sandbox environment  that allows the user to select a directory with an open dialog.

This is because of the following bugs:
- FileDialog RFE not implemented after more than two years: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6927978

- apple.awt.fileDialogForDirectories not honoured (closed as duplicate of the RFE)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7161437

- this bug.

Before the sandbox requirements the only way to do it was to use the JFileChooser but since now it's no longer an option, we're left without any solution.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect to be able to see the files in the folder that the JFileChooser is showing.
ACTUAL -
I see nothing.

---------- BEGIN SOURCE ----------
import javax.swing.JFrame;
import java.io.File;
import javax.swing.JFileChooser;

public  class SwingTest extends JFrame {

    public String selectFolder() {
      JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
      chooser.showOpenDialog(this);
      return chooser.getSelectedFile().getAbsolutePath();
    }

    public static void main(String[] args) {
        SwingTest fdt = new SwingTest();

        File dir = new File(System.getProperty("user.home"));
        String selectedFolder = fdt.selectFolder();
        System.out.println("The selected file was: " + selectedFolder);
    }

} 

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

CUSTOMER SUBMITTED WORKAROUND :
There is no workaround when using the JFileChooser. The only way to open a directory would be to use a FileDialog and apply the following patch which will make the FileDialog honour the apple.awt.fileDialogForDirectories property:

diff -r 6432464ffec2 src/macosx/classes/sun/lwawt/macosx/CFileDialog.java
--- a/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Sat May 26 08:01:40 2012 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Tue May 29 17:56:51 2012 +0100
@@ -49,20 +49,28 @@ class CFileDialog implements FileDialogP
 
                 navigateApps = true;
 
                 String title = target.getTitle();
                 if (title == null) {
                     title = " ";
                 }
 
+                String chooseDirectoriesValue = System.getProperty("apple.awt.fileDialogForDirectories");
+                boolean chooseDirectories = false;
+                if(chooseDirectoriesValue != null &&
+                        chooseDirectoriesValue.equalsIgnoreCase("true")) {
+                    chooseDirectories = true;
+                }
+
                 String[] userFileNames = nativeRunFileDialog(title,
                         dialogMode,
                         target.isMultipleMode(),
                         navigateApps,
+                        chooseDirectories,
                         target.getFilenameFilter() != null,
                         target.getDirectory(),
                         target.getFile());
 
                 String directory = null;
                 String file = null;
                 File[] files = null;
 
@@ -137,18 +145,18 @@ class CFileDialog implements FileDialogP
             File directoryObj = new File(fileObj.getParent());
             String nameOnly = fileObj.getName();
             ret = ff.accept(directoryObj, nameOnly);
         }
         return ret;
     }
 
     private native String[] nativeRunFileDialog(String title, int mode,
-            boolean multipleMode, boolean shouldNavigateApps, boolean hasFilenameFilter,
-            String directory, String file);
+            boolean multipleMode, boolean shouldNavigateApps, boolean canChooseDirectories,
+            boolean hasFilenameFilter, String directory, String file);
 
     @Override
     public void setDirectory(String dir) {
     }
 
     @Override
     public void setFile(String file) {
     }
diff -r 6432464ffec2 src/macosx/native/sun/awt/CFileDialog.h
--- a/src/macosx/native/sun/awt/CFileDialog.h	Sat May 26 08:01:40 2012 -0700
+++ b/src/macosx/native/sun/awt/CFileDialog.h	Tue May 29 17:56:51 2012 +0100
@@ -47,16 +47,19 @@
     jint fMode;
 
     // Indicates whether the user can select multiple files
     BOOL fMultipleMode;
 
     // Should we navigate into apps?
     BOOL fNavigateApps;
 
+    // Can the dialog choose directories ?
+    BOOL fChooseDirectories;
+
     // Contains the absolute paths of the selected files as URLs
     NSArray *fURLs;
 }
 
 // Allocator
 - (id) initWithFilter:(jboolean)inHasFilter
            fileDialog:(jobject)inDialog
                 title:(NSString *)inTitle
diff -r 6432464ffec2 src/macosx/native/sun/awt/CFileDialog.m
--- a/src/macosx/native/sun/awt/CFileDialog.m	Sat May 26 08:01:40 2012 -0700
+++ b/src/macosx/native/sun/awt/CFileDialog.m	Tue May 29 17:56:51 2012 +0100
@@ -38,30 +38,32 @@
 - (id)initWithFilter:(jboolean)inHasFilter
           fileDialog:(jobject)inDialog
                title:(NSString *)inTitle
            directory:(NSString *)inPath
                 file:(NSString *)inFile
                 mode:(jint)inMode
         multipleMode:(BOOL)inMultipleMode
       shouldNavigate:(BOOL)inNavigateApps
+canChooseDirectories:(BOOL)inChooseDirectories
              withEnv:(JNIEnv*)env;
 {
     if (self == [super init]) {
         fHasFileFilter = inHasFilter;
         fFileDialog = JNFNewGlobalRef(env, inDialog);
         fDirectory = inPath;
         [fDirectory retain];
         fFile = inFile;
         [fFile retain];
         fTitle = inTitle;
         [fTitle retain];
         fMode = inMode;
         fMultipleMode = inMultipleMode;
         fNavigateApps = inNavigateApps;
+        fChooseDirectories = inChooseDirectories;
         fPanelResult = NSCancelButton;
     }
 
     return self;
 }
 
 -(void) disposer {
     if (fFileDialog != NULL) {
@@ -104,17 +106,17 @@
         if (fNavigateApps) {
             [thePanel setTreatsFilePackagesAsDirectories:YES];
         }
 
         if (fMode == java_awt_FileDialog_LOAD) {
             NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
             [openPanel setAllowsMultipleSelection:fMultipleMode];
             [openPanel setCanChooseFiles:YES];
-            [openPanel setCanChooseDirectories:NO];
+            [openPanel setCanChooseDirectories:fChooseDirectories];
             [openPanel setCanCreateDirectories:YES];
         }
 
         [thePanel setDelegate:self];
         fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile];
         [thePanel setDelegate:nil];
 
         if ([self userClickedOK]) {
@@ -177,17 +179,17 @@
  * Class:     sun_lwawt_macosx_CFileDialog
  * Method:    nativeRunFileDialog
  * Signature: (Ljava/lang/String;ILjava/io/FilenameFilter;
  *             Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL
 Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog
 (JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,
- jboolean navigateApps, jboolean hasFilter, jstring directory, jstring file)
+ jboolean navigateApps, jboolean chooseDirectories, jboolean hasFilter, jstring directory, jstring file)
 {
     jobjectArray returnValue = NULL;
 
 JNF_COCOA_ENTER(env);
     NSString *dialogTitle = JNFJavaToNSString(env, title);
     if ([dialogTitle length] == 0) {
         dialogTitle = @" ";
     }
@@ -195,16 +197,17 @@ JNF_COCOA_ENTER(env);
     CFileDialog *dialogDelegate = [[CFileDialog alloc] initWithFilter:hasFilter
                                                            fileDialog:peer
                                                                 title:dialogTitle
                                                             directory:JNFJavaToNSString(env, directory)
                                                                  file:JNFJavaToNSString(env, file)
                                                                  mode:mode
                                                          multipleMode:multipleMode
                                                        shouldNavigate:navigateApps
+                                                 canChooseDirectories:chooseDirectories
                                                               withEnv:env];
 
     [JNFRunLoop performOnMainThread:@selector(safeSaveOrLoad)
                                  on:dialogDelegate
                          withObject:nil
                       waitUntilDone:YES];
 
     if ([dialogDelegate userClickedOK]) {

Comments
EVALUATION Closing this bug as duplicate of 7175692. All JFileDialog specific problems, e.g. directory selection dialog RFE (6927978) or "apple.awt.fileDialogForDirectories" support (7161437) are tracked as separate bugs.
13-06-2012

EVALUATION This issue is being discussed at macosx-port-dev: http://mail.openjdk.java.net/pipermail/macosx-port-dev/2012-June/004375.html As far as I see, it's not specific to JFileChooser, but rather related to Runtime.exec(), so I'm dispatching it to java/java/classes_lang.
13-06-2012