2016-07-15 32 views
0

在Eclipse RCP應用程序中創建新工作區時出現問題。在Eclipse RCP應用程序中創建新工作區時出錯

當啓動RCP應用程序時,會提示對話框詢問工作區位置。 指定位置時,出現錯誤「無法創建指定的工作區,因此無法啓動產品 指定的工作區目錄無效或只讀」。 我從eclipse的IDEApplication.java中看到了代碼,但仍面臨同樣的問題。

施藥代碼:

@SuppressWarnings("restriction") 
public class MyRcpApplication implements IApplication 
{ 

    private static final String METADATA_PROJECTS_PATH = "/.plugins/org.eclipse.core.resources/.projects"; 
    private static final String METADATA_ROOT = ".metadata"; 
    private static final String COMMAND_ARG = "--container"; 
    private static final String SYSTEM_PROPERTY_EXIT_CODE = "eclipse.exitcode"; 
    private static final String WORKSPACE_VERSION_KEY = "org.eclipse.core.runtime"; 
    private static final String VERSION_FILENAME = "version.ini"; 
    private static final String WORKSPACE_VERSION_VALUE = "1"; //$NON-NLS-1$ 

    public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$ 
    private Shell shell; 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) 
    */ 
    @Override 
    public Object start(final IApplicationContext context) 
    { 

    Display display = PlatformUI.createDisplay(); 
    Shell shell = display.getActiveShell(); 
    try 
    { 
     // for backward compatibility we need to clear the workspace before start also 
     cleanUpTheWorkSpace(); 
     boolean instanceLocationCheck = checkInstanceLocation(shell, context.getArguments()); 
     if (!instanceLocationCheck) 
     { 
     MessageDialog.openError(shell, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle, 
      "Could not launch the product because the associated workspace is currently in use by another My Application."); 
     return IApplication.EXIT_OK; 
     } 

     int returnCode = PlatformUI.createAndRunWorkbench(display, new MyApplicationWorkbenchAdvisor()); 
     if (returnCode == PlatformUI.RETURN_RESTART) 
     { 
     // eclipse.exitcode system property may be set to re-launch 
     if (IApplication.EXIT_RELAUNCH.equals(Integer.getInteger(SYSTEM_PROPERTY_EXIT_CODE))) 
     { 
      return IApplication.EXIT_RELAUNCH; 
     } 

     return IApplication.EXIT_RESTART; 
     } 
     // if application return code is exit clean up the workspace 
     // cleanUpTheWorkSpace(); 
     return IApplication.EXIT_OK; 
    } 
    finally 
    { 
     if (display != null) 
     { 
     display.dispose(); 
     } 
     Location instanceLoc = Platform.getInstanceLocation(); 
     if (instanceLoc != null) 
     { 
     instanceLoc.release(); 
     } 
    } 
    } 

    @SuppressWarnings("rawtypes") 
    private boolean checkInstanceLocation(final Shell shell, final Map arguments) 
    { 
    Location instanceLoc = Platform.getInstanceLocation(); 
    if (instanceLoc == null) 
    { 
     MessageDialog.openError(shell, "Workspace is Mandatory", "IDEs need a valid workspace."); 
     return false; 
    } 

    // -data "/valid/path", workspace already set 
    if (instanceLoc.isSet()) 
    { 

     // make sure the meta data version is compatible (or the user has 
     // chosen to overwrite it). 
     try 
     { 
     // Used to check whether are we launching My application from development environment or not 
     if (isDevLaunchMode(arguments)) 
     { 
      return true; 
     } 
     // Used to check instance location is locked or not 
     if (instanceLoc.isLocked()) 
     { 
      return false; 
     } 
     // we failed to create the directory. 
     // Two possibilities: 
     // 1. directory is already in use 
     // 2. directory could not be created 
     File workspaceDirectory = new File(instanceLoc.getURL().getFile()); 
     if (workspaceDirectory.exists()) 
     { 
      if (isDevLaunchMode(arguments)) 
      { 
      return true; 
      } 
      MessageDialog.openError(
       shell, 
       "Workspace Cannot Be Locked", 
       "Could not launch the product because the associated workspace at '" + workspaceDirectory.getAbsolutePath() 
        + "' is currently in use by another Eclipse application"); 

     } 
     else 
     { 
      MessageDialog 
       .openError(
        shell, 
        "Workspace Cannot Be Created", 
        "Could not launch the product because the specified workspace cannot be created. The specified workspace directory is either invalid or read-only."); 
     } 
     } 
     catch (IOException e) 
     { 
     MessageDialog.openError(shell, "Internal Error", e.getMessage()); 
     } 
    } 
    else 
    { 
     try 
     { 
     // -data @noDefault or -data not specified, prompt and set 
     ChooseWorkspaceData launchData = new ChooseWorkspaceData(instanceLoc.getDefault()); 
     boolean force = false; 
     while (true) 
     { 
      URL workspaceUrl = promptForWorkspace(shell, launchData, force); 
      if (workspaceUrl == null) 
      { 
      return false; 
      } 

      // if there is an error with the first selection, then force the 
      // dialog to open to give the user a chance to correct 
      force = true; 

      try 
      { 
      // the operation will fail if the url is not a valid 
      // instance data area, so other checking is unneeded 
      if (instanceLoc.set(workspaceUrl, false)) 
      { 
       launchData.writePersistedData(); 
       writeWorkspaceVersion(workspaceUrl); 
       return true; 
      } 
      } 
      catch (IllegalStateException e) 
      { 
      MessageDialog 
       .openError(
        shell, 
        IDEWorkbenchMessages 
        .IDEApplication_workspaceCannotBeSetTitle, 
        IDEWorkbenchMessages 
        .IDEApplication_workspaceCannotBeSetMessage); 
      return false; 
      } 

      // by this point it has been determined that the workspace is 
      // already in use -- force the user to choose again 
      MessageDialog.openError(shell, IDEWorkbenchMessages 
       .IDEApplication_workspaceInUseTitle, 
       IDEWorkbenchMessages. 
       IDEApplication_workspaceInUseMessage); 
     } 
     } 

     catch (IllegalStateException | IOException e) 
     { 
     } 
    } 

    return true; 
    } 

    private static void writeWorkspaceVersion(final URL defaultValue) 
    { 
    Location instanceLoc = Platform.getInstanceLocation(); 
    if (instanceLoc.isReadOnly()) 
    { 
     // MessageDialog.openError(shell,"Read-Only Dialog", "Location was read-only"); 
     System.out.println("Instance Got Locked......"); 
    } 
    if ((instanceLoc == null) || instanceLoc.isReadOnly()) 
    { 
     return; 
    } 

    File versionFile = getVersionFile(instanceLoc.getURL(), true); 
    if (versionFile == null) 
    { 
     return; 
    } 

    OutputStream output = null; 
    try 
    { 
     String versionLine = WORKSPACE_VERSION_KEY + '=' + WORKSPACE_VERSION_VALUE; 

     output = new FileOutputStream(versionFile); 
     output.write(versionLine.getBytes("UTF-8")); //$NON-NLS-1$ 
    } 
    catch (IOException e) 
    { 
     IDEWorkbenchPlugin.log("Could not write version file", //$NON-NLS-1$ 
      StatusUtil.newStatus(IStatus.ERROR, e.getMessage(), e)); 
    } 
    finally 
    { 
     try 
     { 
     if (output != null) 
     { 
      output.close(); 
     } 
     } 
     catch (IOException e) 
     { 
     // do nothing 
     } 
    } 
    } 

    /* 
    * (non-Javadoc) 
    * 
    * @see org.eclipse.equinox.app.IApplication#stop() 
    */ 
    @Override 
    public void stop() 
    { 
    if (!PlatformUI.isWorkbenchRunning()) 
    { 
     return; 
    } 
    final IWorkbench workbench = PlatformUI.getWorkbench(); 
    final Display display = workbench.getDisplay(); 
    display.syncExec(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
     if (!display.isDisposed()) 
     { 
      workbench.close(); 
     } 
     } 
    }); 
    } 

    private URL promptForWorkspace(final Shell shell, final ChooseWorkspaceData launchData, boolean force) 
    { 
    URL url = null; 
    do 
    { 
     new ChooseWorkspaceDialog(shell, launchData, false, force).prompt(force); 
     String instancePath = launchData.getSelection(); 
     if (instancePath == null) 
     { 
     return null; 
     } 

     // the dialog is not forced on the first iteration, but is on every 
     // subsequent one -- if there was an error then the user needs to be 
     // allowed to 
     force = true; 

     // create the workspace if it does not already exist 
     File workspace = new File(instancePath); 
     if (!workspace.exists()) 
     { 
     workspace.mkdir(); 
     } 

     try 
     { 
     // Don't use File.toURL() since it adds a leading slash that Platform does not 
     // handle properly. See bug 54081 for more details. 
     String path = workspace.getAbsolutePath().replace(File.separatorChar, '/'); 
     url = new URL("file", null, path); //$NON-NLS-1$ 
     } 
     catch (MalformedURLException e) 
     { 
     MessageDialog 
      .openError(
       shell, 
       IDEWorkbenchMessages 
       .IDEApplication_workspaceInvalidTitle, 
       IDEWorkbenchMessages 
       .IDEApplication_workspaceInvalidMessage); 
     continue; 
     } 
    } 
    while (!checkValidWorkspace(shell, url)); 

    return url; 
    } 

    private boolean checkValidWorkspace(final Shell shell, final URL url) 
    { 
    String version = readWorkspaceVersion(url); 

    // if the version could not be read, then there is not any existing 
    // workspace data to trample, e.g., perhaps its a new directory that 
    // is just starting to be used as a workspace 
    if (version == null) 
    { 
     return true; 
    } 

    final int ide_version = Integer.parseInt(WORKSPACE_VERSION_VALUE); 
    int workspace_version = Integer.parseInt(version); 

    // equality test is required since any version difference (newer 
    // or older) may result in data being trampled 
    if (workspace_version == ide_version) 
    { 
     return true; 
    } 

    // At this point workspace has been detected to be from a version 
    // other than the current ide version -- find out if the user wants 
    // to use it anyhow. 
    String title = "My App Titile"; //$NON-NLS-1$ 
    String message = "My App Message"; 

    MessageBox mbox = new MessageBox(shell, SWT.OK | SWT.CANCEL 
     | SWT.ICON_WARNING | SWT.APPLICATION_MODAL); 
    mbox.setText(title); 
    mbox.setMessage(message); 
    return mbox.open() == SWT.OK; 
    } 

    private static String readWorkspaceVersion(final URL workspace) 
    { 
    File versionFile = getVersionFile(workspace, false); 
    if ((versionFile == null) || !versionFile.exists()) 
    { 
     return null; 
    } 

    try 
    { 
     // Although the version file is not spec'ed to be a Java properties 
     // file, it happens to follow the same format currently, so using 
     // Properties to read it is convenient. 
     Properties props = new Properties(); 
     FileInputStream is = new FileInputStream(versionFile); 
     try 
     { 
     props.load(is); 
     } 
     finally 
     { 
     is.close(); 
     } 

     return props.getProperty(WORKSPACE_VERSION_KEY); 
    } 
    catch (IOException e) 
    { 
     IDEWorkbenchPlugin.log("Could not read version file", new Status(//$NON-NLS-1$ 
      IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, 
      IStatus.ERROR, 
      e.getMessage() == null ? "" : e.getMessage(), //$NON-NLS-1$, 
      e)); 
     return null; 
    } 
    } 

    private static File getVersionFile(final URL workspaceUrl, final boolean create) 
    { 
    if (workspaceUrl == null) 
    { 
     return null; 
    } 

    try 
    { 
     // make sure the directory exists 
     File metaDir = new File(workspaceUrl.getPath(), METADATA_FOLDER); 
     if (!metaDir.exists() && (!create || !metaDir.mkdir())) 
     { 
     return null; 
     } 

     // make sure the file exists 
     File versionFile = new File(metaDir, VERSION_FILENAME); 
     if (!versionFile.exists() 
      && (!create || !versionFile.createNewFile())) 
     { 
     return null; 
     } 

     return versionFile; 
    } 
    catch (IOException e) 
    { 
     // cannot log because instance area has not been set 
     return null; 
    } 
    } 

    @SuppressWarnings("rawtypes") 
    private static boolean isDevLaunchMode(final Map args) 
    { 
    // see org.eclipse.pde.internal.core.PluginPathFinder.isDevLaunchMode() 
    if (Boolean.getBoolean("eclipse.pde.launch")) 
    { 
     return true; 
    } 
    return args.containsKey("-pdelaunch"); //$NON-NLS-1$ 
    } 

    /** 
    * Deletes all the available projects in the workspace 
    */ 
    private void cleanUpTheWorkSpace() 
    { 
    // this will be the 
    String[] commands = Platform.getCommandLineArgs(); 
    if (commands != null) 
    { 
     List<String> args = Arrays.asList(commands); 
     if (args.contains(COMMAND_ARG)) 
     { 
     // if project is in the root delete it.. it will delete associated metadata 
     IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); 
     if (projects != null) 
     { 
      for (IProject project : projects) 
      { 
      try 
      { 
       project.delete(true, new NullProgressMonitor()); 
      } 
      catch (CoreException e) 
      { 
       // msgHandler.post(MsgSeverity.ERROR, "Unable to clear the workspace"); 
      } 
      } 
     } 
     // if project is not in the root but if its in the workspace delete the metadata too 
     File[] workSpaceFiles = Platform.getLocation().toFile().listFiles(); 
     for (File file : workSpaceFiles) 
     { 
      if (METADATA_ROOT.equals(file.getName())) 
      { 
      File projectMeta = new File(file.getPath() + METADATA_PROJECTS_PATH); 
      if ((projectMeta != null) && projectMeta.exists()) 
      { 
       File[] children = projectMeta.listFiles(); 
       for (File child : children) 
       { 
       FileUtils.deleteQuietly(child); 
       } 
      } 
      } 

      /* 
      * else { FileUtils.deleteQuietly(file); } 
      */ 
     } 
     } 
    } 
    } 
} 
+0

指定的工作空間目錄無效或只讀。你從中得到什麼 – Boola

+4

也許你指定的工作空間目錄是無效的還是隻讀的? – Blobonat

+0

那麼你在工作空間中指定了什麼?向我們展示應用程序代碼。 –

回答

0

你的代碼只是調用

if (instanceLoc.isLocked()) 
{ 
    return false; 
} 

檢查工作空間被鎖定,但什麼都不做,使工作區鎖定,這將總是會遇到錯誤代碼。

IDEApplication做到這一點:

if (instanceLoc.lock()) { 
    writeWorkspaceVersion(); 
    return null; 
} 

你需要做類似的事情。

+0

當工作區第一次創建時,目錄被標記爲只讀,因此應用程序即使是第一次也不能啓動。 我也嘗試將代碼更改爲以下代碼: if(instanceLoc.lock()) writeWorkspaceVersion(); 返回true; } 仍存在問題。 –

0

嘗試以管理員身份運行Eclipse。

相關問題