Skip to content

Commit

Permalink
Configure Maven Execution JRE separately
Browse files Browse the repository at this point in the history
The value is automatically derived from maven-enforcer rule requireJava

This closes eclipse-m2e#1134
This closes eclipse-m2e#1099

Co-authored-by: Hannes Wellmann <wellmann.hannes1@gmx.net>
  • Loading branch information
kwin and HannesWell committed Feb 27, 2023
1 parent f866bd7 commit e92b0d3
Show file tree
Hide file tree
Showing 14 changed files with 501 additions and 193 deletions.
16 changes: 15 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## 2.2.0

* 📅 Release Date: _expected_ end of Februar 2023

### Mojos without a mapping are now executed by default in incremental builds

Before it was neccesary to explicitly configure a mapping or there is a connector or the plugin iself contains mappings for a mojo to participate in the incremental maven build.
Expand All @@ -23,9 +25,21 @@ The property "<maven.test.skip>true</maven.test.skip>" and the "skip" property i
account by M2E in the sense that, if enabled, M2E ignores the corresponding folder, which no longer appear in the Package Explorer as "Java" folders but as standard folders.
This allows, depending on the need (especially compilation time), to either not compile tests or not copy test resources.

In general it is not recomended to use the mentioned properties but to use `-DskipTests` instead:
In general it is not recommended to use the mentioned properties but to use `-DskipTests` instead:
https://maven.apache.org/surefire/maven-surefire-plugin/examples/skipping-tests.html


### Configuration of Maven Execution JRE

