Merge pull request #28136 from jonatan-ivanov
* pr/28136: Polish "Add Java InfoContributor" Add Java InfoContributor Closes gh-28136
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import org.springframework.boot.actuate.info.BuildInfoContributor;
|
||||
import org.springframework.boot.actuate.info.EnvironmentInfoContributor;
|
||||
import org.springframework.boot.actuate.info.GitInfoContributor;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
import org.springframework.boot.actuate.info.JavaInfoContributor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
@@ -40,6 +41,7 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
||||
*
|
||||
* @author Meang Akira Tanaka
|
||||
* @author Stephane Nicoll
|
||||
* @author Jonatan Ivanov
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -77,4 +79,11 @@ public class InfoContributorAutoConfiguration {
|
||||
return new BuildInfoContributor(buildProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnEnabledInfoContributor("java")
|
||||
@Order(DEFAULT_ORDER)
|
||||
public JavaInfoContributor javaInfoContributor() {
|
||||
return new JavaInfoContributor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,17 +19,19 @@ package org.springframework.boot.actuate.autoconfigure.info;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.actuate.info.BuildInfoContributor;
|
||||
import org.springframework.boot.actuate.info.EnvironmentInfoContributor;
|
||||
import org.springframework.boot.actuate.info.GitInfoContributor;
|
||||
import org.springframework.boot.actuate.info.Info;
|
||||
import org.springframework.boot.actuate.info.InfoContributor;
|
||||
import org.springframework.boot.actuate.info.JavaInfoContributor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.info.BuildProperties;
|
||||
import org.springframework.boot.info.GitProperties;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.boot.info.JavaInfo;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -39,94 +41,117 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link InfoContributorAutoConfiguration}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Jonatan Ivanov
|
||||
*/
|
||||
class InfoContributorAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(InfoContributorAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void disableEnvContributor() {
|
||||
load("management.info.env.enabled:false");
|
||||
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
|
||||
assertThat(beans).hasSize(0);
|
||||
this.contextRunner.withPropertyValues("management.info.env.enabled=false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(EnvironmentInfoContributor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void disableJavaContributor() {
|
||||
this.contextRunner.withPropertyValues("management.info.java.enabled=false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(JavaInfoContributor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultInfoContributorsEnabled() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(EnvironmentInfoContributor.class)
|
||||
.hasSingleBean(JavaInfoContributor.class);
|
||||
assertThat(context.getBeansOfType(InfoContributor.class)).hasSize(2);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultInfoContributorsDisabled() {
|
||||
load("management.info.defaults.enabled:false");
|
||||
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
|
||||
assertThat(beans).hasSize(0);
|
||||
this.contextRunner.withPropertyValues("management.info.defaults.enabled=false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(InfoContributor.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultInfoContributorsDisabledWithCustomOne() {
|
||||
load(CustomInfoContributorConfiguration.class, "management.info.defaults.enabled:false");
|
||||
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
|
||||
assertThat(beans).hasSize(1);
|
||||
assertThat(this.context.getBean("customInfoContributor")).isSameAs(beans.values().iterator().next());
|
||||
this.contextRunner.withPropertyValues("management.info.defaults.enabled=false")
|
||||
.withUserConfiguration(CustomInfoContributorConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(InfoContributor.class);
|
||||
assertThat(context.getBean(InfoContributor.class))
|
||||
.isSameAs(context.getBean("customInfoContributor"));
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void gitPropertiesDefaultMode() {
|
||||
load(GitPropertiesConfiguration.class);
|
||||
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
|
||||
assertThat(beans).containsKeys("gitInfoContributor");
|
||||
Map<String, Object> content = invokeContributor(
|
||||
this.context.getBean("gitInfoContributor", InfoContributor.class));
|
||||
Object git = content.get("git");
|
||||
assertThat(git).isInstanceOf(Map.class);
|
||||
Map<String, Object> gitInfo = (Map<String, Object>) git;
|
||||
assertThat(gitInfo).containsOnlyKeys("branch", "commit");
|
||||
this.contextRunner.withUserConfiguration(GitPropertiesConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(GitInfoContributor.class);
|
||||
Map<String, Object> content = invokeContributor(context.getBean(GitInfoContributor.class));
|
||||
Object git = content.get("git");
|
||||
assertThat(git).isInstanceOf(Map.class);
|
||||
Map<String, Object> gitInfo = (Map<String, Object>) git;
|
||||
assertThat(gitInfo).containsOnlyKeys("branch", "commit");
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void gitPropertiesFullMode() {
|
||||
load(GitPropertiesConfiguration.class, "management.info.git.mode=full");
|
||||
Map<String, Object> content = invokeContributor(
|
||||
this.context.getBean("gitInfoContributor", InfoContributor.class));
|
||||
Object git = content.get("git");
|
||||
assertThat(git).isInstanceOf(Map.class);
|
||||
Map<String, Object> gitInfo = (Map<String, Object>) git;
|
||||
assertThat(gitInfo).containsOnlyKeys("branch", "commit", "foo");
|
||||
assertThat(gitInfo.get("foo")).isEqualTo("bar");
|
||||
this.contextRunner.withPropertyValues("management.info.git.mode=full")
|
||||
.withUserConfiguration(GitPropertiesConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(GitInfoContributor.class);
|
||||
Map<String, Object> content = invokeContributor(context.getBean(GitInfoContributor.class));
|
||||
Object git = content.get("git");
|
||||
assertThat(git).isInstanceOf(Map.class);
|
||||
Map<String, Object> gitInfo = (Map<String, Object>) git;
|
||||
assertThat(gitInfo).containsOnlyKeys("branch", "commit", "foo");
|
||||
assertThat(gitInfo.get("foo")).isEqualTo("bar");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customGitInfoContributor() {
|
||||
load(CustomGitInfoContributorConfiguration.class);
|
||||
assertThat(this.context.getBean(GitInfoContributor.class))
|
||||
.isSameAs(this.context.getBean("customGitInfoContributor"));
|
||||
this.contextRunner.withUserConfiguration(CustomGitInfoContributorConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(GitInfoContributor.class);
|
||||
assertThat(context.getBean(GitInfoContributor.class)).isSameAs(context.getBean("customGitInfoContributor"));
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void buildProperties() {
|
||||
load(BuildPropertiesConfiguration.class);
|
||||
Map<String, InfoContributor> beans = this.context.getBeansOfType(InfoContributor.class);
|
||||
assertThat(beans).containsKeys("buildInfoContributor");
|
||||
Map<String, Object> content = invokeContributor(
|
||||
this.context.getBean("buildInfoContributor", InfoContributor.class));
|
||||
Object build = content.get("build");
|
||||
assertThat(build).isInstanceOf(Map.class);
|
||||
Map<String, Object> buildInfo = (Map<String, Object>) build;
|
||||
assertThat(buildInfo).containsOnlyKeys("group", "artifact", "foo");
|
||||
assertThat(buildInfo.get("foo")).isEqualTo("bar");
|
||||
this.contextRunner.withUserConfiguration(BuildPropertiesConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(BuildInfoContributor.class);
|
||||
Map<String, Object> content = invokeContributor(context.getBean(BuildInfoContributor.class));
|
||||
Object build = content.get("build");
|
||||
assertThat(build).isInstanceOf(Map.class);
|
||||
Map<String, Object> buildInfo = (Map<String, Object>) build;
|
||||
assertThat(buildInfo).containsOnlyKeys("group", "artifact", "foo");
|
||||
assertThat(buildInfo.get("foo")).isEqualTo("bar");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customBuildInfoContributor() {
|
||||
load(CustomBuildInfoContributorConfiguration.class);
|
||||
assertThat(this.context.getBean(BuildInfoContributor.class))
|
||||
.isSameAs(this.context.getBean("customBuildInfoContributor"));
|
||||
this.contextRunner.withUserConfiguration(CustomBuildInfoContributorConfiguration.class).run((context) -> {
|
||||
assertThat(context).hasSingleBean(BuildInfoContributor.class);
|
||||
assertThat(context.getBean(BuildInfoContributor.class))
|
||||
.isSameAs(context.getBean("customBuildInfoContributor"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaInfoContributor() {
|
||||
this.contextRunner.run((context) -> {
|
||||
assertThat(context).hasSingleBean(JavaInfoContributor.class);
|
||||
Map<String, Object> content = invokeContributor(context.getBean(JavaInfoContributor.class));
|
||||
assertThat(content).containsKey("java");
|
||||
assertThat(content.get("java")).isInstanceOf(JavaInfo.class);
|
||||
});
|
||||
}
|
||||
|
||||
private Map<String, Object> invokeContributor(InfoContributor contributor) {
|
||||
@@ -135,21 +160,6 @@ class InfoContributorAutoConfigurationTests {
|
||||
return builder.build().getDetails();
|
||||
}
|
||||
|
||||
private void load(String... environment) {
|
||||
load(null, environment);
|
||||
}
|
||||
|
||||
private void load(Class<?> config, String... environment) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
if (config != null) {
|
||||
context.register(config);
|
||||
}
|
||||
context.register(InfoContributorAutoConfiguration.class);
|
||||
TestPropertyValues.of(environment).applyTo(context);
|
||||
context.refresh();
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class GitPropertiesConfiguration {
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.info;
|
||||
|
||||
import org.springframework.boot.actuate.info.Info.Builder;
|
||||
import org.springframework.boot.info.JavaInfo;
|
||||
|
||||
/**
|
||||
* An {@link InfoContributor} that exposes {@link JavaInfo}.
|
||||
*
|
||||
* @author Jonatan Ivanov
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public class JavaInfoContributor implements InfoContributor {
|
||||
|
||||
private final JavaInfo javaInfo;
|
||||
|
||||
public JavaInfoContributor() {
|
||||
this.javaInfo = new JavaInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contribute(Builder builder) {
|
||||
builder.withDetail("java", this.javaInfo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.info;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.info.JavaInfo;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JavaInfoContributor}
|
||||
*
|
||||
* @author Jonatan Ivanov
|
||||
*/
|
||||
class JavaInfoContributorTests {
|
||||
|
||||
@Test
|
||||
void javaInfoShouldBeAdded() {
|
||||
JavaInfoContributor javaInfoContributor = new JavaInfoContributor();
|
||||
Info.Builder builder = new Info.Builder();
|
||||
javaInfoContributor.contribute(builder);
|
||||
Info info = builder.build();
|
||||
assertThat(info.getDetails().get("java")).isInstanceOf(JavaInfo.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1157,6 +1157,9 @@ When appropriate, Spring auto-configures the following `InfoContributor` beans:
|
||||
|
||||
| {spring-boot-actuator-module-code}/info/BuildInfoContributor.java[`BuildInfoContributor`]
|
||||
| Exposes build information if a `META-INF/build-info.properties` file is available.
|
||||
|
||||
| {spring-boot-actuator-module-code}/info/JavaInfoContributor.java[`JavaInfoContributor`]
|
||||
| Exposes Java runtime information under the `java` key.
|
||||
|===
|
||||
|
||||
TIP: You can disable them all by setting the configprop:management.info.defaults.enabled[] property.
|
||||
@@ -1240,6 +1243,12 @@ See "<<howto#howto.build.generate-info,how to generate build information>>" for
|
||||
|
||||
|
||||
|
||||
[[actuator.endpoints.info.java-information]]
|
||||
==== Java Information
|
||||
The `info` endpoint publishes information about your Java runtime environment, see {spring-boot-module-api}/info/JavaInfo.html[`JavaInfo`] for more details.
|
||||
|
||||
|
||||
|
||||
[[actuator.endpoints.info.writing-custom-info-contributors]]
|
||||
==== Writing Custom InfoContributors
|
||||
To provide custom application information, you can register Spring beans that implement the {spring-boot-actuator-module-code}/info/InfoContributor.java[`InfoContributor`] interface.
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.info;
|
||||
|
||||
/**
|
||||
* Information about the Java environment the application is running in.
|
||||
*
|
||||
* @author Jonatan Ivanov
|
||||
* @author Stephane Nicoll
|
||||
* @since 2.6.0
|
||||
*/
|
||||
public class JavaInfo {
|
||||
|
||||
private final String vendor;
|
||||
|
||||
private final String version;
|
||||
|
||||
private final JavaRuntimeEnvironmentInfo runtime;
|
||||
|
||||
private final JavaVirtualMachineInfo jvm;
|
||||
|
||||
public JavaInfo() {
|
||||
this.vendor = System.getProperty("java.vendor");
|
||||
this.version = System.getProperty("java.version");
|
||||
this.runtime = new JavaRuntimeEnvironmentInfo();
|
||||
this.jvm = new JavaVirtualMachineInfo();
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return this.vendor;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public JavaRuntimeEnvironmentInfo getRuntime() {
|
||||
return this.runtime;
|
||||
}
|
||||
|
||||
public JavaVirtualMachineInfo getJvm() {
|
||||
return this.jvm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about the Java Runtime Environment the application is running in.
|
||||
*/
|
||||
public static class JavaRuntimeEnvironmentInfo {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String version;
|
||||
|
||||
public JavaRuntimeEnvironmentInfo() {
|
||||
this.name = System.getProperty("java.runtime.name");
|
||||
this.version = System.getProperty("java.runtime.version");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about the Java Virtual Machine) the application is running in.
|
||||
*/
|
||||
public static class JavaVirtualMachineInfo {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String vendor;
|
||||
|
||||
private final String version;
|
||||
|
||||
public JavaVirtualMachineInfo() {
|
||||
this.name = System.getProperty("java.vm.name");
|
||||
this.vendor = System.getProperty("java.vm.vendor");
|
||||
this.version = System.getProperty("java.vm.version");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getVendor() {
|
||||
return this.vendor;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.info;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JavaInfo}.
|
||||
*
|
||||
* @author Jonatan Ivanov
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class JavaInfoTests {
|
||||
|
||||
@Test
|
||||
void javaInfoIsAvailable() {
|
||||
JavaInfo javaInfo = new JavaInfo();
|
||||
assertThat(javaInfo.getVendor()).isEqualTo(System.getProperty("java.vendor"));
|
||||
assertThat(javaInfo.getVersion()).isEqualTo(System.getProperty("java.version"));
|
||||
assertThat(javaInfo.getRuntime()).satisfies((jreInfo) -> {
|
||||
assertThat(jreInfo.getName()).isEqualTo(System.getProperty("java.runtime.name"));
|
||||
assertThat(jreInfo.getVersion()).isEqualTo(System.getProperty("java.runtime.version"));
|
||||
});
|
||||
assertThat(javaInfo.getJvm()).satisfies((jvmInfo) -> {
|
||||
assertThat(jvmInfo.getName()).isEqualTo(System.getProperty("java.vm.name"));
|
||||
assertThat(jvmInfo.getVendor()).isEqualTo(System.getProperty("java.vm.vendor"));
|
||||
assertThat(jvmInfo.getVersion()).isEqualTo(System.getProperty("java.vm.version"));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user