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

[macosx] JFileChooser should be enhanced to work in the OSX sandbox environment

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P4 P4
    • 8
    • 7
    • core-libs

      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]) {

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: