Update fat jar loader to support multi-release jar files

Closes gh-12523
This commit is contained in:
Andy Wilkinson
2018-11-07 19:08:18 +00:00
parent 60b35df215
commit 56eebc9385
7 changed files with 153 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -52,13 +52,25 @@ public abstract class TestJarCreator {
writeNestedEntry("nested.jar", unpackNested, jarOutputStream);
writeNestedEntry("another-nested.jar", unpackNested, jarOutputStream);
writeNestedEntry("space nested.jar", unpackNested, jarOutputStream);
writeNestedMultiReleaseEntry("multi-release.jar", unpackNested,
jarOutputStream);
}
}
private static void writeNestedEntry(String name, boolean unpackNested,
JarOutputStream jarOutputStream) throws Exception {
writeNestedEntry(name, unpackNested, jarOutputStream, false);
}
private static void writeNestedMultiReleaseEntry(String name, boolean unpackNested,
JarOutputStream jarOutputStream) throws Exception {
writeNestedEntry(name, unpackNested, jarOutputStream, true);
}
private static void writeNestedEntry(String name, boolean unpackNested,
JarOutputStream jarOutputStream, boolean multiRelease) throws Exception {
JarEntry nestedEntry = new JarEntry(name);
byte[] nestedJarData = getNestedJarData();
byte[] nestedJarData = getNestedJarData(multiRelease);
nestedEntry.setSize(nestedJarData.length);
nestedEntry.setCompressedSize(nestedJarData.length);
if (unpackNested) {
@@ -74,23 +86,40 @@ public abstract class TestJarCreator {
jarOutputStream.closeEntry();
}
private static byte[] getNestedJarData() throws Exception {
private static byte[] getNestedJarData(boolean multiRelease) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JarOutputStream jarOutputStream = new JarOutputStream(byteArrayOutputStream);
writeManifest(jarOutputStream, "j2");
writeEntry(jarOutputStream, "3.dat", 3);
writeEntry(jarOutputStream, "4.dat", 4);
writeEntry(jarOutputStream, "\u00E4.dat", '\u00E4');
writeManifest(jarOutputStream, "j2", multiRelease);
if (multiRelease) {
writeEntry(jarOutputStream, "multi-release.dat", 8);
writeEntry(jarOutputStream, "META-INF/versions/9/multi-release.dat", 9);
writeEntry(jarOutputStream, "META-INF/versions/10/multi-release.dat", 10);
writeEntry(jarOutputStream, "META-INF/versions/11/multi-release.dat", 11);
}
else {
writeEntry(jarOutputStream, "3.dat", 3);
writeEntry(jarOutputStream, "4.dat", 4);
writeEntry(jarOutputStream, "\u00E4.dat", '\u00E4');
}
jarOutputStream.close();
return byteArrayOutputStream.toByteArray();
}
private static void writeManifest(JarOutputStream jarOutputStream, String name)
throws Exception {
writeManifest(jarOutputStream, name, false);
}
private static void writeManifest(JarOutputStream jarOutputStream, String name,
boolean multiRelease) throws Exception {
writeDirEntry(jarOutputStream, "META-INF/");
Manifest manifest = new Manifest();
manifest.getMainAttributes().putValue("Built-By", name);
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
if (multiRelease) {
manifest.getMainAttributes().putValue("Multi-Release",
Boolean.toString(true));
}
jarOutputStream.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
manifest.write(jarOutputStream);
jarOutputStream.closeEntry();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -108,7 +108,7 @@ public class ExplodedArchiveTests {
@Test
public void getEntries() {
Map<String, Archive.Entry> entries = getEntriesMap(this.archive);
assertThat(entries.size()).isEqualTo(11);
assertThat(entries.size()).isEqualTo(12);
}
@Test

View File

@@ -78,7 +78,7 @@ public class JarFileArchiveTests {
@Test
public void getEntries() {
Map<String, Archive.Entry> entries = getEntriesMap(this.archive);
assertThat(entries.size()).isEqualTo(11);
assertThat(entries.size()).isEqualTo(12);
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2017 the original author or authors.
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,6 +82,7 @@ public class CentralDirectoryParserTests {
assertThat(headers.next().getName().toString()).isEqualTo("nested.jar");
assertThat(headers.next().getName().toString()).isEqualTo("another-nested.jar");
assertThat(headers.next().getName().toString()).isEqualTo("space nested.jar");
assertThat(headers.next().getName().toString()).isEqualTo("multi-release.jar");
assertThat(headers.hasNext()).isFalse();
}

View File

@@ -91,6 +91,7 @@ public class JarFileTests {
assertThat(entries.nextElement().getName()).isEqualTo("nested.jar");
assertThat(entries.nextElement().getName()).isEqualTo("another-nested.jar");
assertThat(entries.nextElement().getName()).isEqualTo("space nested.jar");
assertThat(entries.nextElement().getName()).isEqualTo("multi-release.jar");
assertThat(entries.hasMoreElements()).isFalse();
URL jarUrl = new URL("jar:" + this.rootJarFile.toURI() + "!/");
URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { jarUrl });
@@ -134,6 +135,7 @@ public class JarFileTests {
assertThat(entries.nextElement().getName()).isEqualTo("nested.jar");
assertThat(entries.nextElement().getName()).isEqualTo("another-nested.jar");
assertThat(entries.nextElement().getName()).isEqualTo("space nested.jar");
assertThat(entries.nextElement().getName()).isEqualTo("multi-release.jar");
assertThat(entries.hasMoreElements()).isFalse();
}
@@ -499,4 +501,26 @@ public class JarFileTests {
}
}
@Test
public void multiReleaseEntry() throws Exception {
JarFile multiRelease = this.jarFile
.getNestedJarFile(this.jarFile.getEntry("multi-release.jar"));
ZipEntry entry = multiRelease.getEntry("multi-release.dat");
assertThat(entry.getName()).isEqualTo("multi-release.dat");
InputStream inputStream = multiRelease.getInputStream(entry);
assertThat(inputStream.available()).isEqualTo(1);
assertThat(inputStream.read()).isEqualTo(getJavaVersion());
}
private int getJavaVersion() {
try {
Object runtimeVersion = Runtime.class.getMethod("version").invoke(null);
return (int) runtimeVersion.getClass().getMethod("major")
.invoke(runtimeVersion);
}
catch (Throwable ex) {
return 8;
}
}
}