HADOOP-15477. Make unjar in RunJar overrideable

Signed-off-by: Akira Ajisaka <aajisaka@apache.org>
This commit is contained in:
Johan Gustavsson 2018-05-28 17:29:59 +09:00 committed by Akira Ajisaka
parent 0cf6e87f92
commit d14e26b31f
No known key found for this signature in database
GPG Key ID: C1EDBB9CA400FD50
3 changed files with 51 additions and 7 deletions

View File

@ -76,7 +76,11 @@ public class RunJar {
*/
public static final String HADOOP_CLIENT_CLASSLOADER_SYSTEM_CLASSES =
"HADOOP_CLIENT_CLASSLOADER_SYSTEM_CLASSES";
/**
* Environment key for disabling unjar in client code.
*/
public static final String HADOOP_CLIENT_SKIP_UNJAR =
"HADOOP_CLIENT_SKIP_UNJAR";
/**
* Buffer size for copy the content of compressed file to new file.
*/
@ -93,7 +97,7 @@ public class RunJar {
* @throws IOException if an I/O error has occurred or toDir
* cannot be created and does not already exist
*/
public static void unJar(File jarFile, File toDir) throws IOException {
public void unJar(File jarFile, File toDir) throws IOException {
unJar(jarFile, toDir, MATCH_ANY);
}
@ -292,8 +296,9 @@ public void run() {
}
}, SHUTDOWN_HOOK_PRIORITY);
if (!skipUnjar()) {
unJar(file, workDir);
}
ClassLoader loader = createClassLoader(file, workDir);
@ -364,6 +369,10 @@ boolean useClientClassLoader() {
return Boolean.parseBoolean(System.getenv(HADOOP_USE_CLIENT_CLASSLOADER));
}
boolean skipUnjar() {
return Boolean.parseBoolean(System.getenv(HADOOP_CLIENT_SKIP_UNJAR));
}
String getHadoopClasspath() {
return System.getenv(HADOOP_CLASSPATH);
}

View File

@ -17,10 +17,14 @@
*/
package org.apache.hadoop.util;
import static org.apache.hadoop.util.RunJar.MATCH_ANY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
@ -99,7 +103,7 @@ public void testUnJar() throws Exception {
// Unjar everything
RunJar.unJar(new File(TEST_ROOT_DIR, TEST_JAR_NAME),
unjarDir);
unjarDir, MATCH_ANY);
assertTrue("foobar unpacked",
new File(unjarDir, TestRunJar.FOOBAR_TXT).exists());
assertTrue("foobaz unpacked",
@ -177,7 +181,7 @@ public void testUnJarDoesNotLooseLastModify() throws Exception {
// Unjar everything
RunJar.unJar(new File(TEST_ROOT_DIR, TEST_JAR_NAME),
unjarDir);
unjarDir, MATCH_ANY);
String failureMessage = "Last modify time was lost during unJar";
assertEquals(failureMessage, MOCKED_NOW, new File(unjarDir, TestRunJar.FOOBAR_TXT).lastModified());
@ -221,5 +225,34 @@ public void testClientClassLoader() throws Throwable {
// run RunJar
runJar.run(args);
// it should not throw an exception
verify(runJar, times(1)).unJar(any(File.class), any(File.class));
}
@Test
public void testClientClassLoaderSkipUnjar() throws Throwable {
RunJar runJar = spy(new RunJar());
// enable the client classloader
when(runJar.useClientClassLoader()).thenReturn(true);
// set the system classes and blacklist the test main class and the test
// third class so they can be loaded by the application classloader
String mainCls = ClassLoaderCheckMain.class.getName();
String thirdCls = ClassLoaderCheckThird.class.getName();
String systemClasses = "-" + mainCls + "," +
"-" + thirdCls + "," +
ApplicationClassLoader.SYSTEM_CLASSES_DEFAULT;
when(runJar.getSystemClasses()).thenReturn(systemClasses);
// create the test jar
File testJar = JarFinder.makeClassLoaderTestJar(this.getClass(),
TEST_ROOT_DIR, TEST_JAR_2_NAME, BUFF_SIZE, mainCls, thirdCls);
// form the args
String[] args = new String[3];
args[0] = testJar.getAbsolutePath();
args[1] = mainCls;
when(runJar.skipUnjar()).thenReturn(true);
// run RunJar
runJar.run(args);
// it should not throw an exception
verify(runJar, times(0)).unJar(any(File.class), any(File.class));
}
}

View File

@ -72,6 +72,8 @@
import org.apache.hadoop.util.StringUtils;
import org.apache.hadoop.util.Tool;
import static org.apache.hadoop.util.RunJar.MATCH_ANY;
/** All the client-side work happens here.
* (Jar packaging, MapRed job submission and monitoring)
*/
@ -1006,7 +1008,7 @@ public int submitAndMonitorJob() throws IOException {
if (jar_ != null && isLocalHadoop()) {
// getAbs became required when shell and subvm have different working dirs...
File wd = new File(".").getAbsoluteFile();
RunJar.unJar(new File(jar_), wd);
RunJar.unJar(new File(jar_), wd, MATCH_ANY);
}
// if jobConf_ changes must recreate a JobClient