HADOOP-9661. Allow metrics sources to be extended. (sandyr via tucu)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1496227 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Alejandro Abdelnur 2013-06-24 21:41:25 +00:00
parent e60fbbcc2e
commit 2c6a4e1a75
4 changed files with 89 additions and 3 deletions

View File

@ -295,6 +295,8 @@ Release 2.2.0 - UNRELEASED
IMPROVEMENTS
HADOOP-9661. Allow metrics sources to be extended. (sandyr via tucu)
OPTIMIZATIONS
BUG FIXES

View File

@ -33,6 +33,7 @@ import org.apache.hadoop.metrics2.MetricsInfo;
import org.apache.hadoop.metrics2.MetricsSource;
import org.apache.hadoop.metrics2.annotation.Metric;
import org.apache.hadoop.metrics2.annotation.Metrics;
import org.apache.hadoop.util.ReflectionUtils;
/**
* Helper class to build {@link MetricsSource} object from annotations.
@ -63,10 +64,10 @@ public class MetricsSourceBuilder {
Class<?> cls = source.getClass();
registry = initRegistry(source);
for (Field field : cls.getDeclaredFields()) {
for (Field field : ReflectionUtils.getDeclaredFieldsIncludingInherited(cls)) {
add(source, field);
}
for (Method method : cls.getDeclaredMethods()) {
for (Method method : ReflectionUtils.getDeclaredMethodsIncludingInherited(cls)) {
add(source, method);
}
}
@ -97,7 +98,7 @@ public class MetricsSourceBuilder {
Class<?> cls = source.getClass();
MetricsRegistry r = null;
// Get the registry if it already exists.
for (Field field : cls.getDeclaredFields()) {
for (Field field : ReflectionUtils.getDeclaredFieldsIncludingInherited(cls)) {
if (field.getType() != MetricsRegistry.class) continue;
try {
field.setAccessible(true);

View File

@ -25,7 +25,10 @@ import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -302,4 +305,36 @@ public class ReflectionUtils {
buffer.moveData();
dst.readFields(buffer.inBuffer);
}
/**
* Gets all the declared fields of a class including fields declared in
* superclasses.
*/
public static List<Field> getDeclaredFieldsIncludingInherited(Class<?> clazz) {
List<Field> fields = new ArrayList<Field>();
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
fields.add(field);
}
clazz = clazz.getSuperclass();
}
return fields;
}
/**
* Gets all the declared methods of a class including methods declared in
* superclasses.
*/
public static List<Method> getDeclaredMethodsIncludingInherited(Class<?> clazz) {
List<Method> methods = new ArrayList<Method>();
while (clazz != null) {
for (Method method : clazz.getDeclaredMethods()) {
methods.add(method);
}
clazz = clazz.getSuperclass();
}
return methods;
}
}

View File

@ -18,9 +18,12 @@
package org.apache.hadoop.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.List;
import static org.junit.Assert.*;
import org.junit.Before;
@ -109,6 +112,51 @@ public class TestReflectionUtils {
System.gc();
assertTrue(cacheSize()+" too big", cacheSize()<iterations);
}
@Test
public void testGetDeclaredFieldsIncludingInherited() {
Parent child = new Parent() {
private int childField;
@SuppressWarnings("unused")
public int getChildField() { return childField; }
};
List<Field> fields = ReflectionUtils.getDeclaredFieldsIncludingInherited(
child.getClass());
boolean containsParentField = false;
boolean containsChildField = false;
for (Field field : fields) {
if (field.getName().equals("parentField")) {
containsParentField = true;
} else if (field.getName().equals("childField")) {
containsChildField = true;
}
}
List<Method> methods = ReflectionUtils.getDeclaredMethodsIncludingInherited(
child.getClass());
boolean containsParentMethod = false;
boolean containsChildMethod = false;
for (Method method : methods) {
if (method.getName().equals("getParentField")) {
containsParentMethod = true;
} else if (method.getName().equals("getChildField")) {
containsChildMethod = true;
}
}
assertTrue("Missing parent field", containsParentField);
assertTrue("Missing child field", containsChildField);
assertTrue("Missing parent method", containsParentMethod);
assertTrue("Missing child method", containsChildMethod);
}
// Used for testGetDeclaredFieldsIncludingInherited
private class Parent {
private int parentField;
@SuppressWarnings("unused")
public int getParentField() { return parentField; }
}
private static class LoadedInChild {
}