001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.util; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertTrue; 024import static org.junit.Assert.fail; 025 026import java.io.File; 027import java.io.FileInputStream; 028import java.io.FileOutputStream; 029import org.apache.hadoop.conf.Configuration; 030import org.apache.hadoop.fs.Path; 031import org.apache.hadoop.hbase.HBaseClassTestRule; 032import org.apache.hadoop.hbase.HBaseCommonTestingUtility; 033import org.apache.hadoop.hbase.testclassification.MiscTests; 034import org.apache.hadoop.hbase.testclassification.SmallTests; 035import org.apache.hadoop.io.IOUtils; 036import org.junit.ClassRule; 037import org.junit.Test; 038import org.junit.experimental.categories.Category; 039 040/** 041 * Test TestCoprocessorClassLoader. More tests are in TestClassLoading 042 */ 043@Category({MiscTests.class, SmallTests.class}) 044public class TestCoprocessorClassLoader { 045 046 @ClassRule 047 public static final HBaseClassTestRule CLASS_RULE = 048 HBaseClassTestRule.forClass(TestCoprocessorClassLoader.class); 049 050 private static final HBaseCommonTestingUtility TEST_UTIL = new HBaseCommonTestingUtility(); 051 private static final Configuration conf = TEST_UTIL.getConfiguration(); 052 static { 053 TEST_UTIL.getDataTestDir(); // prepare data test dir and hbase local dir 054 } 055 056 @Test 057 public void testCleanupOldJars() throws Exception { 058 String className = "TestCleanupOldJars"; 059 String folder = TEST_UTIL.getDataTestDir().toString(); 060 File jarFile = ClassLoaderTestHelper.buildJar( 061 folder, className, null, ClassLoaderTestHelper.localDirPath(conf)); 062 File tmpJarFile = new File(jarFile.getParent(), "/tmp/" + className + ".test.jar"); 063 if (tmpJarFile.exists()) tmpJarFile.delete(); 064 assertFalse("tmp jar file should not exist", tmpJarFile.exists()); 065 IOUtils.copyBytes(new FileInputStream(jarFile), 066 new FileOutputStream(tmpJarFile), conf, true); 067 assertTrue("tmp jar file should be created", tmpJarFile.exists()); 068 Path path = new Path(jarFile.getAbsolutePath()); 069 ClassLoader parent = TestCoprocessorClassLoader.class.getClassLoader(); 070 CoprocessorClassLoader.parentDirLockSet.clear(); // So that clean up can be triggered 071 ClassLoader classLoader = CoprocessorClassLoader.getClassLoader(path, parent, "111", conf); 072 assertNotNull("Classloader should be created", classLoader); 073 assertFalse("tmp jar file should be removed", tmpJarFile.exists()); 074 } 075 076 @Test 077 public void testLibJarName() throws Exception { 078 checkingLibJarName("TestLibJarName.jar", "/lib/"); 079 } 080 081 @Test 082 public void testRelativeLibJarName() throws Exception { 083 checkingLibJarName("TestRelativeLibJarName.jar", "lib/"); 084 } 085 086 /** 087 * Test to make sure the lib jar file extracted from a coprocessor jar have 088 * the right name. Otherwise, some existing jar could be override if there are 089 * naming conflicts. 090 */ 091 private void checkingLibJarName(String jarName, String libPrefix) throws Exception { 092 File tmpFolder = new File(ClassLoaderTestHelper.localDirPath(conf), "tmp"); 093 if (tmpFolder.exists()) { // Clean up the tmp folder 094 File[] files = tmpFolder.listFiles(); 095 if (files != null) { 096 for (File f: files) { 097 f.delete(); 098 } 099 } 100 } 101 String className = "CheckingLibJarName"; 102 String folder = TEST_UTIL.getDataTestDir().toString(); 103 File innerJarFile = ClassLoaderTestHelper.buildJar( 104 folder, className, null, ClassLoaderTestHelper.localDirPath(conf)); 105 File targetJarFile = new File(innerJarFile.getParent(), jarName); 106 ClassLoaderTestHelper.addJarFilesToJar(targetJarFile, libPrefix, innerJarFile); 107 Path path = new Path(targetJarFile.getAbsolutePath()); 108 ClassLoader parent = TestCoprocessorClassLoader.class.getClassLoader(); 109 ClassLoader classLoader = CoprocessorClassLoader.getClassLoader(path, parent, "112", conf); 110 assertNotNull("Classloader should be created", classLoader); 111 String fileToLookFor = "." + className + ".jar"; 112 String[] files = tmpFolder.list(); 113 if (files != null) { 114 for (String f: files) { 115 if (f.endsWith(fileToLookFor) && f.contains(jarName)) { 116 // Cool, found it; 117 return; 118 } 119 } 120 } 121 fail("Could not find the expected lib jar file"); 122 } 123 124 // HBASE-14548 125 @Test 126 public void testDirectoryAndWildcard() throws Exception { 127 String testClassName = "TestClass"; 128 String dataTestDir = TEST_UTIL.getDataTestDir().toString(); 129 System.out.println(dataTestDir); 130 String localDirContainingJar = ClassLoaderTestHelper.localDirPath(conf); 131 ClassLoaderTestHelper.buildJar(dataTestDir, testClassName, null, localDirContainingJar); 132 ClassLoader parent = TestCoprocessorClassLoader.class.getClassLoader(); 133 CoprocessorClassLoader.parentDirLockSet.clear(); // So that clean up can be triggered 134 135 CoprocessorClassLoader coprocessorClassLoader = null; 136 Path testPath = null; 137 138 // Directory 139 testPath = new Path(localDirContainingJar); 140 coprocessorClassLoader = CoprocessorClassLoader.getClassLoader(testPath, parent, "113_1", conf); 141 verifyCoprocessorClassLoader(coprocessorClassLoader, testClassName); 142 143 // Wildcard - *.jar 144 testPath = new Path(localDirContainingJar, "*.jar"); 145 coprocessorClassLoader = CoprocessorClassLoader.getClassLoader(testPath, parent, "113_2", conf); 146 verifyCoprocessorClassLoader(coprocessorClassLoader, testClassName); 147 148 // Wildcard - *.j* 149 testPath = new Path(localDirContainingJar, "*.j*"); 150 coprocessorClassLoader = CoprocessorClassLoader.getClassLoader(testPath, parent, "113_3", conf); 151 verifyCoprocessorClassLoader(coprocessorClassLoader, testClassName); 152 } 153 154 /** 155 * Verify the coprocessorClassLoader is not null and the expected class can be loaded successfully 156 * @param coprocessorClassLoader the CoprocessorClassLoader to verify 157 * @param className the expected class to be loaded by the coprocessorClassLoader 158 * @throws ClassNotFoundException 159 */ 160 private void verifyCoprocessorClassLoader(CoprocessorClassLoader coprocessorClassLoader, String className) 161 throws ClassNotFoundException{ 162 assertNotNull("Classloader should be created and not null", coprocessorClassLoader); 163 assertEquals(className, coprocessorClassLoader.loadClass(className).getName()); 164 } 165}