13
13
*******************************************************************************/
14
14
package org .eclipse .pde .internal .core ;
15
15
16
+ import java .lang .reflect .Method ;
17
+ import java .util .Map ;
18
+ import java .util .concurrent .ConcurrentHashMap ;
19
+ import java .util .concurrent .atomic .AtomicBoolean ;
20
+
16
21
import org .eclipse .core .resources .IProject ;
17
22
import org .eclipse .core .runtime .CoreException ;
23
+ import org .eclipse .core .runtime .ILog ;
18
24
import org .eclipse .core .runtime .IPath ;
19
25
import org .eclipse .core .runtime .IStatus ;
20
26
import org .eclipse .core .runtime .Status ;
27
+ import org .eclipse .core .runtime .jobs .IJobChangeEvent ;
21
28
import org .eclipse .core .runtime .jobs .Job ;
29
+ import org .eclipse .core .runtime .jobs .JobChangeAdapter ;
22
30
import org .eclipse .jdt .core .ClasspathContainerInitializer ;
23
31
import org .eclipse .jdt .core .IClasspathContainer ;
24
32
import org .eclipse .jdt .core .IJavaProject ;
25
33
import org .eclipse .jdt .core .JavaCore ;
34
+ import org .eclipse .jdt .core .JavaModelException ;
26
35
import org .eclipse .pde .core .plugin .IPluginModelBase ;
27
36
28
37
public class RequiredPluginsInitializer extends ClasspathContainerInitializer {
29
38
39
+ private static final AtomicBoolean WARNING_LOGGED = new AtomicBoolean ();
40
+
41
+ private static final Map <IJavaProject , Job > JOB_MAP = new ConcurrentHashMap <>();
42
+
30
43
private static final Job initPDEJob = Job .create (PDECoreMessages .PluginModelManager_InitializingPluginModels ,
31
44
monitor -> {
32
45
if (!PDECore .getDefault ().getModelManager ().isInitialized ()) {
@@ -36,6 +49,48 @@ public class RequiredPluginsInitializer extends ClasspathContainerInitializer {
36
49
37
50
@ Override
38
51
public void initialize (IPath containerPath , IJavaProject javaProject ) throws CoreException {
52
+ if (isCalledFromUI ()) {
53
+ // See https://github.com/eclipse-pde/eclipse.pde/issues/1481
54
+ if (WARNING_LOGGED .compareAndSet (false , true )) {
55
+ ILog .get ().warn (
56
+ "RequiredPluginsInitializer called from within the UI thread this will badly impact your IDE performance!" , //$NON-NLS-1$
57
+ new RuntimeException ("Called from main thread here" )); //$NON-NLS-1$
58
+ }
59
+ JOB_MAP .compute (javaProject , (jp , oldjob ) -> {
60
+ if (oldjob != null ) {
61
+ oldjob .cancel ();
62
+ }
63
+ Job job = Job .create (PDECoreMessages .PluginModelManager_InitializingPluginModels , m -> {
64
+ if (oldjob != null ) {
65
+ try {
66
+ oldjob .join ();
67
+ } catch (InterruptedException e ) {
68
+ }
69
+ }
70
+ setClasspath (jp );
71
+ });
72
+ job .addJobChangeListener (new JobChangeAdapter () {
73
+ @ Override
74
+ public void done (IJobChangeEvent event ) {
75
+ JOB_MAP .remove (jp );
76
+ }
77
+ });
78
+ job .schedule ();
79
+ return job ;
80
+ });
81
+ return ;
82
+ }
83
+ Job job = JOB_MAP .get (javaProject );
84
+ if (job != null ) {
85
+ try {
86
+ job .join ();
87
+ } catch (InterruptedException e ) {
88
+ }
89
+ }
90
+ setClasspath (javaProject );
91
+ }
92
+
93
+ protected void setClasspath (IJavaProject javaProject ) throws JavaModelException {
39
94
IProject project = javaProject .getProject ();
40
95
// The first project to be built may initialize the PDE models, potentially long running, so allow cancellation
41
96
PluginModelManager manager = PDECore .getDefault ().getModelManager ();
@@ -85,4 +140,15 @@ public void requestClasspathContainerUpdate(IPath containerPath, IJavaProject pr
85
140
JavaCore .setClasspathContainer (containerPath , new IJavaProject [] {project }, new IClasspathContainer [] {containerSuggestion }, null );
86
141
}
87
142
143
+ private static boolean isCalledFromUI () {
144
+ try {
145
+ Class <?> display = RequiredPluginsInitializer .class .getClassLoader ()
146
+ .loadClass ("org.eclipse.swt.widgets.Display" ); //$NON-NLS-1$
147
+ Method findDisplay = display .getMethod ("findDisplay" , Thread .class ); //$NON-NLS-1$
148
+ return findDisplay .invoke (null , Thread .currentThread ()) != null ;
149
+ } catch (Exception e ) {
150
+ }
151
+ return false ;
152
+ }
153
+
88
154
}
0 commit comments