diff --git a/buildSrc/src/main/groovy/io.deephaven.java-open-nio.gradle b/buildSrc/src/main/groovy/io.deephaven.java-open-nio.gradle index a3c1b6f1a87..b24b0eecaa3 100644 --- a/buildSrc/src/main/groovy/io.deephaven.java-open-nio.gradle +++ b/buildSrc/src/main/groovy/io.deephaven.java-open-nio.gradle @@ -2,8 +2,8 @@ plugins { id 'java' } -def runtimeVersion = Integer.parseInt((String)project.findProperty('runtimeVersion') ?: '11') -def testRuntimeVersion = Integer.parseInt((String)project.findProperty('testRuntimeVersion') ?: '11') +def runtimeVersion = Integer.parseInt((String)project.findProperty('runtimeVersion') ?: '21') +def testRuntimeVersion = Integer.parseInt((String)project.findProperty('testRuntimeVersion') ?: '21') // Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field long java.nio.Buffer.address accessible: module java.base does not "opens java.nio" to unnamed module @5a42bbf4 // at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) diff --git a/buildSrc/src/main/groovy/io.deephaven.java-toolchain-conventions.gradle b/buildSrc/src/main/groovy/io.deephaven.java-toolchain-conventions.gradle index 2a1322225bc..0d1ccae9553 100644 --- a/buildSrc/src/main/groovy/io.deephaven.java-toolchain-conventions.gradle +++ b/buildSrc/src/main/groovy/io.deephaven.java-toolchain-conventions.gradle @@ -4,15 +4,15 @@ plugins { id 'java' } -def compilerVersion = Integer.parseInt((String)project.findProperty('compilerVersion') ?: '11') +def compilerVersion = Integer.parseInt((String)project.findProperty('compilerVersion') ?: '21') def compilerVendor = project.hasProperty('compilerVendor') ? JvmVendorSpec.matching((String)project.property('compilerVendor')): null def languageLevel = Integer.parseInt((String)project.findProperty('languageLevel') ?: '11') -def runtimeVersion = Integer.parseInt((String)project.findProperty('runtimeVersion') ?: '11') +def runtimeVersion = Integer.parseInt((String)project.findProperty('runtimeVersion') ?: '21') def runtimeVendor = project.hasProperty('runtimeVendor') ? JvmVendorSpec.matching((String)project.property('runtimeVendor')): null def testLanguageLevel = Integer.parseInt((String)project.findProperty('testLanguageLevel') ?: '11') -def testRuntimeVersion = Integer.parseInt((String)project.findProperty('testRuntimeVersion') ?: '11') +def testRuntimeVersion = Integer.parseInt((String)project.findProperty('testRuntimeVersion') ?: '21') def testRuntimeVendor = project.hasProperty('testRuntimeVendor') ? JvmVendorSpec.matching((String)project.property('testRuntimeVendor')): null if (languageLevel > compilerVersion) { @@ -79,17 +79,50 @@ tasks.withType(JavaCompile).configureEach { options.incremental = true options.compilerArgs << '-parameters' - if (name == 'compileTestJava') { + if (name == 'compileJava') { + if (compilerVersion != languageLevel) { + options.release.set languageLevel + sourceCompatibility = languageLevel + targetCompatibility = languageLevel + } + } else { + // This assumes that any JavaCompile task _not_ named 'compileJava' wants to target the testLanguageLevel. + // If this does not hold in the future, we can update this logic. if (compilerVersion != testLanguageLevel) { options.release.set testLanguageLevel + sourceCompatibility = testLanguageLevel + targetCompatibility = testLanguageLevel } - } else { + } +} + +tasks.withType(GroovyCompile).configureEach { + javaLauncher.set groovyCompilerLauncher + + options.fork = true + options.forkOptions.memoryMaximumSize = '2G' + options.encoding = 'UTF-8' + options.incremental = true + options.compilerArgs << '-parameters' + + if (name == 'compileGroovy') { if (compilerVersion != languageLevel) { options.release.set languageLevel + sourceCompatibility = languageLevel + targetCompatibility = languageLevel + } + } else { + // This assumes that any GroovyCompile task _not_ named 'compileGroovy' wants to target the testLanguageLevel. + // If this does not hold in the future, we can update this logic. + if (compilerVersion != testLanguageLevel) { + options.release.set testLanguageLevel + sourceCompatibility = testLanguageLevel + targetCompatibility = testLanguageLevel } } } + def createCompilerDirectives = tasks.register('createCompilerDirectives') { def compilerDirectivesFile = project.layout.buildDirectory.file('dh-compiler-directives.txt') def compilerDirectivesText = new JsonBuilder([{ @@ -199,10 +232,6 @@ tasks.withType(Test).configureEach { jvmArgs += compilerArgs(compilerDirectivesFile.singleFile.path) + ["-XX:VMOptionsFile=${vmOptionsFile.singleFile.path}"] + START_OPTS } -tasks.withType(GroovyCompile).configureEach { - javaLauncher.set groovyCompilerLauncher -} - JavaApplication application = extensions.findByType(JavaApplication) if (application) { application.applicationDistribution.into('etc') { diff --git a/clock-impl/build.gradle b/clock-impl/build.gradle index b7af62787ed..22cf58023a7 100644 --- a/clock-impl/build.gradle +++ b/clock-impl/build.gradle @@ -8,14 +8,33 @@ dependencies { implementation project(':clock') compileOnly libs.autoservice annotationProcessor libs.autoservice.compiler + + testImplementation libs.assertj + testImplementation platform(libs.junit.bom) + testImplementation libs.junit.jupiter + testRuntimeOnly libs.junit.platform.launcher +} + +test { + useJUnitPlatform() } +// TODO(deephaven-core#6345): Improve build process for jars that depend on JVM internals +// In the meantime, we can be relatively confident this JAR works for the multiple versions of java since we do nightly +// tests with a range of testRuntimeVersions. + tasks.withType(JavaCompile).configureEach { options.compilerArgs += ['--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED'] - // Explicitly set the source compatibility so gradle will invoke javac with `-source 11` instead of `--release` - sourceCompatibility = 11 + // Explicitly unset release so gradle will invoke javac with `-source -target ` + // instead of `--release `, which would otherwise produce + // > error: exporting a package from system module java.base is not allowed with --release + options.release.unset() } tasks.withType(Javadoc).configureEach { options.addStringOption('-add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED') } + +tasks.withType(Test).configureEach { + jvmArgs += ['--add-exports', 'java.base/jdk.internal.misc=ALL-UNNAMED'] +} diff --git a/clock-impl/src/test/java/io/deephaven/base/clock/SystemClockJdkInternalMiscVmTest.java b/clock-impl/src/test/java/io/deephaven/base/clock/SystemClockJdkInternalMiscVmTest.java new file mode 100644 index 00000000000..b12ffb32dfc --- /dev/null +++ b/clock-impl/src/test/java/io/deephaven/base/clock/SystemClockJdkInternalMiscVmTest.java @@ -0,0 +1,46 @@ +// +// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending +// +package io.deephaven.base.clock; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Instant; + +import static org.assertj.core.api.Assertions.assertThat; + +class SystemClockJdkInternalMiscVmTest { + + private SystemClockJdkInternalMiscVm SUT; + + @BeforeEach + void setUp() { + SUT = new SystemClockJdkInternalMiscVm(); + } + + @Test + void currentTimeMillis() { + assertThat(SUT.currentTimeMillis()).isPositive(); + } + + @Test + void currentTimeMicros() { + assertThat(SUT.currentTimeMicros()).isPositive(); + } + + @Test + void currentTimeNanos() { + assertThat(SUT.currentTimeNanos()).isPositive(); + } + + @Test + void instantMillis() { + assertThat(SUT.instantMillis()).isAfter(Instant.EPOCH); + } + + @Test + void instantNanos() { + assertThat(SUT.instantNanos()).isAfter(Instant.EPOCH); + } +} diff --git a/clock-impl/src/test/java/io/deephaven/base/clock/SystemClockTest.java b/clock-impl/src/test/java/io/deephaven/base/clock/SystemClockTest.java new file mode 100644 index 00000000000..be6015a3d87 --- /dev/null +++ b/clock-impl/src/test/java/io/deephaven/base/clock/SystemClockTest.java @@ -0,0 +1,23 @@ +// +// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending +// +package io.deephaven.base.clock; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.InvocationTargetException; + +import static org.assertj.core.api.Assertions.assertThat; + +class SystemClockTest { + @Test + void of() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, + InstantiationException, IllegalAccessException { + assertThat(SystemClock.of()).isExactlyInstanceOf(SystemClockJdkInternalMiscVm.class); + } + + @Test + void serviceLoader() { + assertThat(SystemClock.serviceLoader()).get().isExactlyInstanceOf(SystemClockJdkInternalMiscVm.class); + } +} diff --git a/hotspot-impl/build.gradle b/hotspot-impl/build.gradle index 65562498d26..cc187124758 100644 --- a/hotspot-impl/build.gradle +++ b/hotspot-impl/build.gradle @@ -8,14 +8,34 @@ dependencies { implementation project(':hotspot') compileOnly libs.autoservice annotationProcessor libs.autoservice.compiler + + testImplementation libs.assertj + testImplementation platform(libs.junit.bom) + testImplementation libs.junit.jupiter + testRuntimeOnly libs.junit.platform.launcher +} + +test { + useJUnitPlatform() } +// TODO(deephaven-core#6345): Improve build process for jars that depend on JVM internals +// In the meantime, we can be relatively confident this JAR works for the multiple versions of java since we do nightly +// tests with a range of testRuntimeVersions. + tasks.withType(JavaCompile).configureEach { + // TODO(deephaven-core#6345): Improve build process for jars that depend on JVM internals options.compilerArgs += ['--add-exports', 'java.management/sun.management=ALL-UNNAMED'] - // Explicitly set the source compatibility so gradle will invoke javac with `-source 11` instead of `--release` - sourceCompatibility = 11 + // Explicitly unset release so gradle will invoke javac with `-source -target ` + // instead of `--release `, which would otherwise produce + // > error: exporting a package from system module java.management is not allowed with --release + options.release.unset() } tasks.withType(Javadoc).configureEach { options.addStringOption('-add-exports', 'java.management/sun.management=ALL-UNNAMED') } + +tasks.withType(Test).configureEach { + jvmArgs += ['--add-exports', 'java.management/sun.management=ALL-UNNAMED'] +} diff --git a/hotspot-impl/src/test/java/io/deephaven/hotspot/HotSpotTest.java b/hotspot-impl/src/test/java/io/deephaven/hotspot/HotSpotTest.java new file mode 100644 index 00000000000..3fb3927c863 --- /dev/null +++ b/hotspot-impl/src/test/java/io/deephaven/hotspot/HotSpotTest.java @@ -0,0 +1,17 @@ +// +// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending +// +package io.deephaven.hotspot; + +import io.deephaven.hotspot.impl.HotSpotImpl; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class HotSpotTest { + + @Test + void loadImpl() { + assertThat(HotSpot.loadImpl()).get().isExactlyInstanceOf(HotSpotImpl.class); + } +} diff --git a/hotspot-impl/src/test/java/io/deephaven/hotspot/impl/HotSpotImplTest.java b/hotspot-impl/src/test/java/io/deephaven/hotspot/impl/HotSpotImplTest.java new file mode 100644 index 00000000000..6166b17f64a --- /dev/null +++ b/hotspot-impl/src/test/java/io/deephaven/hotspot/impl/HotSpotImplTest.java @@ -0,0 +1,34 @@ +// +// Copyright (c) 2016-2024 Deephaven Data Labs and Patent Pending +// +package io.deephaven.hotspot.impl; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class HotSpotImplTest { + + private HotSpotImpl SUT; + + @BeforeEach + void setUp() { + SUT = new HotSpotImpl(); + } + + @Test + void getSafepointCount() { + assertThat(SUT.getSafepointCount()).isNotNegative(); + } + + @Test + void getTotalSafepointTimeMillis() { + assertThat(SUT.getTotalSafepointTimeMillis()).isNotNegative(); + } + + @Test + void getSafepointSyncTimeMillis() { + assertThat(SUT.getSafepointSyncTimeMillis()).isNotNegative(); + } +}