diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/shared/StatusTool.java b/tycho-core/src/main/java/org/eclipse/tycho/core/shared/StatusTool.java index 9317c73a12..8a3eb308fc 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/shared/StatusTool.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/shared/StatusTool.java @@ -12,6 +12,7 @@ *******************************************************************************/ package org.eclipse.tycho.core.shared; +import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; public class StatusTool { @@ -71,7 +72,8 @@ private static class HierarchyFormatter { final String listSeparatorString; - HierarchyFormatter(String childrenStart, String indentationIncrement, String listSeparator, String childrenEnd) { + HierarchyFormatter(String childrenStart, String indentationIncrement, String listSeparator, + String childrenEnd) { this("", childrenStart, indentationIncrement, listSeparator, childrenEnd); } @@ -151,4 +153,14 @@ private static Throwable findExceptionInChildren(IStatus[] children) { private static boolean hasChildren(IStatus status) { return status.getChildren() != null && status.getChildren().length > 0; } + + public static IStatus findStatus(Throwable t) { + if (t == null) { + return null; + } + if (t instanceof CoreException e) { + return e.getStatus(); + } + return findStatus(t.getCause()); + } } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/AbstractDirectorApplicationCommand.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/AbstractDirectorApplicationCommand.java index 1d2acbd372..37bfd9bb09 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/AbstractDirectorApplicationCommand.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/AbstractDirectorApplicationCommand.java @@ -14,6 +14,7 @@ import java.io.File; import java.net.URI; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.StringJoiner; @@ -21,6 +22,7 @@ import java.util.stream.Collectors; import org.eclipse.equinox.p2.engine.IPhaseSet; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.tycho.ArtifactType; import org.eclipse.tycho.DependencySeed; import org.eclipse.tycho.TargetEnvironment; @@ -47,6 +49,7 @@ public abstract class AbstractDirectorApplicationCommand implements DirectorRunt private File bundlePool; private IPhaseSet phaseSet; private boolean installSources; + private Collection eeUnits; @Override public final void addMetadataSources(Iterable metadataRepositories) { @@ -172,4 +175,16 @@ public Map getProfileProperties() { return props; } + @Override + public void setEEUnits(Collection eeUnits) { + this.eeUnits = eeUnits; + } + + public Collection getEEUnits() { + if (eeUnits == null) { + return List.of(); + } + return eeUnits; + } + } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java index f87bdab8a1..bf3eb04b1e 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/director/shared/DirectorRuntime.java @@ -14,9 +14,11 @@ import java.io.File; import java.net.URI; +import java.util.Collection; import java.util.Map; import org.eclipse.equinox.p2.engine.IPhaseSet; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.tycho.DependencySeed; import org.eclipse.tycho.PlatformPropertiesUtils; import org.eclipse.tycho.TargetEnvironment; @@ -63,6 +65,8 @@ public interface Command { void setPhaseSet(IPhaseSet phaseSet); void setInstallSources(boolean installSources); + + void setEEUnits(Collection eeUnits); } /** diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/DirectorApplicationWrapper.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/DirectorApplicationWrapper.java index 46bb966dc0..69bf7a3f56 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/DirectorApplicationWrapper.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/DirectorApplicationWrapper.java @@ -72,8 +72,9 @@ public void execute() { } try { - Object exitCode = new DirectorApplication(this, getPhaseSet(), agent, agentProvider) - .run(arguments.toArray(new String[arguments.size()])); + DirectorApplication application = new DirectorApplication(this, getPhaseSet(), agent, agentProvider); + application.setExtraInstallableUnits(getEEUnits()); + Object exitCode = application.run(arguments.toArray(new String[arguments.size()])); if (!(EXIT_OK.equals(exitCode))) { throw new DirectorCommandException("Call to p2 director application failed with exit code " + exitCode + ". Program arguments were: " + arguments + "."); diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/DirectorApplication.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/DirectorApplication.java index 4cd19d9fed..b1d04c35a8 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/DirectorApplication.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/DirectorApplication.java @@ -632,6 +632,7 @@ private static File processFileArgument(String arg) { private IPhaseSet phaseSet; private IProvisioningAgent defaultAgent; private IProvisioningAgentProvider provisioningAgentProvider; + private Collection extraUnits; public DirectorApplication(ILog log, IPhaseSet phaseSet, IProvisioningAgent defaultAgent, IProvisioningAgentProvider provisioningAgentProvider) { @@ -990,7 +991,7 @@ private void initializeServices() throws CoreException { * * @return the current default agent, never null * @throws CoreException - * when fetching the agent failed + * when fetching the agent failed */ protected IProvisioningAgent getDefaultAgent() throws CoreException { return defaultAgent; @@ -1000,10 +1001,10 @@ protected IProvisioningAgent getDefaultAgent() throws CoreException { * Creates a new agent for the given data area * * @param p2DataArea - * the data area to create a new agent + * the data area to create a new agent * @return the new agent, never null * @throws CoreException - * if creation of the agent for the given location failed + * if creation of the agent for the given location failed */ protected IProvisioningAgent createAgent(URI p2DataArea) throws CoreException { IProvisioningAgent agent = provisioningAgentProvider.createAgent(p2DataArea); @@ -1013,8 +1014,8 @@ protected IProvisioningAgent createAgent(URI p2DataArea) throws CoreException { /* * See bug: https://bugs.eclipse.org/340971 Using the event bus to detect whether or not a - * repository was added in a touchpoint action. If it was, then (if it exists) remove it from our - * list of repos to remove after we complete our install. + * repository was added in a touchpoint action. If it was, then (if it exists) remove it from + * our list of repos to remove after we complete our install. */ @Override public void notify(EventObject o) { @@ -1096,6 +1097,9 @@ private void performProvisioningActions() throws CoreException { context.setArtifactRepositories(artifactRepositoryLocations.stream().toArray(URI[]::new)); context.setProperty(ProvisioningContext.FOLLOW_REPOSITORY_REFERENCES, String.valueOf(followReferences)); context.setProperty(FOLLOW_ARTIFACT_REPOSITORY_REFERENCES, String.valueOf(followReferences)); + if (extraUnits != null && !extraUnits.isEmpty()) { + context.setExtraInstallableUnits(List.copyOf(extraUnits)); + } ProfileChangeRequest request = buildProvisioningRequest(profile, installs, uninstalls); printRequest(request); planAndExecute(profile, context, request); @@ -1108,6 +1112,10 @@ private void performProvisioningActions() throws CoreException { } } + public void setExtraInstallableUnits(Collection extraUnits) { + this.extraUnits = extraUnits; + } + private void planAndExecute(IProfile profile, ProvisioningContext context, ProfileChangeRequest request) throws CoreException { IProvisioningPlan result = planner.getProvisioningPlan(request, context, new NullProgressMonitor()); @@ -1412,9 +1420,9 @@ else if (!printHelpInfo && !printIUList && !printRootIUList && !printTags && !pu /** * @param pairs - * a comma separated list of tag=value pairs + * a comma separated list of tag=value pairs * @param properties - * the collection into which the pairs are put + * the collection into which the pairs are put */ private void putProperties(String pairs, Map properties) { String[] propPairs = StringHelper.getArrayFromString(pairs, ','); diff --git a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/MaterializeProductsMojo.java b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/MaterializeProductsMojo.java index dd19313324..6dae367992 100644 --- a/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/MaterializeProductsMojo.java +++ b/tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/MaterializeProductsMojo.java @@ -13,6 +13,8 @@ package org.eclipse.tycho.plugins.p2.director; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -27,9 +29,17 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.toolchain.ToolchainManager; +import org.codehaus.plexus.logging.Logger; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.equinox.p2.metadata.IInstallableUnit; import org.eclipse.tycho.DependencySeed; +import org.eclipse.tycho.ExecutionEnvironment; import org.eclipse.tycho.TargetEnvironment; import org.eclipse.tycho.TychoConstants; +import org.eclipse.tycho.core.ee.ExecutionEnvironmentUtils; +import org.eclipse.tycho.core.ee.impl.StandardEEResolutionHints; +import org.eclipse.tycho.core.shared.StatusTool; import org.eclipse.tycho.p2.tools.RepositoryReferences; import org.eclipse.tycho.p2.tools.director.shared.DirectorCommandException; import org.eclipse.tycho.p2.tools.director.shared.DirectorRuntime; @@ -54,6 +64,17 @@ public enum DirectorRuntimeType { internal, standalone } + /** + *

+ * Comma-separated list of profile names to be published. Examples: JavaSE-11, JavaSE-17, + * JavaSE-18. + * + * If not given, all current available JavaSE profiles with version >= 11 are used. + *

+ */ + @Parameter + private String EEProfiles; + @Component private MojoExecution execution; @@ -63,6 +84,12 @@ public enum DirectorRuntimeType { @Component private StandaloneDirectorRuntimeFactory standaloneDirectorFactory; + @Component + private ToolchainManager toolchainManager; + + @Component + private Logger logger; + @Component DirectorRuntime director; @@ -196,7 +223,18 @@ private void buildProduct(DirectorRuntime director, RepositoryReferences sources if (rootFolder != null && !rootFolder.isEmpty()) { destination = new File(destination, rootFolder); } - + List eeUnits = new ArrayList<>(); + for (String profile : getProductEEProfiles()) { + profile = profile.trim(); + if (profile.isEmpty()) { + continue; + } + ExecutionEnvironment ee = ExecutionEnvironmentUtils.getExecutionEnvironment(profile, toolchainManager, + getSession(), logger); + StandardEEResolutionHints hints = new StandardEEResolutionHints(ee); + eeUnits.addAll(hints.getMandatoryUnits()); + } + command.setEEUnits(eeUnits); command.setBundlePool(getProductBundlePoolDirectory(product)); command.addMetadataSources(sources.getMetadataRepositories()); command.addArtifactSources(sources.getArtifactRepositories()); @@ -215,6 +253,13 @@ private void buildProduct(DirectorRuntime director, RepositoryReferences sources try { command.execute(); } catch (DirectorCommandException e) { + IStatus status = StatusTool.findStatus(e); + if (status != null) { + String logMessage = StatusTool.toLogMessage(status); + getLog().error(logMessage); + throw new MojoFailureException("Installation of product " + product.getId() + " for environment " + env + + " failed: " + logMessage, e); + } throw new MojoFailureException( "Installation of product " + product.getId() + " for environment " + env + " failed", e); } @@ -251,4 +296,13 @@ private RepositoryReferences getTargetPlatformRepositories() throws MojoExecutio int flags = RepositoryReferenceTool.REPOSITORIES_INCLUDE_CURRENT_MODULE; return repositoryReferenceTool.getVisibleRepositories(getProject(), getSession(), flags); } + + private Iterable getProductEEProfiles() { + if (EEProfiles != null && !EEProfiles.isEmpty()) { + return Arrays.asList(EEProfiles.split(",")); + } + return ExecutionEnvironmentUtils.getProfileNames(toolchainManager, getSession(), logger).stream() + .filter(str -> str.startsWith("JavaSE-")) + .filter(profile -> ExecutionEnvironmentUtils.getVersion(profile) >= 11).toList(); + } }