hive-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ser...@apache.org
Subject svn commit: r1673951 - /hive/branches/llap/common/src/java/org/apache/hive/common/util/ReflectionUtil.java
Date Wed, 15 Apr 2015 20:27:09 GMT
Author: sershe
Date: Wed Apr 15 20:27:08 2015
New Revision: 1673951

URL: http://svn.apache.org/r1673951
Log:
HIVE-10329 : Hadoop reflectionutils has issues (Sergey Shelukhin, reviewed by Vikram Dixit
K) ADDENDUM

Added:
    hive/branches/llap/common/src/java/org/apache/hive/common/util/ReflectionUtil.java

Added: hive/branches/llap/common/src/java/org/apache/hive/common/util/ReflectionUtil.java
URL: http://svn.apache.org/viewvc/hive/branches/llap/common/src/java/org/apache/hive/common/util/ReflectionUtil.java?rev=1673951&view=auto
==============================================================================
--- hive/branches/llap/common/src/java/org/apache/hive/common/util/ReflectionUtil.java (added)
+++ hive/branches/llap/common/src/java/org/apache/hive/common/util/ReflectionUtil.java Wed
Apr 15 20:27:08 2015
@@ -0,0 +1,118 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.hive.common.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
+/**
+ * Same as Hadoop ReflectionUtils, but (1) does not leak classloaders (or shouldn't anyway,
we
+ * rely on Guava cache, and could fix it otherwise); (2) does not have a hidden epic lock.
+ */
+public class ReflectionUtil {
+
+  // TODO: expireAfterAccess locks cache segments on put and expired get. It doesn't look
too bad,
+  //       but if we find some perf issues it might be a good idea to remove this - we are
probably
+  //       not caching that many constructors.
+  // Note that weakKeys causes "==" to be used for key compare; this will only work
+  // for classes in the same classloader. Should be ok in this case.
+  private static final Cache<Class<?>, Constructor<?>> CONSTRUCTOR_CACHE
=
+      CacheBuilder.newBuilder().expireAfterAccess(15, TimeUnit.MINUTES)
+                               .concurrencyLevel(64)
+                               .weakKeys().weakValues().build();
+  private static final Class<?>[] EMPTY_ARRAY = new Class[] {};
+  private static final Class<?> jobConfClass, jobConfigurableClass;
+  private static final Method configureMethod;
+
+  static {
+    Class<?> jobConfClassLocal, jobConfigurableClassLocal;
+    Method configureMethodLocal;
+    try {
+      jobConfClassLocal = Class.forName("org.apache.hadoop.mapred.JobConf");
+      jobConfigurableClassLocal = Class.forName("org.apache.hadoop.mapred.JobConfigurable");
+      configureMethodLocal = jobConfigurableClassLocal.getMethod("configure", jobConfClassLocal);
+    } catch (Throwable t) {
+      // Meh.
+      jobConfClassLocal = jobConfigurableClassLocal = null;
+      configureMethodLocal = null;
+    }
+    jobConfClass = jobConfClassLocal;
+    jobConfigurableClass = jobConfigurableClassLocal;
+    configureMethod = configureMethodLocal;
+  }
+
+  /**
+   * Create an object for the given class and initialize it from conf
+   * @param theClass class of which an object is created
+   * @param conf Configuration
+   * @return a new object
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> T newInstance(Class<T> theClass, Configuration conf) {
+    T result;
+    try {
+      Constructor<?> ctor = CONSTRUCTOR_CACHE.getIfPresent(theClass);
+      if (ctor == null) {
+        ctor = theClass.getDeclaredConstructor(EMPTY_ARRAY);
+        ctor.setAccessible(true);
+        CONSTRUCTOR_CACHE.put(theClass, ctor);
+      }
+      result = (T)ctor.newInstance();
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+    setConf(result, conf);
+    return result;
+  }
+
+
+  /**
+   * Check and set 'configuration' if necessary.
+   * 
+   * @param theObject object for which to set configuration
+   * @param conf Configuration
+   */
+  public static void setConf(Object theObject, Configuration conf) {
+    if (conf != null) {
+      if (theObject instanceof Configurable) {
+        ((Configurable) theObject).setConf(conf);
+      }
+      setJobConf(theObject, conf);
+    }
+  }
+
+  private static void setJobConf(Object theObject, Configuration conf) {
+    if (configureMethod == null) return;
+    try {
+      if (jobConfClass.isAssignableFrom(conf.getClass()) &&
+            jobConfigurableClass.isAssignableFrom(theObject.getClass())) {
+        configureMethod.invoke(theObject, conf);
+      }
+    } catch (Exception e) {
+      throw new RuntimeException("Error in configuring object", e);
+    }
+  }
+}



Mime
View raw message