Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ask users to import projects when opening a new folder #1501

Merged
merged 10 commits into from
Jul 3, 2020

Conversation

jdneo
Copy link
Collaborator

@jdneo jdneo commented Jun 23, 2020

Kapture 2020-06-23 at 19 58 17

Signed-off-by: Sheng Chen sheche@microsoft.com

package.json Outdated Show resolved Hide resolved
Comment on lines +50 to +59
const config = getJavaConfiguration();
const isMavenImporterEnabled: boolean = config.get<boolean>("import.maven.enabled");
const isGradleImporterEnabled: boolean = config.get<boolean>("import.gradle.enabled");
const patterns: string[] = [];
if (isMavenImporterEnabled) {
patterns.push("**/pom.xml");
}
if (isGradleImporterEnabled) {
patterns.push("**/build.gradle");
}
Copy link
Collaborator

@fbricon fbricon Jun 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to figure out a way to let 3rd party extensions (eg. bazel) register patterns/import prefs from their package.json (something similar to extension jars)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this?

"contributes": {
    "javaConfigurationFiles": [
        {
            "name": "BUILD",
            "contentPattern": "java_binary\\s*\\([\\s\\S]*\\)"  <--- optional
        }
    ],
    "javaExtensions": [
        ...
    ],
    ...
}

where contentPattern is optional, since for Bazel, the BUILD file can also be used to build other language's project, so we need a regex pattern to test towards the file content.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, you doesn't need test against the file content, because vscode-java won't be automatically activated when detecting BUILD file.