In the past the project's build JRE was also used by default to execute Maven itself.
Now the default Java version for executing Maven is determined from the configuration of the `maven-enforcer-plugin` rule [`requireJavaVersion`](https://maven.apache.org/enforcer/enforcer-rules/requireJavaVersion.html) when creating or updating the Maven configuration. This value is no longer considered for configuring the project's build JRE.
In case this plugin configuration is not found one falls back to either project's build JRE or workspace default JRE.

For each Maven build configuration you can overwrite the default execution JRE in the Maven Launch configuration's JRE tab:

![Maven Launch Configuration JRE Tab](https://user-images.githubusercontent.com/185025/208966517-7d847058-23b9-4e2e-8b1a-7a86df4836bd.png)


## 2.1.0

* 📅 Release Date: November 24th 2022
Expand Down
13 changes: 8 additions & 5 deletions org.eclipse.m2e.core.tests/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ Bundle-Version: 2.0.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-Vendor: Eclipse.org - m2e
Require-Bundle: org.eclipse.m2e.tests.common,
org.junit,
org.eclipse.core.resources,
org.eclipse.core.runtime,
org.eclipse.m2e.maven.runtime
Import-Package: javax.annotation;version="1.2.0",
org.apache.commons.io
org.eclipse.m2e.launching,
org.eclipse.jdt.launching,
org.eclipse.debug.core,
org.eclipse.jdt.core
Import-Package: org.apache.commons.io,
org.junit,
org.mockito,
org.mockito.stubbing
Eclipse-BundleShape: dir
Automatic-Module-Name: org.eclipse.m2e.core.tests
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[11.0.10,16)</version>
<version>[11.0.6,13)</version>
</requireJavaVersion>
</rules>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*******************************************************************************
* Copyright (c) 2022, 2022 Hannes Wellmann and others
* All rights reserved. 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:
* Hannes Wellmann - initial API and implementation
* Konrad Windszus - Add tests for required java runtime version implied by enforcer rule
*******************************************************************************/

package org.eclipse.m2e.internal.launch;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

import java.io.File;
import java.util.List;
import java.util.function.Supplier;

import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.jdt.internal.launching.StandardVMType;
import org.eclipse.jdt.launching.AbstractVMInstall;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMInstallType;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.m2e.actions.MavenLaunchConstants;
import org.eclipse.m2e.tests.common.AbstractMavenProjectTestCase;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

@SuppressWarnings("restriction")
public class MavenLaunchDelegateTest extends AbstractMavenProjectTestCase {

private static final String DEFAULT_VM = "defaultVM";
private static final List<String> AVAILABLE_VM_VERSIONS = List.of("17.0.4", "11.0.7", "13.0.5", "11.0.1", "1.8.0");

private static MockedStatic<JavaRuntime> javaRuntimeMock;
private static IVMInstall defaultVM;

@BeforeClass
public static void setUpJavaRuntimeMocking() {

defaultVM = Mockito.mock(IVMInstall.class);
Mockito.when(defaultVM.getId()).thenReturn(DEFAULT_VM);

IVMInstallType standardVMType = Mockito.mock(StandardVMType.class, Mockito.CALLS_REAL_METHODS);
IVMInstall[] installs = AVAILABLE_VM_VERSIONS.stream().map(version -> {
AbstractVMInstall vm = Mockito.mock(AbstractVMInstall.class, Mockito.CALLS_REAL_METHODS);
when(vm.getId()).thenReturn(version);
when(vm.getJavaVersion()).thenReturn(version);
when(vm.getVMInstallType()).thenReturn(standardVMType);
when(vm.getName()).thenReturn("JDK " + version);
return vm;
}).toArray(IVMInstall[]::new);
Mockito.doReturn(installs).when(standardVMType).getVMInstalls();

javaRuntimeMock = Mockito.mockStatic(JavaRuntime.class);
javaRuntimeMock.when(() -> JavaRuntime.getVMInstallTypes()).thenReturn(new IVMInstallType[] { standardVMType });
javaRuntimeMock.when(() -> JavaRuntime.computeVMInstall(Mockito.any())).thenReturn(defaultVM);
}

@AfterClass
public static void clearJavaRuntimeMocking() {
javaRuntimeMock.close();
defaultVM = null;
}

@Test
public void testGetBestMatchingVM_majorOnly() throws InvalidVersionSpecificationException {
assertEquals("11.0.7", MavenLaunchDelegate.getBestMatchingVM("11").getId());
}

@Test
public void testGetBestMatchingVM_rangeWithOnlyMajorLowerBound() throws InvalidVersionSpecificationException {
assertEquals("11.0.7", MavenLaunchDelegate.getBestMatchingVM("[11,)").getId());
}

@Test
public void testGetBestMatchingVM_9versionRange() throws InvalidVersionSpecificationException {
assertEquals("17.0.4", MavenLaunchDelegate.getBestMatchingVM("[11,18)").getId());
}

@Test
public void testGetBestMatchingVM_1XversionRange() throws InvalidVersionSpecificationException {
assertEquals("1.8.0", MavenLaunchDelegate.getBestMatchingVM("[1.8,9)").getId());
}

@Test
public void testRequiredJavaVersionFromEnforcerRule_Version() throws Exception {
IProject project = importProject("resources/projects/enforcerSettingsWithVersion/pom.xml");
assertRequiredJavaBuildVersion(project, "13.0.3", "13.0.5");
}

@Test
public void testRequiredJavaVersionFromEnforcerRule_VersionRange() throws Exception {
IProject project = importProject("resources/projects/enforcerSettingsWithVersionRange/pom.xml");
assertRequiredJavaBuildVersion(project, "[11.0.6,13)", "11.0.7");
}

@Test
public void testRequiredJavaVersionFromEnforcerRule_NoVersionRange() throws Exception {
IProject project = importProject("resources/projects/enforcerSettingsWithoutRequiredJavaVersion/pom.xml");
assertRequiredJavaBuildVersion(project, null, DEFAULT_VM);
}

private void assertRequiredJavaBuildVersion(IProject project, String expectedVersionRange, String expectedVMVersion)
throws Exception {

waitForJobsToComplete();

File pomFile = project.getLocation().toFile();

assertEquals(expectedVersionRange, MavenLaunchDelegate.readEnforcedJavaVersion(pomFile, monitor));

List<Supplier<String>> pomDirSuppliers = List.of(
// Case 1: project loc (via variable)
() -> "${workspace_loc:/" + project.getName() + "}",
// Case 2: project outside of workspace
() -> {
try {
project.delete(false, true, monitor);
} catch (CoreException e) {
throw new IllegalStateException(e);
}
return pomFile.toString();
});

for (Supplier<String> pomDir : pomDirSuppliers) {
String pomDirStr = pomDir.get();
ILaunchConfigurationWorkingCopy config = createMavenLaunchConfig(pomDirStr);
assertEquals(expectedVMVersion, new MavenLaunchDelegate().getVMInstall(config).getId());

ILaunchConfigurationWorkingCopy config2 = createMavenLaunchConfig(pomDirStr);
config2.setAttribute(IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH,
"org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17/");
assertEquals(DEFAULT_VM, new MavenLaunchDelegate().getVMInstall(config2).getId());
// When a JRE_CONTAINER_PATH is set, getVMInstall hands over to
// JavaRuntime.computeVMInstall(), which is mocked in this test to always return
// the defaultVM.
}
}

private static ILaunchConfigurationWorkingCopy createMavenLaunchConfig(String pomDir) throws CoreException {
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
String name = launchManager.generateLaunchConfigurationName("RequiredJavaVersionFromEnforcerRuleTest");
ILaunchConfigurationWorkingCopy config = launchManager
.getLaunchConfigurationType(MavenLaunchConstants.LAUNCH_CONFIGURATION_TYPE_ID).newInstance(null, name);
config.setAttribute(ILaunchManager.ATTR_PRIVATE, true);
config.setAttribute(MavenLaunchConstants.ATTR_POM_DIR, pomDir);
return config;
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ MavenClasspathContainerPage_title=Maven Dependencies
MavenPreferencePage_executionEnvironmentJreLink=See <a>Execution Environments</a> for the JREs used for specific execution environments.
MavenPreferencePage_workspaceDefaultJreLink=See <a>Installed JREs</a> for the default workspace JRE.
MavenPreferencePage_jreSystemLibraryVersion=JRE System Library Version
MavenPreferencePage_useExecutionEnvironment=Use execution environment based on maven-enforcer-plugin/maven-compiler-plugin configuration
MavenPreferencePage_useExecutionEnvironment=Use execution environment based on maven-compiler-plugin configuration
MavenPreferencePage_useWorkspaceDefault=Use workspace default
Loading

0 comments on commit e92b0d3

Please sign in to comment.