diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsInitializer.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsInitializer.java index a639647fbb..76b4aa54a0 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsInitializer.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsInitializer.java @@ -13,20 +13,32 @@ *******************************************************************************/ package org.eclipse.pde.internal.core; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; + import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jdt.core.ClasspathContainerInitializer; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.JavaModelException; import org.eclipse.pde.core.plugin.IPluginModelBase; public class RequiredPluginsInitializer extends ClasspathContainerInitializer { + private static final AtomicBoolean WARNING_LOGGED = new AtomicBoolean(); + + private static final Map JOB_MAP = new ConcurrentHashMap<>(); + private static final Job initPDEJob = Job.create(PDECoreMessages.PluginModelManager_InitializingPluginModels, monitor -> { if (!PDECore.getDefault().getModelManager().isInitialized()) { @@ -36,6 +48,48 @@ public class RequiredPluginsInitializer extends ClasspathContainerInitializer { @Override public void initialize(IPath containerPath, IJavaProject javaProject) throws CoreException { + if ("main".equals(Thread.currentThread().getName())) { //$NON-NLS-1$ + // See https://github.com/eclipse-pde/eclipse.pde/issues/1481 + if (WARNING_LOGGED.compareAndSet(false, true)) { + ILog.get().warn( + "RequiredPluginsInitializer called from within the UI thread this will badly impact your IDE performance!", //$NON-NLS-1$ + new RuntimeException("Called from main thread here")); //$NON-NLS-1$ + } + JOB_MAP.compute(javaProject, (jp, oldjob) -> { + if (oldjob != null) { + oldjob.cancel(); + } + Job job = Job.create(PDECoreMessages.PluginModelManager_InitializingPluginModels, m -> { + if (oldjob != null) { + try { + oldjob.join(); + } catch (InterruptedException e) { + } + } + setClasspath(jp); + }); + job.addJobChangeListener(new JobChangeAdapter() { + @Override + public void done(IJobChangeEvent event) { + JOB_MAP.remove(jp); + } + }); + job.schedule(); + return job; + }); + return; + } + Job job = JOB_MAP.get(javaProject); + if (job != null) { + try { + job.join(); + } catch (InterruptedException e) { + } + } + setClasspath(javaProject); + } + + protected void setClasspath(IJavaProject javaProject) throws JavaModelException { IProject project = javaProject.getProject(); // The first project to be built may initialize the PDE models, potentially long running, so allow cancellation PluginModelManager manager = PDECore.getDefault().getModelManager();