"contributes": {
  "javaBuildFiles": [
      {
          "fileNamePattern": "BUILD"
      }
  ]
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to say... If the third-party extension depends on vscode-java, then it will be activated.

src/utils.ts Outdated Show resolved Hide resolved
src/utils.ts Outdated Show resolved Hide resolved
src/syntaxLanguageClient.ts Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
@@ -30,8 +30,7 @@
"onLanguage:java",
"workspaceContains:pom.xml",
"workspaceContains:build.gradle",
"workspaceContains:.classpath",
"onCommand:java.project.import"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would you remove it? If you start from an empty folder, then add a pom.xml, you'd want to be able to trigger import even though vscode-java hasn't started yet

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no API to let the extension know which event activates it. When VS Code Java is activated by this command, the user will be asked again to confirm the import again. Is it acceptable?

Maybe a better solution is to let VS Code check the adding files for workspaceContains: microsoft/vscode#28122.

package.json Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
test/standard-mode-suite/utils.test.ts Outdated Show resolved Hide resolved
test/standard-mode-suite/utils.test.ts Outdated Show resolved Hide resolved
test/standard-mode-suite/utils.test.ts Outdated Show resolved Hide resolved
test/standard-mode-suite/utils.test.ts Outdated Show resolved Hide resolved
test/standard-mode-suite/utils.test.ts Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
src/extension.ts Outdated Show resolved Hide resolved
src/syntaxLanguageClient.ts Outdated Show resolved Hide resolved
src/extension.ts Outdated Show resolved Hide resolved
@jdneo jdneo force-pushed the cs/prompt-import2 branch 2 times, most recently from 0c5653a to a3d5266 Compare June 30, 2020 06:42
@fbricon
Copy link
Collaborator

fbricon commented Jun 30, 2020

@jdneo can you please fix the conflict?

Signed-off-by: Sheng Chen <sheche@microsoft.com>
Signed-off-by: Sheng Chen <sheche@microsoft.com>
Signed-off-by: Sheng Chen <sheche@microsoft.com>
Signed-off-by: Sheng Chen <sheche@microsoft.com>
Signed-off-by: Sheng Chen <sheche@microsoft.com>
@jdneo
Copy link
Collaborator Author

jdneo commented Jun 30, 2020

@fbricon Sure, rebased.

src/extension.ts Outdated Show resolved Hide resolved
@fbricon
Copy link
Collaborator

fbricon commented Jun 30, 2020

Everytime I close the vscode window, the syntax server fails to stop on its own, looks like it never receives the shutdown request

Signed-off-by: Sheng Chen <sheche@microsoft.com>
@jdneo
Copy link
Collaborator Author

jdneo commented Jun 30, 2020

I tried using jps after closing the vs code and not found any language server process. @testforstephen Could you reproduce that?

Copy link
Contributor

@akaroml akaroml left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everytime I close the vscode window, the syntax server fails to stop on its own, looks like it never receives the shutdown request

+1, I observed similar behavior before. Not sure if it's related to this change but I would suggest that we work on a safety net that ensures all Java processes created by vscode-java are closed upon exit. Maybe in a separate PR?

src/extension.ts Outdated Show resolved Hide resolved
@testforstephen
Copy link
Collaborator

I tried using jps after closing the vs code and not found any language server process. @testforstephen Could you reproduce that?

I observed the lightweight server is still running for a while after i forced to close VS Code window. However, it would automatically exit after about 1 minute.

Below is the log.

!ENTRY org.eclipse.jdt.ls.core 1 0 2020-07-01 13:20:12.657
!MESSAGE Parent process stopped running, forcing server exit

!ENTRY org.eclipse.jdt.ls.core 1 0 2020-07-01 13:20:12.658
!MESSAGE Shutdown received... waking up main thread

!ENTRY org.eclipse.jdt.ls.core 1 0 2020-07-01 13:20:12.665
!MESSAGE class org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin is stopping:

!ENTRY org.eclipse.core.resources 2 10035 2020-07-01 13:20:12.678
!MESSAGE The workspace will exit with unsaved changes in this session.

@testforstephen
Copy link
Collaborator

The Standard mode looks like the same behavior as "Parent process stopped running, forcing server exit".

Signed-off-by: Sheng Chen <sheche@microsoft.com>
@fbricon
Copy link
Collaborator

fbricon commented Jul 1, 2020

I see the standard server receiving

!ENTRY org.eclipse.jdt.ls.core 1 0 2020-07-01 11:53:35.884
!MESSAGE >> shutdown

!ENTRY org.eclipse.jdt.ls.core 1 0 2020-07-01 11:53:35.923
!MESSAGE >> exit

but never for the syntax server

@fbricon
Copy link
Collaborator

fbricon commented Jul 1, 2020

From the client log, I can see the shutdown command is never sent for the syntax client, but it is for the standard client, which explains my previous comment. But looking at the code, I don't see why this is not working the same for both.
Very easy to reproduce the issue: simply execute the reload window command (Cmd+R when running in dev mode).

@fbricon
Copy link
Collaborator

fbricon commented Jul 1, 2020

@snjeza
Copy link
Contributor

snjeza commented Jul 1, 2020

@fbricon @testforstephen @akaroml @jdneo could you try the following Java LS patch:

diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java
index a6710c75..d2e23a1a 100644
--- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java
+++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/handlers/JDTLanguageServer.java
@@ -161,6 +161,29 @@ public class JDTLanguageServer extends BaseJDTLanguageServer implements Language
 
 	private ProgressReporterManager progressReporterManager;
 
+	private Job shutdownJob = new Job("Shutdown...") {
+
+		@Override
+		protected IStatus run(IProgressMonitor monitor) {
+			try {
+				JavaRuntime.removeVMInstallChangedListener(jvmConfigurator);
+				if (workspaceDiagnosticsHandler != null) {
+					workspaceDiagnosticsHandler.removeResourceChangeListener();
+					workspaceDiagnosticsHandler = null;
+				}
+				if (classpathUpdateHandler != null) {
+					classpathUpdateHandler.removeElementChangeListener();
+					classpathUpdateHandler = null;
+				}
+				ResourcesPlugin.getWorkspace().save(true, monitor);
+			} catch (CoreException e) {
+				logException(e.getMessage(), e);
+			}
+			return Status.OK_STATUS;
+		}
+
+	};
+
 	@Override
 	public LanguageServerWorkingCopyOwner getWorkingCopyOwner() {
 		return workingCopyOwner;
@@ -348,20 +371,7 @@ public class JDTLanguageServer extends BaseJDTLanguageServer implements Language
 	public CompletableFuture<Object> shutdown() {
 		logInfo(">> shutdown");
 		return computeAsync((monitor) -> {
-			try {
-				JavaRuntime.removeVMInstallChangedListener(jvmConfigurator);
-				if (workspaceDiagnosticsHandler != null) {
-					workspaceDiagnosticsHandler.removeResourceChangeListener();
-					workspaceDiagnosticsHandler = null;
-				}
-				if (classpathUpdateHandler != null) {
-					classpathUpdateHandler.removeElementChangeListener();
-					classpathUpdateHandler = null;
-				}
-				ResourcesPlugin.getWorkspace().save(true, monitor);
-			} catch (CoreException e) {
-				logException(e.getMessage(), e);
-			}
+			shutdownJob.schedule();
 			return new Object();
 		});
 	}
@@ -372,6 +382,11 @@ public class JDTLanguageServer extends BaseJDTLanguageServer implements Language
 	@Override
 	public void exit() {
 		logInfo(">> exit");
+		try {
+			shutdownJob.join();
+		} catch (InterruptedException e) {
+			JavaLanguageServerPlugin.logException(e.getMessage(), e);
+		}
 		JavaLanguageServerPlugin.getLanguageServer().exit();
 		Executors.newSingleThreadScheduledExecutor().schedule(() -> {
 			logInfo("Forcing exit after 1 min.");
diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/syntaxserver/SyntaxLanguageServer.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/syntaxserver/SyntaxLanguageServer.java
index 44daf7f1..d3582e89 100644
--- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/syntaxserver/SyntaxLanguageServer.java
+++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/syntaxserver/SyntaxLanguageServer.java
@@ -29,7 +29,9 @@ import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jdt.ls.core.internal.BaseJDTLanguageServer;
 import org.eclipse.jdt.ls.core.internal.JDTUtils;
@@ -92,6 +94,19 @@ public class SyntaxLanguageServer extends BaseJDTLanguageServer implements Langu
 	private ContentProviderManager contentProviderManager;
 	private ProjectsManager projectsManager;
 	private PreferenceManager preferenceManager;
+	private Job shutdownJob = new Job("Shutdown...") {
+
+		@Override
+		protected IStatus run(IProgressMonitor monitor) {
+			try {
+				ResourcesPlugin.getWorkspace().save(true, monitor);
+			} catch (CoreException e) {
+				logException(e.getMessage(), e);
+			}
+			return Status.OK_STATUS;
+		}
+
+	};
 
 	public SyntaxLanguageServer(ContentProviderManager contentProviderManager,
 								ProjectsManager projectsManager,
@@ -120,12 +135,7 @@ public class SyntaxLanguageServer extends BaseJDTLanguageServer implements Langu
 	public CompletableFuture<Object> shutdown() {
 		logInfo(">> shutdown");
 		return computeAsync((monitor) -> {
-			try {
-				ResourcesPlugin.getWorkspace().save(true, monitor);
-			} catch (CoreException e) {
-				logException(e.getMessage(), e);
-			}
-
+			shutdownJob.schedule();
 			return new Object();
 		});
 	}
@@ -133,6 +143,11 @@ public class SyntaxLanguageServer extends BaseJDTLanguageServer implements Langu
 	@Override
 	public void exit() {
 		logInfo(">> exit");
+		try {
+			shutdownJob.join();
+		} catch (InterruptedException e) {
+			JavaLanguageServerPlugin.logException(e.getMessage(), e);
+		}
 		JavaLanguageServerPlugin.getLanguageServer().exit();
 		Executors.newSingleThreadScheduledExecutor().schedule(() -> {
 			System.exit(1);

@snjeza
Copy link
Contributor

snjeza commented Jul 1, 2020

The issue happens when ResourcesPlugin.getWorkspace().save(true, monitor) takes more than five seconds in which case VS Code doesn't send the exit command.

@jdneo
Copy link
Collaborator Author

jdneo commented Jul 2, 2020

OK, I can now repro this on Mac. Seems this issue is not reproduceable on Windows.

@jdneo
Copy link
Collaborator Author

jdneo commented Jul 2, 2020

@snjeza Thank you for the patch! It works while it has a limitation. It ensures the language serve will be shut down if the initialize request is finished.

If the VS Code is closed before the initialize response is sent from the language server, the client will not send the shutdown event to the server -- which is a restriction of LSP. Thus the servers will still be running. (to simply repro this, you can close the VS Code at the moment when the spinning icon shows at the staus-bar).

// BTW, I suggest to discuss this topic in another new issue thread, since it's out of this PR's scope.

@fbricon
Copy link
Collaborator

fbricon commented Jul 2, 2020

so I found out the extension.deactivate() function is never called when the server is started in hybrid mode but the projects have not been imported. So the syntax server client is never stopped, so never sends the shutdown signal.

I just can't figure out why

src/extension.ts Outdated Show resolved Hide resolved
@fbricon
Copy link
Collaborator

fbricon commented Jul 2, 2020

@fbricon @testforstephen @akaroml @jdneo could you try the following Java LS patch:

please open a PR in jdt.ls, that's a different issue

Signed-off-by: Sheng Chen <sheche@microsoft.com>
@jdneo
Copy link
Collaborator Author

jdneo commented Jul 3, 2020

In case the user may not select an option when asking import. I did some more changes to make sure the vscode java will resolve the API when the asking is needed.

src/extension.ts Outdated Show resolved Hide resolved
Signed-off-by: Sheng Chen <sheche@microsoft.com>
src/syntaxLanguageClient.ts Outdated Show resolved Hide resolved
Signed-off-by: Sheng Chen <sheche@microsoft.com>

async function promptUserForStandardServer(config: WorkspaceConfiguration): Promise<boolean> {
const choice: string = await window.showInformationMessage("The workspace contains Java projects, would you like to import them?", "Yes", "Always", "Later");
switch (choice) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add Never?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Personal option is not including Never here. Since our final goal is to let users to use all the features of VS Code Java.

@fbricon fbricon changed the title Ask users to import for a fresh workspace Ask users to import projects when opening a new folder Jul 3, 2020
@fbricon fbricon merged commit 0c4055b into redhat-developer:master Jul 3, 2020
@fbricon
Copy link
Collaborator

fbricon commented Jul 3, 2020

Thanks @jdneo!

@fbricon fbricon added this to the End June 2020 milestone Jul 3, 2020
@snjeza
Copy link
Contributor

snjeza commented Jul 3, 2020

please open a PR in jdt.ls, that's a different issue

@fbricon See eclipse-jdtls/eclipse.jdt.ls#1495

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants