diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/ISpringBootProject.java b/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/ISpringBootProject.java index cd7957fce..2a11323b6 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/ISpringBootProject.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/ISpringBootProject.java @@ -95,9 +95,8 @@ public interface ISpringBootProject { * Equivalent of triggering a 'update project' operation on a Maven project. I.e. re-apply whatever configuration * gets done based on pom.xml or its equivalent. Client calling this should beware that this operation may be * asynchronous. - * @return Job if the operation is asynchronous or null otherwise. */ - Job updateProjectConfiguration(); + public void updateProjectConfiguration(); /** * Remove a dependency with given group-id and artifact-id from project's pom or build script. diff --git a/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/internal/MavenSpringBootProject.java b/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/internal/MavenSpringBootProject.java index 39e3e82e3..aa09f2b4b 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/internal/MavenSpringBootProject.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.boot/src/org/springframework/ide/eclipse/boot/core/internal/MavenSpringBootProject.java @@ -34,7 +34,10 @@ import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.getTextValue; import static org.eclipse.m2e.core.ui.internal.editing.PomEdits.performOnDOMDocument; import java.io.File; +import java.lang.reflect.Constructor; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -319,27 +322,32 @@ public class MavenSpringBootProject extends SpringBootProject { } @Override - public Job updateProjectConfiguration() { + public void updateProjectConfiguration() { //We wrap the UpdateMavenProjectJob in another job to avoid a race condition //that causes a deadlock. The race condition is avoided by have the //waitForWorkspaceLock wrapper which ensures that pending workspace jobs //are finished before triggering maven project update. //See: https://github.com/spring-projects/sts4/issues/780 - Job waitForWorkspaceLock = new Job("Wait for for workspace") { + Job waitForWorkspaceLock = new Job("Wait for workspace") { { setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule()); } @Override protected IStatus run(IProgressMonitor arg0) { - Job job = new UpdateMavenProjectJob(new IProject[] { - getProject() - }); - job.schedule(); - return Status.OK_STATUS; + Job job = createUpdateMavenProjectJob(getProject()); + if (job != null) { + job.schedule(); + return Status.OK_STATUS; + } + else { + return Status.error("internal error creating update job for maven project"); + } } + }; - return waitForWorkspaceLock; + + waitForWorkspaceLock.schedule(); } @Override @@ -364,6 +372,32 @@ public class MavenSpringBootProject extends SpringBootProject { return SpringBootCore.getDefaultBootVersion(); } + /** + * Helper method to create the job to update maven projects. + * + * Due to m2e 2.0 changing the signature of the constructor (parameter from IProject[] to Collection) + * we need to call the constructor via reflection to allow this code to work with m2e 1.x and m2e 2.x at the same time + */ + private UpdateMavenProjectJob createUpdateMavenProjectJob(IProject project) { + Object args = new IProject[] {project}; + + try { + // check for m2e 1.x version (public UpdateMavenProjectJob(IProject[] projects) + Constructor constructor = UpdateMavenProjectJob.class.getConstructor(IProject[].class); + return constructor.newInstance(args); + } catch (Exception e) { + } + + try { + // check for m2e 2.x version (public UpdateMavenProjectJob(Collection projects) + Constructor constructor = UpdateMavenProjectJob.class.getConstructor(Collection.class); + return constructor.newInstance(Collections.singleton(project)); + } catch (Exception e) { + } + + return null; + } + private void createRepoIfNeeded(Document pom, Repo repo) { if (repo!=null) { addReposIfNeeded(pom, Collections.singletonList(repo)); diff --git a/eclipse-extensions/org.springframework.ide.eclipse.buildship30/src/org/springframework/ide/eclipse/buildship30/GradleSpringBootProject.java b/eclipse-extensions/org.springframework.ide.eclipse.buildship30/src/org/springframework/ide/eclipse/buildship30/GradleSpringBootProject.java index 00920aad6..fdc4e15ad 100644 --- a/eclipse-extensions/org.springframework.ide.eclipse.buildship30/src/org/springframework/ide/eclipse/buildship30/GradleSpringBootProject.java +++ b/eclipse-extensions/org.springframework.ide.eclipse.buildship30/src/org/springframework/ide/eclipse/buildship30/GradleSpringBootProject.java @@ -28,7 +28,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.jobs.Job; import org.gradle.tooling.ModelBuilder; import org.gradle.tooling.model.GradleModuleVersion; import org.gradle.tooling.model.eclipse.EclipseExternalDependency; @@ -171,13 +170,12 @@ public class GradleSpringBootProject extends SpringBootProject { } @Override - public Job updateProjectConfiguration() { - return GradleCore.getWorkspace().getBuild(project).map(build -> { + public void updateProjectConfiguration() { + GradleCore.getWorkspace().getBuild(project).ifPresent(build -> { SynchronizationJob job = new SynchronizationJob(NewProjectHandler.IMPORT_AND_MERGE, Collections.singleton(build)); job.schedule(); - return job; - }).orElse(null); + }); } @Override