HADOOP-5470. RunJar.unJar() should write the last modified time found in the jar entry to the uncompressed file. (Contributed by Andras Bakor)

This commit is contained in:
Arpit Agarwal 2016-04-27 10:06:54 -07:00
parent dd7c9f5b8f
commit 7cd0177310
2 changed files with 33 additions and 2 deletions

View File

@ -43,12 +43,16 @@ import org.apache.hadoop.classification.InterfaceStability;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Run a Hadoop job jar. */
@InterfaceAudience.Private
@InterfaceStability.Unstable
public class RunJar {
private static final Logger LOG = LoggerFactory.getLogger(RunJar.class);
/** Pattern that matches any string */
public static final Pattern MATCH_ANY = Pattern.compile(".*");
@ -93,6 +97,7 @@ public class RunJar {
throws IOException {
JarFile jar = new JarFile(jarFile);
try {
int numOfFailedLastModifiedSet = 0;
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
@ -108,11 +113,18 @@ public class RunJar {
} finally {
out.close();
}
if (!file.setLastModified(entry.getTime())) {
numOfFailedLastModifiedSet++;
}
} finally {
in.close();
}
}
}
if (numOfFailedLastModifiedSet > 0) {
LOG.warn("Could not set last modfied time for {} file(s)",
numOfFailedLastModifiedSet);
}
} finally {
jar.close();
}

View File

@ -41,6 +41,8 @@ public class TestRunJar extends TestCase {
private static final String TEST_JAR_NAME="test-runjar.jar";
private static final String TEST_JAR_2_NAME = "test-runjar2.jar";
private static final long MOCKED_NOW = 1_460_389_972_000L;
private static final long MOCKED_NOW_PLUS_TWO_SEC = MOCKED_NOW + 2_000;
@Override
@Before
@ -70,9 +72,13 @@ public class TestRunJar extends TestCase {
File jarFile = new File(TEST_ROOT_DIR, TEST_JAR_NAME);
JarOutputStream jstream =
new JarOutputStream(new FileOutputStream(jarFile));
jstream.putNextEntry(new ZipEntry("foobar.txt"));
ZipEntry zipEntry1 = new ZipEntry("foobar.txt");
zipEntry1.setTime(MOCKED_NOW);
jstream.putNextEntry(zipEntry1);
jstream.closeEntry();
jstream.putNextEntry(new ZipEntry("foobaz.txt"));
ZipEntry zipEntry2 = new ZipEntry("foobaz.txt");
zipEntry2.setTime(MOCKED_NOW_PLUS_TWO_SEC);
jstream.putNextEntry(zipEntry2);
jstream.closeEntry();
jstream.close();
}
@ -115,6 +121,19 @@ public class TestRunJar extends TestCase {
}
public void testUnJarDoesNotLooseLastModify() throws Exception {
File unjarDir = new File(TEST_ROOT_DIR, "unjar-lastmod");
assertFalse("unjar dir shouldn't exist at test start",
new File(unjarDir, "foobar.txt").exists());
// Unjar everything
RunJar.unJar(new File(TEST_ROOT_DIR, TEST_JAR_NAME),
unjarDir);
assertEquals("Last modify time was lost during unJar", MOCKED_NOW, new File(unjarDir, "foobar.txt").lastModified());
assertEquals("Last modify time was lost during unJar", MOCKED_NOW_PLUS_TWO_SEC, new File(unjarDir, "foobaz.txt").lastModified());
}
/**
* Tests the client classloader to verify the main class and its dependent
* class are loaded correctly by the application classloader, and others are