diff --git a/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/pom.xml b/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/pom.xml
index db79eadab23b..af51813e2187 100644
--- a/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/pom.xml
+++ b/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/pom.xml
@@ -38,6 +38,14 @@
commons-io
commons-io
+
+ javax.annotation
+ javax.annotation-api
+
+
+ javax.inject
+ javax.inject
+
javax.ws.rs
javax.ws.rs-api
@@ -86,6 +94,10 @@
org.eclipse.che.plugin
che-plugin-java-server
+
+ org.eclipse.lsp4j
+ org.eclipse.lsp4j
+
org.slf4j
slf4j-api
diff --git a/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectModule.java b/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectModule.java
index 8cd048d38a78..857c67ef1f4b 100644
--- a/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectModule.java
+++ b/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectModule.java
@@ -32,5 +32,6 @@ protected void configure() {
newSetBinder(binder(), ProjectHandler.class).addBinding().to(PlainJavaInitHandler.class);
bind(ClasspathUpdaterService.class);
+ bind(PlainJavaProjectSourceFolderWatcher.class).asEagerSingleton();
}
}
diff --git a/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectSourceFolderWatcher.java b/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectSourceFolderWatcher.java
new file mode 100644
index 000000000000..6994e46b3093
--- /dev/null
+++ b/plugins/plugin-java/che-plugin-java-plain/che-plugin-java-plain-server/src/main/java/org/eclipse/che/plugin/java/plain/server/inject/PlainJavaProjectSourceFolderWatcher.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012-2018 Red Hat, Inc.
+ * This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0
+ * which is available at https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ */
+package org.eclipse.che.plugin.java.plain.server.inject;
+
+import static java.nio.file.Files.isDirectory;
+import static java.util.Collections.singletonList;
+import static org.eclipse.che.api.languageserver.LanguageServiceUtils.prefixURI;
+import static org.eclipse.che.api.languageserver.LanguageServiceUtils.removeUriScheme;
+import static org.eclipse.che.jdt.ls.extension.api.Commands.GET_PROJECT_SOURCE_LOCATIONS_COMMAND;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.reflect.TypeToken;
+import java.lang.reflect.Type;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import org.eclipse.che.api.core.notification.EventService;
+import org.eclipse.che.api.languageserver.ExtendedLanguageServer;
+import org.eclipse.che.api.languageserver.FindServer;
+import org.eclipse.che.api.project.server.notification.ProjectUpdatedEvent;
+import org.eclipse.che.api.watcher.server.FileWatcherManager;
+import org.eclipse.che.api.watcher.server.impl.FileWatcherByPathMatcher;
+import org.eclipse.che.plugin.java.inject.JavaModule;
+import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
+import org.eclipse.lsp4j.ExecuteCommandParams;
+import org.eclipse.lsp4j.FileChangeType;
+import org.eclipse.lsp4j.FileEvent;
+import org.eclipse.lsp4j.services.LanguageServer;
+
+/**
+ * Reports the create/update/delete changes on project source folders to jdt.ls
+ *
+ * @author V. Rubezhny
+ */
+public class PlainJavaProjectSourceFolderWatcher {
+ private static final Gson gson =
+ new GsonBuilder().disableHtmlEscaping().serializeNulls().create();
+
+ private final FileWatcherManager manager;
+ private final FileWatcherByPathMatcher matcher;
+ private final FindServer lsRegistry;
+
+ private final EventService eventService;
+
+ private final CopyOnWriteArrayList watcherIds = new CopyOnWriteArrayList<>();
+
+ @Inject
+ public PlainJavaProjectSourceFolderWatcher(
+ FileWatcherManager manager,
+ FileWatcherByPathMatcher matcher,
+ FindServer lsRegistry,
+ EventService eventService) {
+ this.manager = manager;
+ this.matcher = matcher;
+ this.lsRegistry = lsRegistry;
+ this.eventService = eventService;
+ }
+
+ @PostConstruct
+ protected void startWatchers() {
+ int watcherId =
+ manager.registerByMatcher(
+ folderMatcher(),
+ s -> report(s, FileChangeType.Created),
+ s -> {},
+ s -> report(s, FileChangeType.Deleted));
+
+ watcherIds.add(watcherId);
+ eventService.subscribe(this::onProjectUpdated, ProjectUpdatedEvent.class);
+ }
+
+ @PreDestroy
+ public void stopWatchers() {
+ watcherIds.stream().forEach(id -> manager.unRegisterByMatcher(id));
+ }
+
+ private void onProjectUpdated(ProjectUpdatedEvent event) {
+ ExecuteCommandParams params =
+ new ExecuteCommandParams(
+ GET_PROJECT_SOURCE_LOCATIONS_COMMAND, singletonList(prefixURI(event.getProjectPath())));
+
+ ExtendedLanguageServer languageServer = lsRegistry.byId(JavaModule.LS_ID);
+ if (languageServer == null) {
+ return;
+ }
+
+ languageServer
+ .getServer()
+ .getWorkspaceService()
+ .executeCommand(params)
+ .thenAccept(
+ result -> {
+ if (result == null) {
+ return;
+ }
+ Type type = new TypeToken>() {}.getType();
+ List paths = gson.fromJson(gson.toJson(result), type);
+ paths.stream().forEach(f -> matcher.accept(Paths.get(removeUriScheme(prefixURI(f)))));
+ });
+ }
+
+ private PathMatcher folderMatcher() {
+ return it -> isDirectory(it);
+ }
+
+ private void report(String path, FileChangeType changeType) {
+ ExtendedLanguageServer languageServer = lsRegistry.byId(JavaModule.LS_ID);
+ if (languageServer != null) {
+ send(languageServer.getServer(), path, changeType);
+ }
+ }
+
+ private void send(LanguageServer server, String path, FileChangeType changeType) {
+ DidChangeWatchedFilesParams params =
+ new DidChangeWatchedFilesParams(
+ Collections.singletonList(new FileEvent(prefixURI(path), changeType)));
+ server.getWorkspaceService().didChangeWatchedFiles(params);
+ }
+}
diff --git a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/plainjava/PlainJavaProjectConfigureClasspathTest.java b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/plainjava/PlainJavaProjectConfigureClasspathTest.java
index 043be809b9fc..8e78941f1da6 100644
--- a/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/plainjava/PlainJavaProjectConfigureClasspathTest.java
+++ b/selenium/che-selenium-test/src/test/java/org/eclipse/che/selenium/plainjava/PlainJavaProjectConfigureClasspathTest.java
@@ -30,6 +30,7 @@
import org.eclipse.che.selenium.core.workspace.TestWorkspace;
import org.eclipse.che.selenium.pageobject.CodenvyEditor;
import org.eclipse.che.selenium.pageobject.ConfigureClasspath;
+import org.eclipse.che.selenium.pageobject.Consoles;
import org.eclipse.che.selenium.pageobject.Ide;
import org.eclipse.che.selenium.pageobject.Loader;
import org.eclipse.che.selenium.pageobject.Menu;
@@ -64,6 +65,7 @@ public class PlainJavaProjectConfigureClasspathTest {
@Inject private Loader loader;
@Inject private Menu menu;
@Inject private TestProjectServiceClient testProjectServiceClient;
+ @Inject private Consoles consoles;
@BeforeClass
public void prepare() throws Exception {
@@ -75,6 +77,7 @@ public void prepare() throws Exception {
testProjectServiceClient.importProject(
ws.getId(), Paths.get(resource.toURI()), LIB_PROJECT, ProjectTemplates.PLAIN_JAVA);
ide.open(ws);
+ consoles.waitJDTLSProjectResolveFinishedMessage(PROJECT_NAME);
}
@Test