Skip to content

Commit

Permalink
Add JvmVendor on DaemonContext using systemProperties to obtain its v…
Browse files Browse the repository at this point in the history
…alue from running daemon process

Signed-off-by: Madalin Valceleanu <vmadalin@google.com>
  • Loading branch information
vmadalin committed Apr 23, 2024
1 parent aa27ff3 commit 6b25458
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,13 @@ public boolean isIbmJvm() {
return false;
}

@Nullable
public String getVendor() {
for (String vendorProperty : VENDOR_PROPERTIES) {
if (System.getProperties().containsKey(vendorProperty) && !System.getProperty(vendorProperty).isEmpty()) {
return System.getProperty(vendorProperty);
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.gradle.integtests.fixtures.AvailableJavaHomes
import org.gradle.integtests.fixtures.jvm.JavaToolchainFixture
import org.gradle.internal.buildconfiguration.fixture.BuildPropertiesFixture
import org.gradle.internal.jvm.Jvm
import org.gradle.internal.os.OperatingSystem
import org.gradle.test.precondition.Requires
import org.gradle.test.preconditions.IntegTestPreconditions
import org.junit.Assume
Expand All @@ -47,15 +48,29 @@ class DaemonToolchainIntegrationTest extends AbstractIntegrationSpec implements
def "Given other daemon toolchain version When executing any task Then daemon jvm was set up with expected configuration"() {
given:
def otherJvm = AvailableJavaHomes.differentVersion
writeJvmCriteria(otherJvm)
writeJvmCriteria(otherJvm.javaVersion)
captureJavaHome()

expect:
withInstallations(otherJvm).succeeds("help")
assertDaemonUsedJvm(otherJvm)
}

def "Given daemon toolchain criteria that doesn't match installed ones When executing any task Then fails with the expected message"() {
@Requires(IntegTestPreconditions.JavaHomeWithDifferentVersionAvailable)
def "Given other daemon toolchain version and vendor When executing any task Then daemon jvm was set up with expected configuration"() {
given:
def otherJvm = AvailableJavaHomes.differentVersion
def otherMetadata = AvailableJavaHomes.getJvmInstallationMetadata(otherJvm)

writeJvmCriteria(otherJvm.javaVersion, otherMetadata.vendor.knownVendor.name())
captureJavaHome()

expect:
withInstallations(otherJvm).succeeds("help")
assertDaemonUsedJvm(otherJvm)
}

def "Given daemon toolchain criteria with version that doesn't match installed ones When executing any task Then fails with the expected message"() {
given:
// Java 10 is not available
def java10 = AvailableJavaHomes.getAvailableJdks(JavaVersion.VERSION_1_10)
Expand All @@ -65,6 +80,19 @@ class DaemonToolchainIntegrationTest extends AbstractIntegrationSpec implements

expect:
fails("help")
failure.assertHasDescription("Cannot find a Java installation on your machine")
failure.assertHasDescription("Cannot find a Java installation on your machine (${OperatingSystem.current()}) matching the Daemon JVM defined requirements: JVM version '10' vendor 'any'")
}

def "Given daemon toolchain criteria with version and vendor that doesn't match installed ones When executing any task Then fails with the expected message"() {
given:
// Java 10 is not available
def java10 = AvailableJavaHomes.getAvailableJdks(JavaVersion.VERSION_1_10)
Assume.assumeTrue(java10.isEmpty())
writeJvmCriteria(JavaVersion.VERSION_1_10, "ibm")
captureJavaHome()

expect:
fails("help")
failure.assertHasDescription("Cannot find a Java installation on your machine (${OperatingSystem.current()}) matching the Daemon JVM defined requirements: JVM version '10' vendor 'IBM'")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class DaemonToolchainInvalidCriteriaIntegrationTest extends AbstractIntegrationS
failure.assertHasDescription("Value '-1' given for daemon.jvm.toolchain.version is an invalid Java version")
}

@NotYetImplemented
def "Given unexpected toolchain vendor When execute any task Then fails with expected exception message"() {
given:
writeJvmCriteria(JavaVersion.VERSION_17, "unexpectedVendor")
Expand All @@ -62,7 +61,7 @@ class DaemonToolchainInvalidCriteriaIntegrationTest extends AbstractIntegrationS
fails 'help'

then:
failureDescriptionContains("Option daemon.jvm.toolchain.vendor doesn't accept value 'unexpectedVendor'. Possible values are " +
failureDescriptionContains("Value 'unexpectedVendor' given for daemon.jvm.toolchain.vendor is an invalid Java vendor. Possible values are " +
"[ADOPTIUM, ADOPTOPENJDK, AMAZON, APPLE, AZUL, BELLSOFT, GRAAL_VM, HEWLETT_PACKARD, IBM, JETBRAINS, MICROSOFT, ORACLE, SAP, TENCENT, UNKNOWN]")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.gradle.internal.concurrent.CompositeStoppable;
import org.gradle.internal.concurrent.Stoppable;
import org.gradle.internal.jvm.Jvm;
import org.gradle.internal.jvm.inspection.JvmVendor;
import org.gradle.internal.jvm.inspection.JvmVersionDetector;
import org.gradle.internal.logging.console.GlobalUserInputReceiver;
import org.gradle.internal.nativeintegration.services.NativeServices;
Expand Down Expand Up @@ -193,6 +194,7 @@ static DaemonContext buildDaemonContextForCurrentProcess(DaemonRequestContext re
UUID.randomUUID().toString(),
currentProcess.getJvm().getJavaHome(),
JavaVersion.current(),
JvmVendor.KnownJvmVendor.parse(Jvm.current().getVendor()),
null, 0L, 0,
// The gradle options aren't being properly checked.
requestContext.getDaemonOpts(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
import org.gradle.internal.buildconfiguration.BuildPropertiesDefaults;
import org.gradle.internal.jvm.JavaInfo;
import org.gradle.internal.jvm.JpmsConfiguration;
import org.gradle.internal.jvm.inspection.JvmVendor;
import org.gradle.internal.nativeintegration.services.NativeServices.NativeServicesMode;
import org.gradle.jvm.toolchain.JvmImplementation;
import org.gradle.jvm.toolchain.JvmVendorSpec;
import org.gradle.jvm.toolchain.internal.DefaultJvmVendorSpec;
import org.gradle.jvm.toolchain.internal.DefaultToolchainConfiguration;
import org.gradle.jvm.toolchain.internal.ToolchainConfiguration;
Expand All @@ -32,13 +33,16 @@

import javax.annotation.Nullable;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.gradle.util.internal.GUtil.toEnum;

public class DaemonParameters {
static final int DEFAULT_IDLE_TIMEOUT = 3 * 60 * 60 * 1000;
public static final int DEFAULT_PERIODIC_CHECK_INTERVAL_MILLIS = 10 * 1000;
Expand Down Expand Up @@ -131,13 +135,27 @@ public DaemonJvmCriteria getRequestedJvmCriteria() {
public void setRequestedJvmCriteria(@Nullable Map<String, String> buildProperties) {
String requestedVersion = buildProperties.get(BuildPropertiesDefaults.TOOLCHAIN_VERSION_PROPERTY);
if (requestedVersion != null) {
JavaVersion javaVersion;
try {
JavaVersion javaVersion = JavaVersion.toVersion(requestedVersion);
this.requestedJvmCriteria = new DaemonJvmCriteria(javaVersion, DefaultJvmVendorSpec.any(), JvmImplementation.VENDOR_SPECIFIC);
javaVersion = JavaVersion.toVersion(requestedVersion);
} catch (Exception e) {
// TODO: This should be pushed somewhere else so we consistently report this message in the right context.
throw new IllegalArgumentException(String.format("Value '%s' given for %s is an invalid Java version", requestedVersion, BuildPropertiesDefaults.TOOLCHAIN_VERSION_PROPERTY));
}

JvmVendorSpec javaVendor = DefaultJvmVendorSpec.any();
String requestedVendor = buildProperties.get(BuildPropertiesDefaults.TOOLCHAIN_VENDOR_PROPERTY);
try {
if (requestedVendor != null) {
JvmVendor.KnownJvmVendor knownJvmVendor = toEnum(JvmVendor.KnownJvmVendor.class, requestedVendor);
javaVendor = DefaultJvmVendorSpec.of(knownJvmVendor);
}
} catch (Exception e) {
// TODO: This should be pushed somewhere else so we consistently report this message in the right context.
throw new IllegalArgumentException(String.format("Value '%s' given for %s is an invalid Java vendor. Possible values are %s", requestedVendor, BuildPropertiesDefaults.TOOLCHAIN_VENDOR_PROPERTY, Arrays.toString(JvmVendor.KnownJvmVendor.values())));
}

this.requestedJvmCriteria = new DaemonJvmCriteria(javaVersion, javaVendor);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private boolean daemonOptsMatch(DaemonContext potentialContext) {

private boolean jvmCompatible(DaemonContext potentialContext) {
if (desiredContext.getJvmCriteria() != null) {
return desiredContext.getJvmCriteria().isCompatibleWith(potentialContext.getJavaVersion());
return desiredContext.getJvmCriteria().isCompatibleWith(potentialContext.getJavaVersion(), potentialContext.getJavaVendor());
} else {
try {
File potentialJavaHome = potentialContext.getJavaHome();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.gradle.launcher.daemon.context;

import org.gradle.api.JavaVersion;
import org.gradle.internal.jvm.inspection.JvmVendor;
import org.gradle.internal.nativeintegration.services.NativeServices.NativeServicesMode;
import org.gradle.launcher.daemon.configuration.DaemonParameters;

Expand Down Expand Up @@ -50,6 +51,8 @@ public interface DaemonContext {

JavaVersion getJavaVersion();

JvmVendor getJavaVendor();

/**
* The directory that should be used for daemon storage (not including the gradle version number).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.google.common.base.Joiner;
import org.gradle.api.JavaVersion;
import org.gradle.internal.jvm.Jvm;
import org.gradle.internal.jvm.inspection.JvmVendor;
import org.gradle.internal.nativeintegration.services.NativeServices.NativeServicesMode;
import org.gradle.internal.serialize.Decoder;
import org.gradle.internal.serialize.Encoder;
Expand Down Expand Up @@ -45,11 +46,13 @@ public class DefaultDaemonContext implements DaemonContext {
private final DaemonParameters.Priority priority;
private final NativeServicesMode nativeServicesMode;
private final JavaVersion javaVersion;
private final JvmVendor.KnownJvmVendor javaVendor;

public DefaultDaemonContext(
String uid,
File javaHome,
JavaVersion javaVersion,
JvmVendor.KnownJvmVendor javaVendor,
File daemonRegistryDir,
Long pid,
Integer idleTimeout,
Expand All @@ -68,6 +71,7 @@ public DefaultDaemonContext(
this.applyInstrumentationAgent = applyInstrumentationAgent;
this.priority = priority;
this.nativeServicesMode = nativeServicesMode;
this.javaVendor = javaVendor;
}

@Override
Expand All @@ -92,6 +96,11 @@ public JavaVersion getJavaVersion() {
return javaVersion;
}

@Override
public JvmVendor getJavaVendor() {
return javaVendor.asJvmVendor();
}

@Override
public File getDaemonRegistryDir() {
return daemonRegistryDir;
Expand Down Expand Up @@ -140,6 +149,7 @@ public DefaultDaemonContext read(Decoder decoder) throws Exception {
String pathname = decoder.readString();
File javaHome = new File(pathname);
JavaVersion javaVersion = JavaVersion.valueOf(decoder.readString());
JvmVendor.KnownJvmVendor javaVendor = JvmVendor.KnownJvmVendor.values()[decoder.readInt()];
File registryDir = new File(decoder.readString());
Long pid = decoder.readBoolean() ? decoder.readLong() : null;
Integer idle = decoder.readBoolean() ? decoder.readInt() : null;
Expand All @@ -152,14 +162,15 @@ public DefaultDaemonContext read(Decoder decoder) throws Exception {
NativeServicesMode nativeServicesMode = NativeServicesMode.values()[decoder.readSmallInt()];
DaemonParameters.Priority priority = decoder.readBoolean() ? DaemonParameters.Priority.values()[decoder.readInt()] : null;

return new DefaultDaemonContext(uid, javaHome, javaVersion, registryDir, pid, idle, daemonOpts, applyInstrumentationAgent, nativeServicesMode, priority);
return new DefaultDaemonContext(uid, javaHome, javaVersion, javaVendor, registryDir, pid, idle, daemonOpts, applyInstrumentationAgent, nativeServicesMode, priority);
}

@Override
public void write(Encoder encoder, DefaultDaemonContext context) throws Exception {
encoder.writeNullableString(context.uid);
encoder.writeString(context.javaHome.getPath());
encoder.writeString(context.javaVersion.name());
encoder.writeInt(context.javaVendor.ordinal());
encoder.writeString(context.daemonRegistryDir.getPath());
encoder.writeBoolean(context.pid != null);
if (context.pid != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.gradle.internal.event.ListenerManager;
import org.gradle.internal.invocation.BuildAction;
import org.gradle.internal.jvm.Jvm;
import org.gradle.internal.jvm.inspection.JvmVendor;
import org.gradle.internal.logging.LoggingManagerInternal;
import org.gradle.internal.nativeintegration.ProcessEnvironment;
import org.gradle.internal.nativeintegration.services.NativeServices;
Expand Down Expand Up @@ -97,6 +98,7 @@ protected DaemonContext createDaemonContext(AgentStatus agentStatus, ProcessEnvi
return new DefaultDaemonContext(configuration.getUid(),
canonicalize(Jvm.current().getJavaHome()),
JavaVersion.current(),
JvmVendor.KnownJvmVendor.parse(Jvm.current().getVendor()),
configuration.getBaseDir(),
processEnvironment.maybeGetPid(),
configuration.getIdleTimeout(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package org.gradle.launcher.daemon.toolchain;

import org.gradle.api.JavaVersion;
import org.gradle.internal.jvm.Jvm;
import org.gradle.internal.jvm.inspection.JvmVendor;
import org.gradle.jvm.toolchain.JvmImplementation;
import org.gradle.jvm.toolchain.JvmVendorSpec;

Expand All @@ -26,6 +26,10 @@ public class DaemonJvmCriteria {
private final JvmVendorSpec vendorSpec;
private final JvmImplementation jvmImplementation;

public DaemonJvmCriteria(JavaVersion javaVersion, JvmVendorSpec vendorSpec) {
this(javaVersion, vendorSpec, JvmImplementation.VENDOR_SPECIFIC);
}

public DaemonJvmCriteria(JavaVersion javaVersion, JvmVendorSpec vendorSpec, JvmImplementation jvmImplementation) {
this.javaVersion = javaVersion;
this.vendorSpec = vendorSpec;
Expand All @@ -44,18 +48,12 @@ public JvmImplementation getJvmImplementation() {
return jvmImplementation;
}

public boolean isCompatibleWith(Jvm other) {
return isCompatibleWith(other.getJavaVersion());
}

@Override
public String toString() {
// TODO: Include vendor and implementation
return String.format("JVM version '%s'", getJavaVersion());
return String.format("JVM version '%s' vendor '%s'", getJavaVersion(), getVendorSpec());
}

public boolean isCompatibleWith(JavaVersion javaVersion) {
// TODO: Implement comparisons for vendorSpec and jvmImplementation
return javaVersion == getJavaVersion(); // && vendorSpec.matches() && jvmImplementation == other.jvmImplementation;
public boolean isCompatibleWith(JavaVersion javaVersion, JvmVendor javaVendor) {
return javaVersion == getJavaVersion() && vendorSpec.matches(javaVendor.getRawVendor());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package org.gradle.launcher.daemon.client

import org.gradle.api.JavaVersion
import org.gradle.api.internal.specs.ExplainingSpec
import org.gradle.internal.jvm.Jvm
import org.gradle.internal.jvm.inspection.JvmVendor
import org.gradle.internal.logging.progress.ProgressLoggerFactory
import org.gradle.internal.remote.Address
import org.gradle.internal.remote.internal.ConnectCompletion
Expand Down Expand Up @@ -74,15 +76,15 @@ class DefaultDaemonConnectorTest extends Specification {

def startBusyDaemon() {
def daemonNum = daemonCounter++
DaemonContext context = new DefaultDaemonContext(daemonNum.toString(), javaHome, JavaVersion.current(), javaHome, daemonNum, 1000, [], false, NativeServicesMode.ENABLED, DaemonParameters.Priority.NORMAL)
DaemonContext context = new DefaultDaemonContext(daemonNum.toString(), javaHome, JavaVersion.current(), JvmVendor.KnownJvmVendor.parse(Jvm.current().vendor), javaHome, daemonNum, 1000, [], false, NativeServicesMode.ENABLED, DaemonParameters.Priority.NORMAL)
def address = createAddress(daemonNum)
registry.store(new DaemonInfo(address, context, "password".bytes, Busy))
return new DaemonStartupInfo(daemonNum.toString(), null, null);
}

def startIdleDaemon() {
def daemonNum = daemonCounter++
DaemonContext context = new DefaultDaemonContext(daemonNum.toString(), javaHome, JavaVersion.current(), javaHome, daemonNum, 1000, [], false, NativeServicesMode.ENABLED, DaemonParameters.Priority.NORMAL)
DaemonContext context = new DefaultDaemonContext(daemonNum.toString(), javaHome, JavaVersion.current(), JvmVendor.KnownJvmVendor.parse(Jvm.current().vendor), javaHome, daemonNum, 1000, [], false, NativeServicesMode.ENABLED, DaemonParameters.Priority.NORMAL)
def address = createAddress(daemonNum)
registry.store(new DaemonInfo(address, context, "password".bytes, Idle))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class DaemonCompatibilitySpecSpec extends Specification {
}

def "contexts with different jvm criteria are incompatible"() {
clientWants(new DaemonJvmCriteria(JavaVersion.VERSION_11, JvmVendorSpec.ADOPTIUM, JvmImplementation.VENDOR_SPECIFIC))
clientWants(new DaemonJvmCriteria(JavaVersion.VERSION_11, JvmVendorSpec.ADOPTIUM))

candidate.javaVersion >> JavaVersion.VERSION_15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DaemonStatusAndErrorReportingTest extends Specification {

def "PID can be null"() {
given:
def daemonContext = new DefaultDaemonContext(null, null, null, null, null, null, null, false, NativeServicesMode.ENABLED, null)
def daemonContext = new DefaultDaemonContext(null, null, null, null, null, null, null, null, false, NativeServicesMode.ENABLED, null)

when:
def pid = daemonContext.pid;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import org.gradle.cache.internal.DefaultFileLockManager
import org.gradle.cache.internal.ProcessMetaDataProvider
import org.gradle.cache.internal.locklistener.FileLockContentionHandler
import org.gradle.internal.file.Chmod
import org.gradle.internal.jvm.Jvm
import org.gradle.internal.jvm.inspection.JvmVendor
import org.gradle.internal.remote.internal.inet.SocketInetAddress
import org.gradle.internal.service.DefaultServiceRegistry
import org.gradle.launcher.daemon.configuration.DaemonParameters
Expand Down Expand Up @@ -65,6 +67,7 @@ class DaemonRegistryServicesTest extends Specification {
"$idx",
new File("$idx"),
JavaVersion.current(),
JvmVendor.KnownJvmVendor.parse(Jvm.current().getVendor()),
new File("$idx"),
idx,
5000,
Expand Down

0 comments on commit 6b25458

Please sign in to comment.