diff --git a/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseFramework.java b/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseFramework.java index e546276f60..c00432c19e 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseFramework.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseFramework.java @@ -37,6 +37,7 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.launch.Framework; +import org.osgi.util.tracker.ServiceTracker; public class EclipseFramework implements AutoCloseable { @@ -84,6 +85,25 @@ public void start() throws Exception { } } + public boolean waitForApplicationStart(long timeout) { + String[] args = configuration.getNonFrameworkArgs(); + for (String arg : args) { + if (EclipseApplication.ARG_APPLICATION.equals(arg)) { + ServiceTracker tracker = new ServiceTracker<>(framework.getBundleContext(), + ApplicationLauncher.class, null); + tracker.open(true); + try { + return tracker.waitForService(timeout) != null; + } catch (InterruptedException e) { + return false; + } finally { + tracker.close(); + } + } + } + return true; + } + private int launchApplication(BundleContext systemBundleContext, EquinoxConfiguration configuration) throws Exception { EclipseAppLauncher appLauncher = new EclipseAppLauncher(systemBundleContext, false, true, null, configuration); diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java index 46c449db14..5e67dbec89 100644 --- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java +++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuild.java @@ -19,6 +19,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.jobs.Job; /** * Abstract class for performing a build and producing a result @@ -42,7 +43,7 @@ public final Result call() throws Exception { deleteAllProjects(); IProject project = importProject(); project.build(IncrementalProjectBuilder.CLEAN_BUILD, this); - project.build(IncrementalProjectBuilder.FULL_BUILD, this); + buildProject(project); Result result = createResult(project); for (IMarker marker : project.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE)) { result.addMarker(marker); @@ -52,6 +53,13 @@ public final Result call() throws Exception { return result; } + protected void buildProject(IProject project) throws CoreException { + project.build(IncrementalProjectBuilder.FULL_BUILD, this); + while (!Job.getJobManager().isIdle()) { + Thread.yield(); + } + } + protected abstract Result createResult(IProject project) throws Exception; static void disableAutoBuild() throws CoreException { diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java index 07e4c0206c..ff5b3492f3 100644 --- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java +++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/AbstractEclipseBuildMojo.java @@ -21,6 +21,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -80,6 +81,8 @@ public abstract class AbstractEclipseBuildMojo arguments; + String applicationName = this.application; + boolean useApplication = applicationName != null; + if (useApplication) { + arguments = List.of(EclipseApplication.ARG_APPLICATION, applicationName); + } else { + arguments = List.of(); + } try (EclipseFramework framework = application.startFramework(workspaceManager - .getWorkspace(EclipseApplicationManager.getRepository(eclipseRepository).getURL(), this), List.of())) { + .getWorkspace(EclipseApplicationManager.getRepository(eclipseRepository).getURL(), this), arguments)) { if (debug) { framework.printState(); } + if (useApplication) { + Thread thread = new Thread(new Runnable() { + + @Override + public void run() { + try { + framework.start(); + } catch (Exception e) { + getLog().error("Running application " + applicationName + " failed", e); + } + } + }); + thread.setName(getName() + " Application Thread"); + thread.start(); + framework.waitForApplicationStart(TimeUnit.SECONDS.toMillis(30)); + } if (hasPDENature(eclipseProject)) { if (framework.hasBundle(Bundles.BUNDLE_PDE_CORE)) { framework.execute(new SetTargetPlatform(projectDependencies, debug)); diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/SetTargetPlatform.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/SetTargetPlatform.java index c0e1473d7b..816956a41d 100644 --- a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/SetTargetPlatform.java +++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipsebuild/SetTargetPlatform.java @@ -22,6 +22,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.ILogListener; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.pde.core.target.ITargetDefinition; @@ -29,6 +30,7 @@ import org.eclipse.pde.core.target.ITargetPlatformService; import org.eclipse.pde.core.target.LoadTargetDefinitionJob; import org.eclipse.pde.core.target.TargetBundle; +import org.eclipse.pde.internal.core.PluginModelManager; import org.eclipse.pde.internal.core.target.TargetPlatformService; public class SetTargetPlatform implements Callable, Serializable { @@ -64,6 +66,7 @@ public Serializable call() throws Exception { Job job = new LoadTargetDefinitionJob(target); job.schedule(); job.join(); + Job.getJobManager().join(PluginModelManager.class, new NullProgressMonitor()); return null; }