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

Defer initialization of classpath to the background if called from main #1525

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<IJavaProject, Job> JOB_MAP = new ConcurrentHashMap<>();

private static final Job initPDEJob = Job.create(PDECoreMessages.PluginModelManager_InitializingPluginModels,
monitor -> {
if (!PDECore.getDefault().getModelManager().isInitialized()) {
Expand All @@ -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();
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't this have the effect that the method blocks again until the classpath-set returns?
How would this then improve the start-up performance? Or is it just done to resolve dead-locks?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This codepath is only executed when it is called outside the UI (e.g. in a build thread) where it is fine to block, the goal is to join on a possible execution that previously was scheduled in an UI thread.

} 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();
Expand Down
Loading