Rewrite OS bean provider to avoid using reflection
Try to cast the OperatingSystemMVBean to unix instance and in success case use that instance directly instead of reflection based approach. Given that 99% of gerrit instances are used on linux based systems in production, we can avoid reflection access altogether and thus administrators wouldn't need to pass: --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED option on newer Java versions. Test Plan (on *nix system): 1. Build gerrit to produce Java lanuage level 11: $ bazel build --host_javabase=@bazel_tools//tools/jdk:remote_jdk11 \ --javabase=@bazel_tools//tools/jdk:remote_jdk11 \ --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 \ --java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 \ :release 2. Init new gerrit site 3. Run gerrit site with Java 11 4. Confirm that it can be started and works as expected without passing --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED option. Bug: Issue 7843 Change-Id: I712d3fab05b267fa4ab5b3ba17247287aebebcb6
This commit is contained in:
parent
5044de0330
commit
da8a2ad402
@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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 com.google.gerrit.metrics.proc;
|
||||
|
||||
import com.sun.management.UnixOperatingSystemMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
class OperatingSystemMXBeanFactory {
|
||||
private static final Logger log = LoggerFactory.getLogger(OperatingSystemMXBeanFactory.class);
|
||||
|
||||
static OperatingSystemMXBeanInterface create() {
|
||||
OperatingSystemMXBean sys = ManagementFactory.getOperatingSystemMXBean();
|
||||
if (sys instanceof UnixOperatingSystemMXBean) {
|
||||
return new OperatingSystemMXBeanUnixNative((UnixOperatingSystemMXBean) sys);
|
||||
}
|
||||
|
||||
for (String name :
|
||||
Arrays.asList(
|
||||
"com.sun.management.UnixOperatingSystemMXBean",
|
||||
"com.ibm.lang.management.UnixOperatingSystemMXBean")) {
|
||||
try {
|
||||
Class<?> impl = Class.forName(name);
|
||||
if (impl.isInstance(sys)) {
|
||||
return new OperatingSystemMXBeanReflectionBased(sys);
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
log.debug("No implementation for {}", name, e);
|
||||
}
|
||||
}
|
||||
log.warn("No implementation of UnixOperatingSystemMXBean found");
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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 com.google.gerrit.metrics.proc;
|
||||
|
||||
interface OperatingSystemMXBeanInterface {
|
||||
long getProcessCpuTime();
|
||||
|
||||
long getOpenFileDescriptorCount();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2017 The Android Open Source Project
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
@ -14,51 +14,24 @@
|
||||
|
||||
package com.google.gerrit.metrics.proc;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
class OperatingSystemMXBeanProvider {
|
||||
private static final Logger log = LoggerFactory.getLogger(OperatingSystemMXBeanProvider.class);
|
||||
|
||||
class OperatingSystemMXBeanReflectionBased implements OperatingSystemMXBeanInterface {
|
||||
private final OperatingSystemMXBean sys;
|
||||
private final Method getProcessCpuTime;
|
||||
private final Method getOpenFileDescriptorCount;
|
||||
|
||||
static class Factory {
|
||||
static OperatingSystemMXBeanProvider create() {
|
||||
OperatingSystemMXBean sys = ManagementFactory.getOperatingSystemMXBean();
|
||||
for (String name :
|
||||
Arrays.asList(
|
||||
"com.sun.management.UnixOperatingSystemMXBean",
|
||||
"com.ibm.lang.management.UnixOperatingSystemMXBean")) {
|
||||
try {
|
||||
Class<?> impl = Class.forName(name);
|
||||
if (impl.isInstance(sys)) {
|
||||
return new OperatingSystemMXBeanProvider(sys);
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
log.debug("No implementation for {}", name, e);
|
||||
}
|
||||
}
|
||||
log.warn("No implementation of UnixOperatingSystemMXBean found");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private OperatingSystemMXBeanProvider(OperatingSystemMXBean sys)
|
||||
OperatingSystemMXBeanReflectionBased(OperatingSystemMXBean sys)
|
||||
throws ReflectiveOperationException {
|
||||
this.sys = sys;
|
||||
getProcessCpuTime = sys.getClass().getMethod("getProcessCpuTime", new Class<?>[] {});
|
||||
getProcessCpuTime = sys.getClass().getMethod("getProcessCpuTime");
|
||||
getProcessCpuTime.setAccessible(true);
|
||||
getOpenFileDescriptorCount =
|
||||
sys.getClass().getMethod("getOpenFileDescriptorCount", new Class<?>[] {});
|
||||
getOpenFileDescriptorCount = sys.getClass().getMethod("getOpenFileDescriptorCount");
|
||||
getOpenFileDescriptorCount.setAccessible(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getProcessCpuTime() {
|
||||
try {
|
||||
return (long) getProcessCpuTime.invoke(sys, new Object[] {});
|
||||
@ -67,6 +40,7 @@ class OperatingSystemMXBeanProvider {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getOpenFileDescriptorCount() {
|
||||
try {
|
||||
return (long) getOpenFileDescriptorCount.invoke(sys, new Object[] {});
|
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2019 The Android Open Source Project
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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 com.google.gerrit.metrics.proc;
|
||||
|
||||
import com.sun.management.UnixOperatingSystemMXBean;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
class OperatingSystemMXBeanUnixNative implements OperatingSystemMXBeanInterface {
|
||||
private final UnixOperatingSystemMXBean sys;
|
||||
|
||||
OperatingSystemMXBeanUnixNative(UnixOperatingSystemMXBean sys) {
|
||||
this.sys = sys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getProcessCpuTime() {
|
||||
return sys.getProcessCpuTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getOpenFileDescriptorCount() {
|
||||
return sys.getOpenFileDescriptorCount();
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@ public class ProcMetricModule extends MetricModule {
|
||||
}
|
||||
|
||||
private void procCpuUsage(MetricMaker metrics) {
|
||||
final OperatingSystemMXBeanProvider provider = OperatingSystemMXBeanProvider.Factory.create();
|
||||
OperatingSystemMXBeanInterface provider = OperatingSystemMXBeanFactory.create();
|
||||
|
||||
if (provider == null) {
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user