diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/WorkbenchSWTMessages.java b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/WorkbenchSWTMessages.java
index d7edc32bd8d..addfe96e481 100644
--- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/WorkbenchSWTMessages.java
+++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/WorkbenchSWTMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2019 IBM Corporation and others.
+ * Copyright (c) 2005, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -42,6 +42,17 @@ public class WorkbenchSWTMessages extends NLS {
public static String InternalError;
public static String IDEApplication_versionTitle;
public static String IDEApplication_versionMessage;
+ public static String IDEApplication_workspaceLockMessage;
+
+ public static String IDEApplication_workspaceLockOwner;
+
+ public static String IDEApplication_workspaceLockHost;
+
+ public static String IDEApplication_workspaceLockDisplay;
+
+ public static String IDEApplication_workspaceLockPID;
+
+ public static String IDEApplication_workspaceCannotLockMessage2;
static {
// load message values from bundle file
diff --git a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/messages.properties b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/messages.properties
index 4bfe270a62e..b27474e8284 100644
--- a/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/messages.properties
+++ b/bundles/org.eclipse.e4.ui.workbench.swt/src/org/eclipse/e4/ui/workbench/swt/internal/copy/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2000, 2019 IBM Corporation and others.
+# Copyright (c) 2000, 2025 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -42,3 +42,9 @@ This workspace was written with a different version of the product and needs to
{0}\n\n\
Updating the workspace may make it incompatible with other versions of the product.\n\
Press OK to update the workspace and open it. Press Cancel to select a different workspace.
+IDEApplication_workspaceLockOwner=User:\t\t{0}\n
+IDEApplication_workspaceLockHost=Host:\t\t{0}\n
+IDEApplication_workspaceLockDisplay=Display:\t\t{0}\n
+IDEApplication_workspaceLockPID=Process ID:\t{0}\n
+IDEApplication_workspaceLockMessage=Workspace lock is currently held by:\n{0}
+IDEApplication_workspaceCannotLockMessage2=Could not switch to the selected workspace ''{0}'' because it is currently in use by another Eclipse instance.
\ No newline at end of file
diff --git a/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java b/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java
index de109fddcea..dc87d107fb7 100644
--- a/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java
+++ b/bundles/org.eclipse.ui.ide.application/src/org/eclipse/ui/internal/ide/application/IDEApplication.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2020 IBM Corporation and others.
+ * Copyright (c) 2003, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -24,11 +24,9 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.MalformedURLException;
-import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -42,7 +40,6 @@
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.URIUtil;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
import org.eclipse.equinox.app.IApplication;
@@ -89,8 +86,6 @@ public class IDEApplication implements IApplication, IExecutableExtension {
private static final String VERSION_FILENAME = "version.ini"; //$NON-NLS-1$
- private static final Path LOCK_INFO_FILE = Path.of(METADATA_FOLDER, ".lock_info"); //$NON-NLS-1$
-
private static final String DISPLAY_VAR = "DISPLAY"; //$NON-NLS-1$
private static final String HOST_NAME_VAR = "HOSTNAME"; //$NON-NLS-1$
@@ -223,12 +218,13 @@ public void setInitializationData(IConfigurationElement config,
}
/**
- * Return null if a valid workspace path has been set and an exit code otherwise.
- * Prompt for and set the path if possible and required.
+ * Returns null if a valid workspace has been selected or locked
+ * successfully, and an exit code otherwise. Prompts for and sets the workspace
+ * path if required.
*
* @param applicationArguments the command line arguments
- * @return null if a valid instance location has been set and an exit code
- * otherwise
+ * @return null if a valid instance location has been set and an
+ * exit code otherwise
*/
@SuppressWarnings("rawtypes")
protected Object checkInstanceLocation(Shell shell, Map applicationArguments) {
@@ -273,18 +269,11 @@ protected Object checkInstanceLocation(Shell shell, Map applicationArguments) {
return EXIT_WORKSPACE_LOCKED;
}
- String wsLockedError = NLS.bind(IDEWorkbenchMessages.IDEApplication_workspaceCannotLockMessage,
- workspaceDirectory.getAbsolutePath());
// check if there is a lock info then append it to error message.
- String lockInfo = getWorkspaceLockInfo(instanceLoc.getURL());
- if (lockInfo != null && !lockInfo.isBlank()) {
- wsLockedError = wsLockedError + System.lineSeparator() + System.lineSeparator()
- + NLS.bind(IDEWorkbenchMessages.IDEApplication_Ws_Lock_Owner_Message, lockInfo);
+ String lockInfo = Workbench.getWorkspaceLockDetails(instanceLoc.getURL());
+ if (lockInfo != null) {
+ Workbench.showWorkspaceLockedDialog(workspaceDirectory.getAbsolutePath(), lockInfo);
}
- MessageDialog.openError(
- shell,
- IDEWorkbenchMessages.IDEApplication_workspaceCannotLockTitle,
- wsLockedError);
} else {
MessageDialog.openError(
shell,
@@ -378,7 +367,7 @@ protected Object checkInstanceLocation(Shell shell, Map applicationArguments) {
// by this point it has been determined that the workspace is
// already in use -- force the user to choose again
- String lockInfo = getWorkspaceLockInfo(workspaceUrl);
+ String lockInfo = Workbench.getWorkspaceLockDetails(workspaceUrl);
MessageDialog dialog = new MessageDialog(null, IDEWorkbenchMessages.IDEApplication_workspaceInUseTitle,
null, NLS.bind(IDEWorkbenchMessages.IDEApplication_workspaceInUseMessage, workspaceUrl.getFile()),
@@ -412,49 +401,6 @@ protected Control createCustomArea(Composite parent) {
}
}
- /**
- * Read workspace lock file and parse all the properties present. Based on the
- * eclipse version and operating system some or all the properties may not
- * present. In such scenario it will return empty string.
- *
- * @return Previous lock owner details.
- */
- protected String getWorkspaceLockInfo(URL workspaceUrl) {
- try {
- Path lockFile = getLockInfoFile(workspaceUrl);
- if (!Files.exists(lockFile)) {
- return null;
- }
-
- StringBuilder sb = new StringBuilder();
- Properties props = new Properties();
- try (InputStream is = Files.newInputStream(lockFile)) {
- props.load(is);
- String prop = props.getProperty(USER);
- if (prop != null) {
- sb.append(NLS.bind(IDEWorkbenchMessages.IDEApplication_Ws_Lock_Owner_User, prop));
- }
- prop = props.getProperty(HOST);
- if (prop != null) {
- sb.append(NLS.bind(IDEWorkbenchMessages.IDEApplication_Ws_Lock_Owner_Host, prop));
- }
- prop = props.getProperty(DISPLAY);
- if (prop != null) {
- sb.append(NLS.bind(IDEWorkbenchMessages.IDEApplication_Ws_Lock_Owner_Disp, prop));
- }
- prop = props.getProperty(PROCESS_ID);
- if (prop != null) {
- sb.append(NLS.bind(IDEWorkbenchMessages.IDEApplication_Ws_Lock_Owner_P_Id, prop));
- }
- return sb.toString();
- }
- } catch (Exception e) {
- IDEWorkbenchPlugin.log("Could not read lock info file: ", e); //$NON-NLS-1$
-
- }
- return null;
- }
-
/**
* Write lock owner details onto workspace lock file. Data includes user, host,
* display and current java process id.
@@ -532,20 +478,6 @@ private String getHostName() {
return hostName;
}
- /**
- * Returns the .lock_info file. Does not check if it exists.
- *
- * @param workspaceUrl
- * @return .lock_info file.
- */
- private static Path getLockInfoFile(URL workspaceUrl) {
- try {
- return Path.of(URIUtil.toURI(workspaceUrl)).resolve(LOCK_INFO_FILE);
- } catch (URISyntaxException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
/**
* Creates the .lock_info file if it does not exist.
*
@@ -553,7 +485,7 @@ private static Path getLockInfoFile(URL workspaceUrl) {
* @return .lock_info file.
*/
private static Path createLockInfoFile(URL workspaceUrl) throws Exception {
- Path lockInfoFile = getLockInfoFile(workspaceUrl);
+ Path lockInfoFile = Workbench.getLockInfoFile(workspaceUrl);
if (!Files.exists(lockInfoFile)) {
Files.createFile(lockInfoFile);
}
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
index 0a14c764d01..bec664b18a5 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/IDEWorkbenchMessages.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2017 IBM Corporation and others.
+ * Copyright (c) 2005, 2025 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -1050,8 +1050,6 @@ public class IDEWorkbenchMessages extends NLS {
public static String IDEApplication_workspaceInvalidMessage;
public static String IDEApplication_workspaceCannotBeSetTitle;
public static String IDEApplication_workspaceCannotBeSetMessage;
- public static String IDEApplication_workspaceCannotLockTitle;
- public static String IDEApplication_workspaceCannotLockMessage;
public static String IDEApplication_versionTitle_newerWorkspace;
public static String IDEApplication_versionTitle_olderWorkspace;
public static String IDEApplication_versionMessage_newerWorkspace;
@@ -1147,13 +1145,7 @@ public class IDEWorkbenchMessages extends NLS {
public static String WorkbenchPreference_maxSimultaneousBuilds;
public static String WorkbenchPreference_maxSimultaneousBuildIntervalError;
-
- public static String IDEApplication_Ws_Lock_Owner_User;
- public static String IDEApplication_Ws_Lock_Owner_Host;
- public static String IDEApplication_Ws_Lock_Owner_Disp;
- public static String IDEApplication_Ws_Lock_Owner_P_Id;
public static String IDEApplication_Ws_Lock_Owner_Message;
-
static {
// load message values from bundle file
NLS.initializeMessages(BUNDLE_NAME, IDEWorkbenchMessages.class);
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
index b79612e23ef..348c34e50b9 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/messages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2000, 2022 IBM Corporation and others.
+# Copyright (c) 2000, 2025 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
@@ -1074,8 +1074,6 @@ IDEApplication_workspaceInvalidTitle=Invalid Workspace
IDEApplication_workspaceInvalidMessage=Selected workspace is not valid; choose a different one.
IDEApplication_workspaceCannotBeSetTitle=Workspace Cannot Be Created
IDEApplication_workspaceCannotBeSetMessage=Could not launch the product because the specified workspace cannot be created. The specified workspace directory is either invalid or read-only.
-IDEApplication_workspaceCannotLockTitle=Workspace Cannot Be Locked
-IDEApplication_workspaceCannotLockMessage=Could not launch the product because the associated workspace at ''{0}'' is currently in use by another Eclipse application.
IDEApplication_versionTitle_olderWorkspace=Older Workspace Version
IDEApplication_versionTitle_newerWorkspace=Newer Workspace Version
IDEApplication_versionMessage_olderWorkspace=The ''{0}'' workspace was written with an older version. \
@@ -1152,8 +1150,4 @@ editorAssociationOverride_error_couldNotCreate_message=The ''{0}'' extension fro
editorAssociationOverride_error_invalidElementName_message=An extension from plug-in ''{0}'' to the ''org.eclipse.ui.ide.editorAssociationOverride'' extension point was ignored because it contains the following invalid element: ''{1}''.
editorAssociationOverride_error_invalidExtension_message=The ''{0}'' extension from plug-in ''{1}'' to the ''org.eclipse.ui.ide.editorAssociationOverride'' extension point will be ignored because it contains invalid attributes.
-IDEApplication_Ws_Lock_Owner_User=User:\t\t{0}\n
-IDEApplication_Ws_Lock_Owner_Host=Host:\t\t{0}\n
-IDEApplication_Ws_Lock_Owner_Disp=Display:\t\t{0}\n
-IDEApplication_Ws_Lock_Owner_P_Id=Process ID:\t{0}\n
IDEApplication_Ws_Lock_Owner_Message=Workspace lock is currently held by:\n{0}
diff --git a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/Workbench.java
index 690aa8ac9de..22f271cc7d0 100644
--- a/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/Workbench.java
+++ b/bundles/org.eclipse.ui.workbench/eclipseui/org/eclipse/ui/internal/Workbench.java
@@ -35,9 +35,12 @@
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
+import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -49,6 +52,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
@@ -80,6 +84,7 @@
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.URIUtil;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.preferences.ConfigurationScope;
@@ -114,6 +119,7 @@
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
+import org.eclipse.e4.ui.workbench.swt.internal.copy.WorkbenchSWTMessages;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
@@ -2699,7 +2705,8 @@ private static String buildCommandLine(String workspace) {
* as the workspace location.
*
* @param workspacePath the new workspace location
- * @return {@link IApplication#EXIT_OK} or {@link IApplication#EXIT_RELAUNCH}
+ * @return {@link IApplication#EXIT_OK} or {@link IApplication#EXIT_RELAUNCH} or
+ * null
*/
@SuppressWarnings("restriction")
public static Object setRestartArguments(String workspacePath) {
@@ -2714,6 +2721,16 @@ public static Object setRestartArguments(String workspacePath) {
if (command_line == null) {
return IApplication.EXIT_OK;
}
+ Path selectedWorkspace = Path.of(workspacePath);
+ try {
+ String workspaceLock = getWorkspaceLockDetails(selectedWorkspace.toUri().toURL());
+ if (workspaceLock != null && !workspaceLock.isEmpty()) {
+ showWorkspaceLockedDialog(workspacePath, workspaceLock);
+ return null;
+ }
+ } catch (MalformedURLException e) {
+ return null;
+ }
System.setProperty(Workbench.PROP_EXIT_CODE, IApplication.EXIT_RELAUNCH.toString());
System.setProperty(IApplicationContext.EXIT_DATA_PROPERTY, command_line);
@@ -3684,4 +3701,72 @@ public void runWithInitialAutoScaleValue(Runnable runnable) {
}
}
+
+ /**
+ * Extract the lock details of the selected workspace if it is locked by another
+ * Eclipse application
+ *
+ * @param workspaceUrl the URL of selected workspace
+ * @return String details of lock owned workspace,
+ * null or Empty if not locked
+ */
+ @SuppressWarnings("restriction")
+ public static String getWorkspaceLockDetails(URL workspaceUrl) {
+ Path lockFile = getLockInfoFile(workspaceUrl);
+ if (lockFile != null && Files.exists(lockFile)) {
+ StringBuilder lockDetails = new StringBuilder();
+ Properties properties = new Properties();
+ try (InputStream is = Files.newInputStream(lockFile)) {
+ properties.load(is);
+ String prop = properties.getProperty("user"); //$NON-NLS-1$
+ if (prop != null) {
+ lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockOwner, prop));
+ }
+ prop = properties.getProperty("host"); //$NON-NLS-1$
+ if (prop != null) {
+ lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockHost, prop));
+ }
+ prop = properties.getProperty("display"); //$NON-NLS-1$
+ if (prop != null) {
+ lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockDisplay, prop));
+ }
+ prop = properties.getProperty("process-id"); //$NON-NLS-1$
+ if (prop != null) {
+ lockDetails.append(NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockPID, prop));
+ }
+
+ } catch (IOException e) {
+ WorkbenchPlugin.log(e);
+ }
+ return lockDetails.toString();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the lock file.
+ *
+ * @param workspaceUrl the URL of selected workspace
+ * @return the path to the .lock_info file within the specified
+ * workspace, or null if the workspace URL cannot be
+ * converted to a valid URI
+ */
+ public static Path getLockInfoFile(URL workspaceUrl) {
+ Path lockFile = Path.of(".metadata", ".lock_info"); //$NON-NLS-1$ //$NON-NLS-2$
+ try {
+ return Path.of(URIUtil.toURI(workspaceUrl)).resolve(lockFile);
+ } catch (URISyntaxException e) {
+ return null;
+ }
+ }
+
+ @SuppressWarnings("restriction")
+ public static void showWorkspaceLockedDialog(String workspacePath, String workspaceLock) {
+ String lockMessage = NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceCannotLockMessage2, workspacePath);
+ String wsLockedError = lockMessage + System.lineSeparator() + System.lineSeparator()
+ + NLS.bind(WorkbenchSWTMessages.IDEApplication_workspaceLockMessage, workspaceLock);
+
+ MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
+ WorkbenchSWTMessages.IDEApplication_workspaceCannotLockTitle, wsLockedError);
+ }
}