ReflectionUtils.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:10k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.util;
  19. import java.lang.reflect.Constructor;
  20. import java.lang.reflect.Method;
  21. import java.io.*;
  22. import java.lang.management.*;
  23. import java.util.Map;
  24. import java.util.concurrent.ConcurrentHashMap;
  25. import org.apache.commons.logging.Log;
  26. import org.apache.hadoop.conf.*;
  27. import org.apache.hadoop.io.DataInputBuffer;
  28. import org.apache.hadoop.io.DataOutputBuffer;
  29. import org.apache.hadoop.io.Writable;
  30. import org.apache.hadoop.io.serializer.Deserializer;
  31. import org.apache.hadoop.io.serializer.SerializationFactory;
  32. import org.apache.hadoop.io.serializer.Serializer;
  33. /**
  34.  * General reflection utils
  35.  */
  36. public class ReflectionUtils {
  37.     
  38.   private static final Class<?>[] EMPTY_ARRAY = new Class[]{};
  39.   private static SerializationFactory serialFactory = null;
  40.   /** 
  41.    * Cache of constructors for each class. Pins the classes so they
  42.    * can't be garbage collected until ReflectionUtils can be collected.
  43.    */
  44.   private static final Map<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE = 
  45.     new ConcurrentHashMap<Class<?>, Constructor<?>>();
  46.   /**
  47.    * Check and set 'configuration' if necessary.
  48.    * 
  49.    * @param theObject object for which to set configuration
  50.    * @param conf Configuration
  51.    */
  52.   public static void setConf(Object theObject, Configuration conf) {
  53.     if (conf != null) {
  54.       if (theObject instanceof Configurable) {
  55.         ((Configurable) theObject).setConf(conf);
  56.       }
  57.       setJobConf(theObject, conf);
  58.     }
  59.   }
  60.   
  61.   /**
  62.    * This code is to support backward compatibility and break the compile  
  63.    * time dependency of core on mapred.
  64.    * This should be made deprecated along with the mapred package HADOOP-1230. 
  65.    * Should be removed when mapred package is removed.
  66.    */
  67.   private static void setJobConf(Object theObject, Configuration conf) {
  68.     //If JobConf and JobConfigurable are in classpath, AND
  69.     //theObject is of type JobConfigurable AND
  70.     //conf is of type JobConf then
  71.     //invoke configure on theObject
  72.     try {
  73.       Class<?> jobConfClass = 
  74.         conf.getClassByName("org.apache.hadoop.mapred.JobConf");
  75.       Class<?> jobConfigurableClass = 
  76.         conf.getClassByName("org.apache.hadoop.mapred.JobConfigurable");
  77.        if (jobConfClass.isAssignableFrom(conf.getClass()) &&
  78.             jobConfigurableClass.isAssignableFrom(theObject.getClass())) {
  79.         Method configureMethod = 
  80.           jobConfigurableClass.getMethod("configure", jobConfClass);
  81.         configureMethod.invoke(theObject, conf);
  82.       }
  83.     } catch (ClassNotFoundException e) {
  84.       //JobConf/JobConfigurable not in classpath. no need to configure
  85.     } catch (Exception e) {
  86.       throw new RuntimeException("Error in configuring object", e);
  87.     }
  88.   }
  89.   /** Create an object for the given class and initialize it from conf
  90.    * 
  91.    * @param theClass class of which an object is created
  92.    * @param conf Configuration
  93.    * @return a new object
  94.    */
  95.   @SuppressWarnings("unchecked")
  96.   public static <T> T newInstance(Class<T> theClass, Configuration conf) {
  97.     T result;
  98.     try {
  99.       Constructor<T> meth = (Constructor<T>) CONSTRUCTOR_CACHE.get(theClass);
  100.       if (meth == null) {
  101.         meth = theClass.getDeclaredConstructor(EMPTY_ARRAY);
  102.         meth.setAccessible(true);
  103.         CONSTRUCTOR_CACHE.put(theClass, meth);
  104.       }
  105.       result = meth.newInstance();
  106.     } catch (Exception e) {
  107.       throw new RuntimeException(e);
  108.     }
  109.     setConf(result, conf);
  110.     return result;
  111.   }
  112.   static private ThreadMXBean threadBean = 
  113.     ManagementFactory.getThreadMXBean();
  114.     
  115.   public static void setContentionTracing(boolean val) {
  116.     threadBean.setThreadContentionMonitoringEnabled(val);
  117.   }
  118.     
  119.   private static String getTaskName(long id, String name) {
  120.     if (name == null) {
  121.       return Long.toString(id);
  122.     }
  123.     return id + " (" + name + ")";
  124.   }
  125.     
  126.   /**
  127.    * Print all of the thread's information and stack traces.
  128.    * 
  129.    * @param stream the stream to
  130.    * @param title a string title for the stack trace
  131.    */
  132.   public static void printThreadInfo(PrintWriter stream,
  133.                                      String title) {
  134.     final int STACK_DEPTH = 20;
  135.     boolean contention = threadBean.isThreadContentionMonitoringEnabled();
  136.     long[] threadIds = threadBean.getAllThreadIds();
  137.     stream.println("Process Thread Dump: " + title);
  138.     stream.println(threadIds.length + " active threads");
  139.     for (long tid: threadIds) {
  140.       ThreadInfo info = threadBean.getThreadInfo(tid, STACK_DEPTH);
  141.       if (info == null) {
  142.         stream.println("  Inactive");
  143.         continue;
  144.       }
  145.       stream.println("Thread " + 
  146.                      getTaskName(info.getThreadId(),
  147.                                  info.getThreadName()) + ":");
  148.       Thread.State state = info.getThreadState();
  149.       stream.println("  State: " + state);
  150.       stream.println("  Blocked count: " + info.getBlockedCount());
  151.       stream.println("  Waited count: " + info.getWaitedCount());
  152.       if (contention) {
  153.         stream.println("  Blocked time: " + info.getBlockedTime());
  154.         stream.println("  Waited time: " + info.getWaitedTime());
  155.       }
  156.       if (state == Thread.State.WAITING) {
  157.         stream.println("  Waiting on " + info.getLockName());
  158.       } else  if (state == Thread.State.BLOCKED) {
  159.         stream.println("  Blocked on " + info.getLockName());
  160.         stream.println("  Blocked by " + 
  161.                        getTaskName(info.getLockOwnerId(),
  162.                                    info.getLockOwnerName()));
  163.       }
  164.       stream.println("  Stack:");
  165.       for (StackTraceElement frame: info.getStackTrace()) {
  166.         stream.println("    " + frame.toString());
  167.       }
  168.     }
  169.     stream.flush();
  170.   }
  171.     
  172.   private static long previousLogTime = 0;
  173.     
  174.   /**
  175.    * Log the current thread stacks at INFO level.
  176.    * @param log the logger that logs the stack trace
  177.    * @param title a descriptive title for the call stacks
  178.    * @param minInterval the minimum time from the last 
  179.    */
  180.   public static void logThreadInfo(Log log,
  181.                                    String title,
  182.                                    long minInterval) {
  183.     boolean dumpStack = false;
  184.     if (log.isInfoEnabled()) {
  185.       synchronized (ReflectionUtils.class) {
  186.         long now = System.currentTimeMillis();
  187.         if (now - previousLogTime >= minInterval * 1000) {
  188.           previousLogTime = now;
  189.           dumpStack = true;
  190.         }
  191.       }
  192.       if (dumpStack) {
  193.         ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  194.         printThreadInfo(new PrintWriter(buffer), title);
  195.         log.info(buffer.toString());
  196.       }
  197.     }
  198.   }
  199.   /**
  200.    * Return the correctly-typed {@link Class} of the given object.
  201.    *  
  202.    * @param o object whose correctly-typed <code>Class</code> is to be obtained
  203.    * @return the correctly typed <code>Class</code> of the given object.
  204.    */
  205.   @SuppressWarnings("unchecked")
  206.   public static <T> Class<T> getClass(T o) {
  207.     return (Class<T>)o.getClass();
  208.   }
  209.   
  210.   // methods to support testing
  211.   static void clearCache() {
  212.     CONSTRUCTOR_CACHE.clear();
  213.   }
  214.     
  215.   static int getCacheSize() {
  216.     return CONSTRUCTOR_CACHE.size();
  217.   }
  218.   /**
  219.    * A pair of input/output buffers that we use to clone writables.
  220.    */
  221.   private static class CopyInCopyOutBuffer {
  222.     DataOutputBuffer outBuffer = new DataOutputBuffer();
  223.     DataInputBuffer inBuffer = new DataInputBuffer();
  224.     /**
  225.      * Move the data from the output buffer to the input buffer.
  226.      */
  227.     void moveData() {
  228.       inBuffer.reset(outBuffer.getData(), outBuffer.getLength());
  229.     }
  230.   }
  231.   
  232.   /**
  233.    * Allocate a buffer for each thread that tries to clone objects.
  234.    */
  235.   private static ThreadLocal<CopyInCopyOutBuffer> cloneBuffers
  236.       = new ThreadLocal<CopyInCopyOutBuffer>() {
  237.       protected synchronized CopyInCopyOutBuffer initialValue() {
  238.         return new CopyInCopyOutBuffer();
  239.       }
  240.     };
  241.   private static SerializationFactory getFactory(Configuration conf) {
  242.     if (serialFactory == null) {
  243.       serialFactory = new SerializationFactory(conf);
  244.     }
  245.     return serialFactory;
  246.   }
  247.   
  248.   /**
  249.    * Make a copy of the writable object using serialization to a buffer
  250.    * @param dst the object to copy from
  251.    * @param src the object to copy into, which is destroyed
  252.    * @throws IOException
  253.    */
  254.   @SuppressWarnings("unchecked")
  255.   public static <T> T copy(Configuration conf, 
  256.                                 T src, T dst) throws IOException {
  257.     CopyInCopyOutBuffer buffer = cloneBuffers.get();
  258.     buffer.outBuffer.reset();
  259.     SerializationFactory factory = getFactory(conf);
  260.     Class<T> cls = (Class<T>) src.getClass();
  261.     Serializer<T> serializer = factory.getSerializer(cls);
  262.     serializer.open(buffer.outBuffer);
  263.     serializer.serialize(src);
  264.     buffer.moveData();
  265.     Deserializer<T> deserializer = factory.getDeserializer(cls);
  266.     deserializer.open(buffer.inBuffer);
  267.     dst = deserializer.deserialize(dst);
  268.     return dst;
  269.   }
  270.   @Deprecated
  271.   public static void cloneWritableInto(Writable dst, 
  272.                                        Writable src) throws IOException {
  273.     CopyInCopyOutBuffer buffer = cloneBuffers.get();
  274.     buffer.outBuffer.reset();
  275.     src.write(buffer.outBuffer);
  276.     buffer.moveData();
  277.     dst.readFields(buffer.inBuffer);
  278.   }
  279. }