31
31
import java .util .Objects ;
32
32
import java .util .Properties ;
33
33
import java .util .concurrent .Callable ;
34
+ import java .util .concurrent .TimeUnit ;
35
+ import java .util .regex .Pattern ;
34
36
35
37
import org .eclipse .core .resources .ICommand ;
36
38
import org .eclipse .core .resources .IFolder ;
94
96
*/
95
97
public class ApiAnalysis implements Serializable , Callable <ApiAnalysisResult > {
96
98
99
+ private static final Pattern COMPONENT_DISPOSED_ERROR = Pattern
100
+ .compile ("Component '(.+)' in the baseline '(.+)' is disposed" );
101
+
97
102
private Collection <String > baselineBundles ;
98
103
private Collection <String > targetBundles ;
99
104
private String baselineName ;
@@ -164,7 +169,36 @@ public void aboutToRun(IJobChangeEvent event) {
164
169
deleteAllProjects ();
165
170
IPath projectPath = IPath .fromOSString (projectDir );
166
171
IProject project = getProject (projectPath );
167
- ApiAnalysisResult result = new ApiAnalysisResult (getVersion ());
172
+ RuntimeException exception = new RuntimeException ("Can't get API result due to API application error" );
173
+ String version = getVersion ();
174
+ for (int i = 0 ; i < 5 ; i ++) {
175
+ ApiAnalysisResult result = new ApiAnalysisResult (version );
176
+ IStatus status = runAnalysis (projectPath , project , result );
177
+ if (!status .isOK () && status .getException () instanceof Exception error ) {
178
+ if (isRecoverable (error )) {
179
+ exception .addSuppressed (error );
180
+ TimeUnit .SECONDS .sleep (10 );
181
+ continue ;
182
+ }
183
+ throw error ;
184
+ }
185
+ return result ;
186
+ }
187
+ throw exception ;
188
+ }
189
+
190
+ private boolean isRecoverable (Exception error ) {
191
+ if (error instanceof CoreException ) {
192
+ String message = error .getMessage ();
193
+ if (message != null ) {
194
+ return COMPONENT_DISPOSED_ERROR .matcher (message ).matches ();
195
+ }
196
+ }
197
+ return false ;
198
+ }
199
+
200
+ private IStatus runAnalysis (IPath projectPath , IProject project , ApiAnalysisResult result )
201
+ throws InterruptedException {
168
202
IStatus status ;
169
203
if (runAsJob ) {
170
204
WorkspaceJob job = new WorkspaceJob ("Tycho API Analysis" ) {
@@ -184,10 +218,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) {
184
218
}
185
219
JRTUtil .reset (); // reclaim space due to loaded multiple JRTUtil should better be fixed to not
186
220
// use that much space
187
- if (!status .isOK () && status .getException () instanceof Exception error ) {
188
- throw error ;
189
- }
190
- return result ;
221
+ return status ;
191
222
}
192
223
193
224
private IStatus performAPIAnalysis (IProject project , IPath projectPath , ApiAnalysisResult result ) {
0 commit comments