WORKSPACE_LOCKS = new ConcurrentHashMap<>();
+
+ /**
+ * Work area. This includes:
+ *
+ * - <work>/configuration: The configuration area
+ * (-configuration)
+ *
- <work>/data: The data ('workspace') area (-data)
+ *
+ */
+ @Parameter(defaultValue = "${project.build.directory}/eclipserun-work")
+ private File work;
+
+ /**
+ * Whether the workspace should be cleared before running eclipse.
+ *
+ * If {@code false} and a workspace from a previous run exists, that workspace
+ * is reused.
+ *
+ */
+ @Parameter(defaultValue = "true")
+ private boolean clearWorkspaceBeforeLaunch;
+
+ @Parameter(property = "project")
+ private MavenProject project;
+
+ /**
+ * Dependencies which will be resolved transitively to make up the eclipse
+ * runtime. Example:
+ *
+ *
+ * <dependencies>
+ * <dependency>
+ * <artifactId>org.eclipse.ant.core</artifactId>
+ * <type>eclipse-plugin</type>
+ * </dependency>
+ * </dependencies>
+ *
+ */
+ @Parameter
+ private List dependencies = new ArrayList<>();
+
+ /**
+ * Whether to add default dependencies to bundles org.eclipse.equinox.launcher,
+ * org.eclipse.osgi and org.eclipse.core.runtime.
+ */
+ @Parameter(defaultValue = "true")
+ private boolean addDefaultDependencies;
+
+ /**
+ * Execution environment profile name used to resolve dependencies.
+ */
+ @Parameter(defaultValue = "JavaSE-17")
+ private String executionEnvironment;
+
+ /**
+ * p2 repositories which will be used to resolve dependencies. Example:
+ *
+ *
+ * <repositories>
+ * <repository>
+ * <id>juno</id>
+ * <layout>p2</layout>
+ * <url>https://download.eclipse.org/releases/juno</url>
+ * </repository>
+ * </repositories>
+ *
+ */
+ @Parameter(required = true)
+ private List repositories;
+
+ @Parameter(property = "session", readonly = true, required = true)
+ private MavenSession session;
+
+ /**
+ * Arbitrary JVM options to set on the command line. It is recommended to use
+ * {@link #jvmArgs} instead because it provides more explicit control over
+ * argument separation and content, avoiding the need to quote arguments that
+ * contain spaces.
+ *
+ * @see #jvmArgs
+ */
+ @Parameter
+ private String argLine;
+
+ /**
+ * List of JVM arguments set on the command line. Example:
+ *
+ * {@code
+ *
+ * -Xdebug
+ * -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
+ *
+ * }
+ *
+ * @since 0.25.0
+ */
+ @Parameter
+ private List jvmArgs;
+
+ /**
+ * Whether to skip mojo execution.
+ */
+ @Parameter(property = "eclipserun.skip", defaultValue = "false")
+ private boolean skip;
+
+ /**
+ * Arbitrary applications arguments to set on the command line. It is
+ * recommended to use {@link #applicationArgs} instead because it provides more
+ * explicit control over argument separation and content, avoiding the need to
+ * quote arguments that contain spaces.
+ *
+ * @see #applicationArgs
+ */
+ @Parameter
+ private String appArgLine;
+
+ /**
+ * List of applications arguments set on the command line. Example:
+ *
+ * {@code
+ *
+ * -buildfile
+ * build-test.xml
+ *
+ * }
+ *
+ * @since 0.24.0
+ */
+ @Parameter(alias = "applicationsArgs")
+ private List applicationArgs;
+
+ /**
+ * Kill the forked process after a certain number of seconds. If set to 0, wait
+ * forever for the process, never timing out.
+ */
+ @Parameter(property = "eclipserun.timeout")
+ private int forkedProcessTimeoutInSeconds;
+
+ /**
+ * Additional environments to set for the forked JVM.
+ */
+ @Parameter
+ private Map environmentVariables;
+
+ /**
+ * Bundle start level and auto start configuration used by the eclipse runtime.
+ * Example:
+ *
+ *
+ * <bundleStartLevel>
+ * <bundle>
+ * <id>foo.bar.myplugin</id>
+ * <level>6</level>
+ * <autoStart>true</autoStart>
+ * </bundle>
+ * </bundleStartLevel>
+ *
+ */
+ @Parameter
+ private BundleStartLevel[] bundleStartLevel;
+
+ /**
+ * The default bundle start level and auto start configuration used by the
+ * runtime for bundles where the start level/auto start is not configured in
+ * {@link #bundleStartLevel}. Example:
+ *
+ *
+ * <defaultStartLevel>
+ * <level>6</level>
+ * <autoStart>true</autoStart>
+ * </defaultStartLevel>
+ *
+ */
+ @Parameter
+ private BundleStartLevel defaultStartLevel;
+
+ @Component
+ private EquinoxInstallationFactory installationFactory;
+
+ @Component
+ private EquinoxLauncher launcher;
+
+ @Component
+ private ToolchainProvider toolchainProvider;
+
+ @Component()
+ P2ResolverFactory resolverFactory;
+
+ @Component
+ private Logger logger;
+
+ @Component
+ private ToolchainManager toolchainManager;
+
+ public EclipseRunMojo() {
+ // default constructor
+ }
+
+ /**
+ * Constructor for use of EclipseRunMojo in other Mojos.
+ */
+ public EclipseRunMojo(File work, boolean clearWorkspaceBeforeLaunch, MavenProject project,
+ List dependencies, boolean addDefaultDependencies, String executionEnvironment,
+ List repositories, MavenSession session, List jvmArgs, boolean skip,
+ List applicationArgs, int forkedProcessTimeoutInSeconds, Map environmentVariables,
+ EquinoxInstallationFactory installationFactory, EquinoxLauncher launcher,
+ ToolchainProvider toolchainProvider, P2ResolverFactory resolverFactory, Logger logger,
+ ToolchainManager toolchainManager) {
+ this.work = work;
+ this.clearWorkspaceBeforeLaunch = clearWorkspaceBeforeLaunch;
+ this.project = project;
+ this.dependencies = dependencies;
+ this.addDefaultDependencies = addDefaultDependencies;
+ this.executionEnvironment = executionEnvironment;
+ this.repositories = repositories;
+ this.session = session;
+ this.jvmArgs = jvmArgs;
+ this.skip = skip;
+ this.applicationArgs = applicationArgs;
+ this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
+ this.environmentVariables = environmentVariables;
+ this.installationFactory = installationFactory;
+ this.launcher = launcher;
+ this.toolchainProvider = toolchainProvider;
+ this.resolverFactory = resolverFactory;
+ this.logger = logger;
+ this.toolchainManager = toolchainManager;
+ }
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ if (skip) {
+ getLog().info("Execution was skipped");
+ return;
+ }
+ EquinoxInstallation installation;
+ synchronized (CREATE_LOCK) {
+ installation = createEclipseInstallation();
+ }
+ runEclipse(installation);
+ }
+
+ private void addDefaultDependency(P2Resolver resolver, String bundleId) {
+ try {
+ resolver.addDependency(ArtifactType.TYPE_ECLIPSE_PLUGIN, bundleId, null);
+ } catch (IllegalArtifactReferenceException e) {
+ // shouldn't happen for the constant type and version
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void addDefaultDependencies(P2Resolver resolver) {
+ if (addDefaultDependencies) {
+ addDefaultDependency(resolver, "org.eclipse.osgi");
+ addDefaultDependency(resolver, DefaultEquinoxInstallationDescription.EQUINOX_LAUNCHER);
+ addDefaultDependency(resolver, "org.eclipse.core.runtime");
+ }
+ }
+
+ private EquinoxInstallation createEclipseInstallation() throws MojoFailureException {
+ TargetPlatformConfigurationStub tpConfiguration = new TargetPlatformConfigurationStub();
+ // we want to resolve from remote repos only
+ tpConfiguration.setIgnoreLocalArtifacts(true);
+ for (Repository repository : repositories) {
+ tpConfiguration.addP2Repository(new MavenRepositoryLocation(repository.getId(), repository.getLocation()));
+ }
+ ExecutionEnvironmentConfiguration eeConfiguration = new ExecutionEnvironmentConfigurationImpl(logger, false,
+ toolchainManager, session);
+ eeConfiguration.setProfileConfiguration(executionEnvironment, "tycho-eclipserun-plugin ");
+ TargetPlatform targetPlatform = resolverFactory.getTargetPlatformFactory().createTargetPlatform(tpConfiguration,
+ eeConfiguration, null);
+ P2Resolver resolver = resolverFactory
+ .createResolver(Collections.singletonList(TargetEnvironment.getRunningEnvironment()));
+ for (Dependency dependency : dependencies) {
+ try {
+ resolver.addDependency(dependency.getType(), dependency.getArtifactId(), dependency.getVersion());
+ } catch (IllegalArtifactReferenceException e) {
+ throw new MojoFailureException("Invalid dependency " + dependency.getType() + ":"
+ + dependency.getArtifactId() + ":" + dependency.getVersion() + ": " + e.getMessage(), e);
+ }
+ }
+ addDefaultDependencies(resolver);
+ EquinoxInstallationDescription installationDesc = new DefaultEquinoxInstallationDescription();
+ for (P2ResolutionResult result : resolver.resolveTargetDependencies(targetPlatform, null).values()) {
+ for (Entry entry : result.getArtifacts()) {
+ if (ArtifactType.TYPE_ECLIPSE_PLUGIN.equals(entry.getType())) {
+ installationDesc.addBundle(entry.getId(), entry.getVersion(), entry.getLocation(true));
+ }
+ }
+ }
+ installationDesc.setDefaultBundleStartLevel(defaultStartLevel);
+ if (bundleStartLevel != null) {
+ for (BundleStartLevel level : bundleStartLevel) {
+ installationDesc.addBundleStartLevel(level);
+ }
+ }
+ return installationFactory.createInstallation(installationDesc, work);
+ }
+
+ public void runEclipse(EquinoxInstallation runtime) throws MojoExecutionException {
+ try {
+ File workspace = new File(work, "data").getAbsoluteFile();
+ synchronized (WORKSPACE_LOCKS.computeIfAbsent(workspace.getAbsolutePath(), k -> new Object())) {
+ if (clearWorkspaceBeforeLaunch) {
+ FileUtils.deleteDirectory(workspace);
+ }
+ LaunchConfiguration cli = createCommandLine(runtime);
+ File expectedLog = new File(workspace, ".metadata/.log");
+ getLog().info("Expected Eclipse log file: " + expectedLog.getCanonicalPath());
+ int returnCode = launcher.execute(cli, forkedProcessTimeoutInSeconds);
+ if (returnCode != 0) {
+ throw new MojoExecutionException("Error while executing platform: return code=" + returnCode
+ + ", see content of " + expectedLog + "for more details.");
+ }
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException("Error while executing platform", e);
+ }
+ }
+
+ public LaunchConfiguration createCommandLine(EquinoxInstallation runtime) throws MojoExecutionException {
+ EquinoxLaunchConfiguration cli = new EquinoxLaunchConfiguration(runtime);
+
+ String executable = null;
+ Toolchain tc = getToolchain();
+ if (tc != null) {
+ getLog().info("Toolchain in tycho-eclipserun-plugin: " + tc);
+ executable = tc.findTool("java");
+ if (executable == null) {
+ getLog().error("No 'java' executable was found in toolchain. Current Java runtime will be used");
+ }
+ } else if (Objects.equals(executionEnvironment, "JavaSE-" + Runtime.version().feature())) {
+ getLog().debug("Using current Java runtime as it matches configured executionEnvironment");
+ } else {
+ getLog().warn("No toolchain was found in tycho-eclipserun-plugin for: " + executionEnvironment
+ + ". Current Java runtime will be used");
+ }
+ cli.setJvmExecutable(executable);
+ cli.setWorkingDirectory(project.getBasedir());
+
+ cli.addVMArguments(splitArgLine(argLine));
+ if (jvmArgs != null) {
+ cli.addVMArguments(jvmArgs.toArray(new String[jvmArgs.size()]));
+ }
+
+ addProgramArgs(cli, "-install", runtime.getLocation().getAbsolutePath(), "-configuration",
+ new File(work, "configuration").getAbsolutePath());
+
+ File workspace = new File(work, "data");
+ addProgramArgs(cli, "-data", workspace.getAbsolutePath());
+
+ cli.addProgramArguments(splitArgLine(appArgLine));
+ if (applicationArgs != null) {
+ for (String arg : applicationArgs) {
+ cli.addProgramArguments(arg);
+ }
+ }
+
+ if (environmentVariables != null) {
+ cli.addEnvironmentVariables(environmentVariables);
+ }
+
+ return cli;
+ }
+
+ private String[] splitArgLine(String argumentLine) throws MojoExecutionException {
+ try {
+ return CommandLineUtils.translateCommandline(argumentLine);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Error parsing commandline: " + e.getMessage(), e);
+ }
+ }
+
+ private void addProgramArgs(EquinoxLaunchConfiguration cli, String... arguments) {
+ if (arguments != null) {
+ for (String argument : arguments) {
+ if (argument != null) {
+ cli.addProgramArguments(argument);
+ }
+ }
+ }
+ }
+
+ private Toolchain getToolchain() throws MojoExecutionException {
+ return toolchainProvider.findMatchingJavaToolChain(session, executionEnvironment);
+ }
+
+}
diff --git a/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipserun/Repository.java b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipserun/Repository.java
new file mode 100644
index 0000000000..b7f6579ae8
--- /dev/null
+++ b/tycho-eclipse-plugin/src/main/java/org/eclipse/tycho/eclipserun/Repository.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright (c) 2011 SAP AG and others.
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Tobias Oberlies - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tycho.eclipserun;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+public final class Repository {
+
+ public enum Layout {
+ BOTH("p2"), METADATA("p2-metadata"), ARTIFACTS("p2-artifacts");
+
+ private String literal;
+
+ private Layout(String literal) {
+ this.literal = literal;
+ }
+
+ boolean matches(String value) {
+ return literal.equals(value);
+ }
+
+ public boolean hasMetadata() {
+ return this != ARTIFACTS;
+ }
+
+ public boolean hasArtifacts() {
+ return this != METADATA;
+ }
+
+ @Override
+ public String toString() {
+ return literal;
+ }
+ }
+
+ private String id;
+
+ private URI url;
+
+ private Layout layout = Layout.BOTH;
+
+ public Repository() {
+ }
+
+ public Repository(URI location) {
+ this.url = location;
+ }
+
+ /**
+ * @return never null
+ */
+ public URI getLocation() {
+ if (url == null)
+ throw new IllegalStateException("Attribute 'url' is required for source repositories");
+ return url;
+ }
+
+ /**
+ * @return never null
+ */
+ public Layout getLayout() {
+ return layout;
+ }
+
+ /**
+ * @return may be null
+ */
+ public String getId() {
+ return id;
+ }
+
+ public void setLayout(String value) {
+ for (Layout layout : Layout.values()) {
+ if (layout.matches(value)) {
+ this.layout = layout;
+ return;
+ }
+ }
+ String values = Arrays.stream(Layout.values()).map(Object::toString).collect(Collectors.joining(", "));
+ throw new IllegalArgumentException(
+ "Unrecognized value for attribute 'layout': \"" + value + "\". Valid values are: " + values);
+ }
+
+}
diff --git a/tycho-extras/tycho-eclipserun-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/tycho-eclipse-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
similarity index 100%
rename from tycho-extras/tycho-eclipserun-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
rename to tycho-eclipse-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
diff --git a/tycho-extras/tycho-eclipserun-plugin/src/test/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojoTest.java b/tycho-eclipse-plugin/src/test/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojoTest.java
similarity index 95%
rename from tycho-extras/tycho-eclipserun-plugin/src/test/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojoTest.java
rename to tycho-eclipse-plugin/src/test/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojoTest.java
index 5880c7433d..853571bdb5 100644
--- a/tycho-extras/tycho-eclipserun-plugin/src/test/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojoTest.java
+++ b/tycho-eclipse-plugin/src/test/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojoTest.java
@@ -27,6 +27,7 @@
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.testing.SilentLog;
import org.apache.maven.project.MavenProject;
+import org.apache.maven.toolchain.java.DefaultJavaToolChain;
import org.eclipse.sisu.equinox.launching.EquinoxInstallation;
import org.eclipse.sisu.equinox.launching.EquinoxLauncher;
import org.eclipse.sisu.equinox.launching.LaunchConfiguration;
@@ -35,6 +36,7 @@
import org.eclipse.tycho.core.maven.ToolchainProvider;
import org.eclipse.tycho.core.resolver.P2Resolver;
import org.eclipse.tycho.core.resolver.P2ResolverFactory;
+import org.eclipse.tycho.eclipserun.EclipseRunMojo;
import org.eclipse.tycho.p2.target.facade.TargetPlatformFactory;
import org.eclipse.tycho.testing.AbstractTychoMojoTestCase;
import org.eclipse.tycho.version.TychoVersion;
@@ -52,7 +54,7 @@ public class EclipseRunMojoTest extends AbstractTychoMojoTestCase {
public void setUp() throws Exception {
super.setUp();
- runMojo = (EclipseRunMojo) lookupMojo("org.eclipse.tycho.extras", "tycho-eclipserun-plugin",
+ runMojo = (EclipseRunMojo) lookupMojo("org.eclipse.tycho", "tycho-eclipse-plugin",
TychoVersion.getTychoVersion(), "eclipse-run", null);
runMojo.setLog(new SilentLog());
MavenSession mavenSession = newMavenSession(mock(MavenProject.class));
@@ -153,11 +155,10 @@ public void testExecutionEnvironmentIsRespectedDuringDependencyResolution() thro
}
public void testExecutionEnvironmentIsRespectedDuringEclipseExecution() throws Exception {
- @SuppressWarnings("deprecation")
- org.apache.maven.toolchain.java.DefaultJavaToolChain mockToolchainForCustomEE = mock(
- org.apache.maven.toolchain.java.DefaultJavaToolChain.class);
+ DefaultJavaToolChain mockToolchainForCustomEE = mock(DefaultJavaToolChain.class);
when(mockToolchainForCustomEE.findTool("java")).thenReturn("/path/to/custom-ee-jdk/bin/java");
- when(toolchainProvider.findMatchingJavaToolChain(any(), eq("custom-ee"))).thenReturn(mockToolchainForCustomEE);
+ when(toolchainProvider.findMatchingJavaToolChain(any(), eq("custom-ee")))
+ .thenReturn(mockToolchainForCustomEE);
setVariableValueToObject(runMojo, "executionEnvironment", "custom-ee");
diff --git a/tycho-extras/tycho-eclipserun-plugin/pom.xml b/tycho-extras/tycho-eclipserun-plugin/pom.xml
index e3582080b7..9a5b2ab57c 100644
--- a/tycho-extras/tycho-eclipserun-plugin/pom.xml
+++ b/tycho-extras/tycho-eclipserun-plugin/pom.xml
@@ -23,6 +23,13 @@
${minimal-maven-version}
+
+
+ org.eclipse.tycho
+ tycho-eclipse-plugin
+ The eclipse-run mojo is now part of the tycho-eclipse-plugin
+
+
Tycho Eclipserun Plugin
@@ -57,15 +64,10 @@
org.eclipse.tycho
- tycho-testing-harness
- test
-
-
- org.mockito
- mockito-core
- test
+ tycho-eclipse-plugin
+ ${project.version}
-
+
its
diff --git a/tycho-extras/tycho-eclipserun-plugin/src/main/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojo.java b/tycho-extras/tycho-eclipserun-plugin/src/main/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojo.java
index ac3d619b63..934d112b82 100644
--- a/tycho-extras/tycho-eclipserun-plugin/src/main/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojo.java
+++ b/tycho-extras/tycho-eclipserun-plugin/src/main/java/org/eclipse/tycho/extras/eclipserun/EclipseRunMojo.java
@@ -14,257 +14,28 @@
package org.eclipse.tycho.extras.eclipserun;
import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Dependency;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
-import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.util.FileUtils;
-import org.codehaus.plexus.util.cli.CommandLineUtils;
-import org.eclipse.sisu.equinox.launching.BundleStartLevel;
-import org.eclipse.sisu.equinox.launching.DefaultEquinoxInstallationDescription;
-import org.eclipse.sisu.equinox.launching.EquinoxInstallation;
-import org.eclipse.sisu.equinox.launching.EquinoxInstallationDescription;
import org.eclipse.sisu.equinox.launching.EquinoxInstallationFactory;
import org.eclipse.sisu.equinox.launching.EquinoxLauncher;
-import org.eclipse.sisu.equinox.launching.LaunchConfiguration;
-import org.eclipse.sisu.equinox.launching.internal.EquinoxLaunchConfiguration;
-import org.eclipse.tycho.ArtifactType;
-import org.eclipse.tycho.ExecutionEnvironmentConfiguration;
-import org.eclipse.tycho.IllegalArtifactReferenceException;
-import org.eclipse.tycho.MavenRepositoryLocation;
-import org.eclipse.tycho.TargetEnvironment;
-import org.eclipse.tycho.TargetPlatform;
-import org.eclipse.tycho.core.ee.ExecutionEnvironmentConfigurationImpl;
import org.eclipse.tycho.core.maven.ToolchainProvider;
-import org.eclipse.tycho.core.resolver.P2ResolutionResult;
-import org.eclipse.tycho.core.resolver.P2ResolutionResult.Entry;
-import org.eclipse.tycho.core.resolver.P2Resolver;
import org.eclipse.tycho.core.resolver.P2ResolverFactory;
-import org.eclipse.tycho.p2.target.facade.TargetPlatformConfigurationStub;
-import org.eclipse.tycho.plugins.p2.extras.Repository;
+import org.eclipse.tycho.eclipserun.Repository;
/**
* Launch an eclipse process with arbitrary commandline arguments. The eclipse
* installation is defined by the dependencies to bundles specified.
*/
@Mojo(name = "eclipse-run", threadSafe = true)
-public class EclipseRunMojo extends AbstractMojo {
-
- /**
- * Lock object to ensure thread-safety
- */
- private static final Object CREATE_LOCK = new Object();
-
- private static final ConcurrentMap WORKSPACE_LOCKS = new ConcurrentHashMap<>();
-
- /**
- * Work area. This includes:
- *
- * - <work>/configuration: The configuration area
- * (-configuration)
- *
- <work>/data: The data ('workspace') area (-data)
- *
- */
- @Parameter(defaultValue = "${project.build.directory}/eclipserun-work")
- private File work;
-
- /**
- * Whether the workspace should be cleared before running eclipse.
- *
- * If {@code false} and a workspace from a previous run exists, that workspace
- * is reused.
- *
- */
- @Parameter(defaultValue = "true")
- private boolean clearWorkspaceBeforeLaunch;
-
- @Parameter(property = "project")
- private MavenProject project;
-
- /**
- * Dependencies which will be resolved transitively to make up the eclipse
- * runtime. Example:
- *
- *
- * <dependencies>
- * <dependency>
- * <artifactId>org.eclipse.ant.core</artifactId>
- * <type>eclipse-plugin</type>
- * </dependency>
- * </dependencies>
- *
- */
- @Parameter
- private List dependencies = new ArrayList<>();
-
- /**
- * Whether to add default dependencies to bundles org.eclipse.equinox.launcher,
- * org.eclipse.osgi and org.eclipse.core.runtime.
- */
- @Parameter(defaultValue = "true")
- private boolean addDefaultDependencies;
-
- /**
- * Execution environment profile name used to resolve dependencies.
- */
- @Parameter(defaultValue = "JavaSE-17")
- private String executionEnvironment;
-
- /**
- * p2 repositories which will be used to resolve dependencies. Example:
- *
- *
- * <repositories>
- * <repository>
- * <id>juno</id>
- * <layout>p2</layout>
- * <url>https://download.eclipse.org/releases/juno</url>
- * </repository>
- * </repositories>
- *
- */
- @Parameter(required = true)
- private List repositories;
-
- @Parameter(property = "session", readonly = true, required = true)
- private MavenSession session;
-
- /**
- * Arbitrary JVM options to set on the command line. It is recommended to use
- * {@link #jvmArgs} instead because it provides more explicit control over
- * argument separation and content, avoiding the need to quote arguments that
- * contain spaces.
- *
- * @see #jvmArgs
- */
- @Parameter
- private String argLine;
-
- /**
- * List of JVM arguments set on the command line. Example:
- *
- * {@code
- *
- * -Xdebug
- * -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044
- *
- * }
- *
- * @since 0.25.0
- */
- @Parameter
- private List jvmArgs;
-
- /**
- * Whether to skip mojo execution.
- */
- @Parameter(property = "eclipserun.skip", defaultValue = "false")
- private boolean skip;
-
- /**
- * Arbitrary applications arguments to set on the command line. It is
- * recommended to use {@link #applicationArgs} instead because it provides more
- * explicit control over argument separation and content, avoiding the need to
- * quote arguments that contain spaces.
- *
- * @see #applicationArgs
- */
- @Parameter
- private String appArgLine;
-
- /**
- * List of applications arguments set on the command line. Example:
- *
- * {@code
- *
- * -buildfile
- * build-test.xml
- *
- * }
- *
- * @since 0.24.0
- */
- @Parameter(alias = "applicationsArgs")
- private List applicationArgs;
-
- /**
- * Kill the forked process after a certain number of seconds. If set to 0, wait
- * forever for the process, never timing out.
- */
- @Parameter(property = "eclipserun.timeout")
- private int forkedProcessTimeoutInSeconds;
-
- /**
- * Additional environments to set for the forked JVM.
- */
- @Parameter
- private Map environmentVariables;
-
- /**
- * Bundle start level and auto start configuration used by the eclipse runtime.
- * Example:
- *
- *
- * <bundleStartLevel>
- * <bundle>
- * <id>foo.bar.myplugin</id>
- * <level>6</level>
- * <autoStart>true</autoStart>
- * </bundle>
- * </bundleStartLevel>
- *
- */
- @Parameter
- private BundleStartLevel[] bundleStartLevel;
-
- /**
- * The default bundle start level and auto start configuration used by the
- * runtime for bundles where the start level/auto start is not configured in
- * {@link #bundleStartLevel}. Example:
- *
- *
- * <defaultStartLevel>
- * <level>6</level>
- * <autoStart>true</autoStart>
- * </defaultStartLevel>
- *
- */
- @Parameter
- private BundleStartLevel defaultStartLevel;
-
- @Component
- private EquinoxInstallationFactory installationFactory;
-
- @Component
- private EquinoxLauncher launcher;
-
- @Component
- private ToolchainProvider toolchainProvider;
-
- @Component()
- P2ResolverFactory resolverFactory;
-
- @Component
- private Logger logger;
-
- @Component
- private ToolchainManager toolchainManager;
+@Deprecated
+public class EclipseRunMojo extends org.eclipse.tycho.eclipserun.EclipseRunMojo {
public EclipseRunMojo() {
// default constructor
@@ -280,183 +51,9 @@ public EclipseRunMojo(File work, boolean clearWorkspaceBeforeLaunch, MavenProjec
EquinoxInstallationFactory installationFactory, EquinoxLauncher launcher,
ToolchainProvider toolchainProvider, P2ResolverFactory resolverFactory, Logger logger,
ToolchainManager toolchainManager) {
- this.work = work;
- this.clearWorkspaceBeforeLaunch = clearWorkspaceBeforeLaunch;
- this.project = project;
- this.dependencies = dependencies;
- this.addDefaultDependencies = addDefaultDependencies;
- this.executionEnvironment = executionEnvironment;
- this.repositories = repositories;
- this.session = session;
- this.jvmArgs = jvmArgs;
- this.skip = skip;
- this.applicationArgs = applicationArgs;
- this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
- this.environmentVariables = environmentVariables;
- this.installationFactory = installationFactory;
- this.launcher = launcher;
- this.toolchainProvider = toolchainProvider;
- this.resolverFactory = resolverFactory;
- this.logger = logger;
- this.toolchainManager = toolchainManager;
- }
-
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException {
- if (skip) {
- getLog().info("Execution was skipped");
- return;
- }
- EquinoxInstallation installation;
- synchronized (CREATE_LOCK) {
- installation = createEclipseInstallation();
- }
- runEclipse(installation);
- }
-
- private void addDefaultDependency(P2Resolver resolver, String bundleId) {
- try {
- resolver.addDependency(ArtifactType.TYPE_ECLIPSE_PLUGIN, bundleId, null);
- } catch (IllegalArtifactReferenceException e) {
- // shouldn't happen for the constant type and version
- throw new RuntimeException(e);
- }
- }
-
- private void addDefaultDependencies(P2Resolver resolver) {
- if (addDefaultDependencies) {
- addDefaultDependency(resolver, "org.eclipse.osgi");
- addDefaultDependency(resolver, DefaultEquinoxInstallationDescription.EQUINOX_LAUNCHER);
- addDefaultDependency(resolver, "org.eclipse.core.runtime");
- }
+ super(work, clearWorkspaceBeforeLaunch, project, dependencies, addDefaultDependencies, executionEnvironment,
+ repositories, session, jvmArgs, skip, applicationArgs, forkedProcessTimeoutInSeconds,
+ environmentVariables, installationFactory, launcher, toolchainProvider, resolverFactory, logger,
+ toolchainManager);
}
-
- private EquinoxInstallation createEclipseInstallation() throws MojoFailureException {
- TargetPlatformConfigurationStub tpConfiguration = new TargetPlatformConfigurationStub();
- // we want to resolve from remote repos only
- tpConfiguration.setIgnoreLocalArtifacts(true);
- for (Repository repository : repositories) {
- tpConfiguration.addP2Repository(new MavenRepositoryLocation(repository.getId(), repository.getLocation()));
- }
- ExecutionEnvironmentConfiguration eeConfiguration = new ExecutionEnvironmentConfigurationImpl(logger, false,
- toolchainManager, session);
- eeConfiguration.setProfileConfiguration(executionEnvironment, "tycho-eclipserun-plugin ");
- TargetPlatform targetPlatform = resolverFactory.getTargetPlatformFactory().createTargetPlatform(tpConfiguration,
- eeConfiguration, null);
- P2Resolver resolver = resolverFactory
- .createResolver(Collections.singletonList(TargetEnvironment.getRunningEnvironment()));
- for (Dependency dependency : dependencies) {
- try {
- resolver.addDependency(dependency.getType(), dependency.getArtifactId(), dependency.getVersion());
- } catch (IllegalArtifactReferenceException e) {
- throw new MojoFailureException("Invalid dependency " + dependency.getType() + ":"
- + dependency.getArtifactId() + ":" + dependency.getVersion() + ": " + e.getMessage(), e);
- }
- }
- addDefaultDependencies(resolver);
- EquinoxInstallationDescription installationDesc = new DefaultEquinoxInstallationDescription();
- for (P2ResolutionResult result : resolver.resolveTargetDependencies(targetPlatform, null).values()) {
- for (Entry entry : result.getArtifacts()) {
- if (ArtifactType.TYPE_ECLIPSE_PLUGIN.equals(entry.getType())) {
- installationDesc.addBundle(entry.getId(), entry.getVersion(), entry.getLocation(true));
- }
- }
- }
- installationDesc.setDefaultBundleStartLevel(defaultStartLevel);
- if (bundleStartLevel != null) {
- for (BundleStartLevel level : bundleStartLevel) {
- installationDesc.addBundleStartLevel(level);
- }
- }
- return installationFactory.createInstallation(installationDesc, work);
- }
-
- void runEclipse(EquinoxInstallation runtime) throws MojoExecutionException {
- try {
- File workspace = new File(work, "data").getAbsoluteFile();
- synchronized (WORKSPACE_LOCKS.computeIfAbsent(workspace.getAbsolutePath(), k -> new Object())) {
- if (clearWorkspaceBeforeLaunch) {
- FileUtils.deleteDirectory(workspace);
- }
- LaunchConfiguration cli = createCommandLine(runtime);
- File expectedLog = new File(workspace, ".metadata/.log");
- getLog().info("Expected Eclipse log file: " + expectedLog.getCanonicalPath());
- int returnCode = launcher.execute(cli, forkedProcessTimeoutInSeconds);
- if (returnCode != 0) {
- throw new MojoExecutionException("Error while executing platform: return code=" + returnCode
- + ", see content of " + expectedLog + "for more details.");
- }
- }
- } catch (Exception e) {
- throw new MojoExecutionException("Error while executing platform", e);
- }
- }
-
- LaunchConfiguration createCommandLine(EquinoxInstallation runtime) throws MojoExecutionException {
- EquinoxLaunchConfiguration cli = new EquinoxLaunchConfiguration(runtime);
-
- String executable = null;
- Toolchain tc = getToolchain();
- if (tc != null) {
- getLog().info("Toolchain in tycho-eclipserun-plugin: " + tc);
- executable = tc.findTool("java");
- if (executable == null) {
- getLog().error("No 'java' executable was found in toolchain. Current Java runtime will be used");
- }
- } else if (Objects.equals(executionEnvironment, "JavaSE-" + Runtime.version().feature())) {
- getLog().debug("Using current Java runtime as it matches configured executionEnvironment");
- } else {
- getLog().warn("No toolchain was found in tycho-eclipserun-plugin for: " + executionEnvironment
- + ". Current Java runtime will be used");
- }
- cli.setJvmExecutable(executable);
- cli.setWorkingDirectory(project.getBasedir());
-
- cli.addVMArguments(splitArgLine(argLine));
- if (jvmArgs != null) {
- cli.addVMArguments(jvmArgs.toArray(new String[jvmArgs.size()]));
- }
-
- addProgramArgs(cli, "-install", runtime.getLocation().getAbsolutePath(), "-configuration",
- new File(work, "configuration").getAbsolutePath());
-
- File workspace = new File(work, "data");
- addProgramArgs(cli, "-data", workspace.getAbsolutePath());
-
- cli.addProgramArguments(splitArgLine(appArgLine));
- if (applicationArgs != null) {
- for (String arg : applicationArgs) {
- cli.addProgramArguments(arg);
- }
- }
-
- if (environmentVariables != null) {
- cli.addEnvironmentVariables(environmentVariables);
- }
-
- return cli;
- }
-
- private String[] splitArgLine(String argumentLine) throws MojoExecutionException {
- try {
- return CommandLineUtils.translateCommandline(argumentLine);
- } catch (Exception e) {
- throw new MojoExecutionException("Error parsing commandline: " + e.getMessage(), e);
- }
- }
-
- private void addProgramArgs(EquinoxLaunchConfiguration cli, String... arguments) {
- if (arguments != null) {
- for (String argument : arguments) {
- if (argument != null) {
- cli.addProgramArguments(argument);
- }
- }
- }
- }
-
- private Toolchain getToolchain() throws MojoExecutionException {
- return toolchainProvider.findMatchingJavaToolChain(session, executionEnvironment);
- }
-
}
diff --git a/tycho-spi/src/main/java/org/eclipse/tycho/helper/PluginConfigurationHelper.java b/tycho-spi/src/main/java/org/eclipse/tycho/helper/PluginConfigurationHelper.java
index e8dce66a84..1ffeafa52d 100644
--- a/tycho-spi/src/main/java/org/eclipse/tycho/helper/PluginConfigurationHelper.java
+++ b/tycho-spi/src/main/java/org/eclipse/tycho/helper/PluginConfigurationHelper.java
@@ -15,6 +15,8 @@
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@@ -129,11 +131,7 @@ public Optional getChild(String name) {
public Optional getString(String name) {
return getChild(name).map(child -> {
- String value = child.configuration.getValue();
- if (value == null) {
- return child.configuration.getAttribute("default-value");
- }
- return value;
+ return getValue(child.configuration);
});
}
@@ -158,6 +156,22 @@ public String toString() {
return configuration == null ? "-empty configuration-" : String.valueOf(configuration);
}
+ public Optional> getStringList(String name) {
+ return getChild(name).map(child -> {
+ return Arrays.stream(child.configuration.getChildren()).map(PluginConfigurationHelper::getValue)
+ .toList();
+ });
+
+ }
+
+ }
+
+ private static String getValue(Xpp3Dom dom) {
+ String value = dom.getValue();
+ if (value == null) {
+ return dom.getAttribute("default-value");
+ }
+ return value;
}
}
diff --git a/tycho-spi/src/main/java/org/eclipse/tycho/resolver/InstallableUnitProvider.java b/tycho-spi/src/main/java/org/eclipse/tycho/resolver/InstallableUnitProvider.java
index 4813bde1b2..936f4a2906 100644
--- a/tycho-spi/src/main/java/org/eclipse/tycho/resolver/InstallableUnitProvider.java
+++ b/tycho-spi/src/main/java/org/eclipse/tycho/resolver/InstallableUnitProvider.java
@@ -1,26 +1,49 @@
package org.eclipse.tycho.resolver;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Stream;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.IRequirement;
+import org.eclipse.equinox.p2.metadata.MetadataFactory;
+import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription;
+import org.eclipse.equinox.p2.metadata.Version;
/**
- * Components implementing this interface can provide additional project units,
- * for example source features/bundles.
+ * Components implementing this interface can provide additional project units, for example source
+ * features/bundles.
*/
public interface InstallableUnitProvider {
- /**
- * Computes the {@link IInstallableUnit}s for the given maven project
- *
- * @param project
- * @param session
- * @return the collection of units, probably empty but never null
- * @throws CoreException if anything goes wrong
- */
- Collection getInstallableUnits(MavenProject project, MavenSession session) throws CoreException;
+ /**
+ * Computes the {@link IInstallableUnit}s for the given maven project
+ *
+ * @param project
+ * @param session
+ * @return the collection of units, probably empty but never null
+ * @throws CoreException
+ * if anything goes wrong
+ */
+ Collection getInstallableUnits(MavenProject project, MavenSession session) throws CoreException;
+ static Collection createIU(Stream requirements, String idPrefix) {
+ return createIU(requirements.toList(), idPrefix);
+ }
+
+ static Collection createIU(List requirements, String idPrefix) {
+ if (requirements.isEmpty()) {
+ return Collections.emptyList();
+ }
+ InstallableUnitDescription result = new MetadataFactory.InstallableUnitDescription();
+ result.setId(idPrefix + "-" + UUID.randomUUID());
+ result.setVersion(Version.createOSGi(0, 0, 0, String.valueOf(System.currentTimeMillis())));
+ result.addRequirements(requirements);
+ return List.of(MetadataFactory.createInstallableUnit(result));
+ }
}