You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by li...@apache.org on 2013/01/17 20:19:21 UTC

svn commit: r1434869 - in /hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase: HConstants.java regionserver/Store.java util/DynamicClassLoader.java

Author: liyin
Date: Thu Jan 17 19:19:20 2013
New Revision: 1434869

URL: http://svn.apache.org/viewvc?rev=1434869&view=rev
Log:
[HBASE-6967][89-fb] Adding a way to dynamically add a java class into the classpath for specifying compaction hooks

Author: adela

Summary:
User can specify a jar and a class which will be loaded from
the jar; it should be specified via alter table command, example:
alter 't3', {NAME => 'f1', CONFIG => {'compaction_hook_jar' => '/home/adela/local/latest_jar/simplehook.jar', 'compaction_hook' => 'org.apache.hadoop.hbase.regionserver.compactionhook.SimpleTestCompactionHook'} }

Test Plan: tested with compaction hooks

Reviewers: liyintang, kannan

Reviewed By: liyintang

CC: hbase-eng@

Differential Revision: https://phabricator.fb.com/D680766

Task ID: 2027229

Added:
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java
Modified:
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/HConstants.java
    hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/HConstants.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/HConstants.java?rev=1434869&r1=1434868&r2=1434869&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/HConstants.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/HConstants.java Thu Jan 17 19:19:20 2013
@@ -646,6 +646,11 @@ public final class HConstants {
    */
   public static final String COMPACTION_HOOK = "compaction_hook";
 
+  /**
+   * Absolute path of the external jar which will contain the custom compaction hook
+   */
+  public static  String COMPACTION_HOOK_JAR = "compaction_hook_jar";
+
   private HConstants() {
     // Can't be instantiated with this ctor.
   }

Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java?rev=1434869&r1=1434868&r2=1434869&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/regionserver/Store.java Thu Jan 17 19:19:20 2013
@@ -48,7 +48,6 @@ import org.apache.hadoop.hbase.HColumnDe
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.KeyValue;
-import org.apache.hadoop.hbase.KeyValue.KVComparator;
 import org.apache.hadoop.hbase.RemoteExceptionHandler;
 import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.hbase.io.HeapSize;
@@ -68,14 +67,12 @@ import org.apache.hadoop.hbase.regionser
 import org.apache.hadoop.hbase.regionserver.metrics.SchemaMetrics;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.ClassSize;
+import org.apache.hadoop.hbase.util.DynamicClassLoader;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.apache.hadoop.hbase.util.InjectionEvent;
-import org.apache.hadoop.hbase.util.InjectionHandler;
 import org.apache.hadoop.util.StringUtils;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 
 /**
@@ -262,7 +259,12 @@ public class Store extends SchemaConfigu
     }
     String compactHookString = conf.get(HConstants.COMPACTION_HOOK);
     if (compactHookString != null && !compactHookString.isEmpty()) {
+      String compactionHookJar = conf.get(HConstants.COMPACTION_HOOK_JAR);
+      if (compactionHookJar == null || compactionHookJar.isEmpty()) {
+        throw new IllegalArgumentException("The path of the custom jar for the compaction hook  is not provided");
+      }
       try {
+        DynamicClassLoader.load(compactionHookJar,  compactHookString);
         this.compactHook = (CompactionHook) Class.forName(compactHookString).newInstance();
       } catch (InstantiationException e) {
         throw new IllegalArgumentException(e);

Added: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java?rev=1434869&view=auto
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java (added)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java Thu Jan 17 19:19:20 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.hadoop.hbase.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Scanner;
+
+/**
+ * Allows adding jars dynamically and loading a specified class from the jar.
+ *
+ */
+public class DynamicClassLoader {
+  /**
+   * Adds a jar to the system class loader
+   *
+   * @param s - the path of the jar file as a string
+   * @throws IOException
+   */
+  public static void addFile(String s) throws IOException {
+    File f = new File(s);
+    if (!f.exists()) {
+      throw new IOException("File does not exist, please check your path");
+    }
+    URL url = f.toURI().toURL();
+    URLClassLoader sysloader = (URLClassLoader) ClassLoader
+        .getSystemClassLoader();
+    try {
+      Method method = URLClassLoader.class.getDeclaredMethod("addURL",
+          new Class[] { URL.class });
+      method.setAccessible(true);
+      method.invoke(sysloader, new Object[] { url });
+    } catch (Throwable t) {
+      t.printStackTrace();
+      throw new IOException("Could not add URL to system classloader!");
+    }
+  }
+
+  public static void load(String jarPath, String filePath) throws IOException,
+      ClassNotFoundException {
+    addFile(jarPath);
+    ClassLoader.getSystemClassLoader().loadClass(filePath);
+  }
+
+  public static void main(String args[]) throws IOException, SecurityException,
+      ClassNotFoundException, IllegalArgumentException, InstantiationException,
+      IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+    System.out
+        .println("Insert the absolute path to the jar file that will be added to the classpath:");
+    Scanner s = new Scanner(System.in);
+    String filePath = s.nextLine().trim();
+    addFile(filePath);
+    System.out
+        .println("Insert the class name with path that should be loaded from the jar: (example org.mypackage.MyCompactionHook)");
+    String loadClazz = s.nextLine().trim();
+    ClassLoader.getSystemClassLoader().loadClass(loadClazz);
+    System.out.println("Class " + loadClazz + " was successfully loaded!");
+  }
+}