View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.util;
20  
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNotNull;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.fail;
26  
27  import java.io.File;
28  import java.io.FileInputStream;
29  import java.io.FileOutputStream;
30  
31  import org.apache.hadoop.conf.Configuration;
32  import org.apache.hadoop.fs.Path;
33  import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
34  import org.apache.hadoop.hbase.testclassification.SmallTests;
35  import org.apache.hadoop.io.IOUtils;
36  import org.junit.Test;
37  import org.junit.experimental.categories.Category;
38  
39  /**
40   * Test TestCoprocessorClassLoader. More tests are in TestClassLoading
41   */
42  @Category(SmallTests.class)
43  public class TestCoprocessorClassLoader {
44  
45    private static final HBaseCommonTestingUtility TEST_UTIL = new HBaseCommonTestingUtility();
46    private static final Configuration conf = TEST_UTIL.getConfiguration();
47    static {
48      TEST_UTIL.getDataTestDir(); // prepare data test dir and hbase local dir
49    }
50  
51    @Test
52    public void testCleanupOldJars() throws Exception {
53      String className = "TestCleanupOldJars";
54      String folder = TEST_UTIL.getDataTestDir().toString();
55      File jarFile = ClassLoaderTestHelper.buildJar(
56        folder, className, null, ClassLoaderTestHelper.localDirPath(conf));
57      File tmpJarFile = new File(jarFile.getParent(), "/tmp/" + className + ".test.jar");
58      if (tmpJarFile.exists()) tmpJarFile.delete();
59      assertFalse("tmp jar file should not exist", tmpJarFile.exists());
60      IOUtils.copyBytes(new FileInputStream(jarFile),
61        new FileOutputStream(tmpJarFile), conf, true);
62      assertTrue("tmp jar file should be created", tmpJarFile.exists());
63      Path path = new Path(jarFile.getAbsolutePath());
64      ClassLoader parent = TestCoprocessorClassLoader.class.getClassLoader();
65      CoprocessorClassLoader.parentDirLockSet.clear(); // So that clean up can be triggered
66      ClassLoader classLoader = CoprocessorClassLoader.getClassLoader(path, parent, "111", conf);
67      assertNotNull("Classloader should be created", classLoader);
68      assertFalse("tmp jar file should be removed", tmpJarFile.exists());
69    }
70  
71    @Test
72    public void testLibJarName() throws Exception {
73      checkingLibJarName("TestLibJarName.jar", "/lib/");
74    }
75  
76    @Test
77    public void testRelativeLibJarName() throws Exception {
78      checkingLibJarName("TestRelativeLibJarName.jar", "lib/");
79    }
80  
81    /**
82     * Test to make sure the lib jar file extracted from a coprocessor jar have
83     * the right name.  Otherwise, some existing jar could be override if there are
84     * naming conflicts.
85     */
86    private void checkingLibJarName(String jarName, String libPrefix) throws Exception {
87      File tmpFolder = new File(ClassLoaderTestHelper.localDirPath(conf), "tmp");
88      if (tmpFolder.exists()) { // Clean up the tmp folder
89        File[] files = tmpFolder.listFiles();
90        if (files != null) {
91          for (File f: files) {
92            f.delete();
93          }
94        }
95      }
96      String className = "CheckingLibJarName";
97      String folder = TEST_UTIL.getDataTestDir().toString();
98      File innerJarFile = ClassLoaderTestHelper.buildJar(
99        folder, className, null, ClassLoaderTestHelper.localDirPath(conf));
100     File targetJarFile = new File(innerJarFile.getParent(), jarName);
101     ClassLoaderTestHelper.addJarFilesToJar(targetJarFile, libPrefix, innerJarFile);
102     Path path = new Path(targetJarFile.getAbsolutePath());
103     ClassLoader parent = TestCoprocessorClassLoader.class.getClassLoader();
104     ClassLoader classLoader = CoprocessorClassLoader.getClassLoader(path, parent, "112", conf);
105     assertNotNull("Classloader should be created", classLoader);
106     String fileToLookFor = "." + className + ".jar";
107     String[] files = tmpFolder.list();
108     if (files != null) {
109       for (String f: files) {
110         if (f.endsWith(fileToLookFor) && f.contains(jarName)) {
111           // Cool, found it;
112           return;
113         }
114       }
115     }
116     fail("Could not find the expected lib jar file");
117   }
118 
119   // HBASE-14548
120   @Test
121   public void testDirectoryAndWildcard() throws Exception {
122     String testClassName = "TestClass";
123     String dataTestDir = TEST_UTIL.getDataTestDir().toString();
124     System.out.println(dataTestDir);
125     String localDirContainingJar = ClassLoaderTestHelper.localDirPath(conf);
126     ClassLoaderTestHelper.buildJar(dataTestDir, testClassName, null, localDirContainingJar);
127     ClassLoader parent = TestCoprocessorClassLoader.class.getClassLoader();
128     CoprocessorClassLoader.parentDirLockSet.clear(); // So that clean up can be triggered
129 
130     CoprocessorClassLoader coprocessorClassLoader = null;
131     Path testPath = null;
132 
133     // Directory
134     testPath = new Path(localDirContainingJar);
135     coprocessorClassLoader = CoprocessorClassLoader.getClassLoader(testPath, parent, "113_1", conf);
136     verifyCoprocessorClassLoader(coprocessorClassLoader, testClassName);
137 
138     // Wildcard - *.jar
139     testPath = new Path(localDirContainingJar, "*.jar");
140     coprocessorClassLoader = CoprocessorClassLoader.getClassLoader(testPath, parent, "113_2", conf);
141     verifyCoprocessorClassLoader(coprocessorClassLoader, testClassName);
142 
143     // Wildcard - *.j*
144     testPath = new Path(localDirContainingJar, "*.j*");
145     coprocessorClassLoader = CoprocessorClassLoader.getClassLoader(testPath, parent, "113_3", conf);
146     verifyCoprocessorClassLoader(coprocessorClassLoader, testClassName);
147   }
148 
149   /**
150    * Verify the coprocessorClassLoader is not null and the expected class can be loaded successfully
151    * @param coprocessorClassLoader the CoprocessorClassLoader to verify
152    * @param className the expected class to be loaded by the coprocessorClassLoader
153    * @throws ClassNotFoundException
154    */
155   private void verifyCoprocessorClassLoader(CoprocessorClassLoader coprocessorClassLoader, String className)
156     throws ClassNotFoundException{
157     assertNotNull("Classloader should be created and not null", coprocessorClassLoader);
158     assertEquals(className, coprocessorClassLoader.loadClass(className).getName());
159   }
160 }