Skip to content

Commit

Permalink
Merge pull request #37 from gastaldi/jar_entries
Browse files Browse the repository at this point in the history
Introduce JarEntries, tests and io.smallrye.common.io.jar package
  • Loading branch information
dmlloyd authored Jul 16, 2020
2 parents 829946a + d13710d commit f6e2a6c
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 2 deletions.
Empty file added io/build-release-8
Empty file.
Empty file added io/build-test-java10
Empty file.
Empty file added io/build-test-java8
Empty file.
Empty file added io/build-test-java9
Empty file.
30 changes: 30 additions & 0 deletions io/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,36 @@
<artifactId>smallrye-common-io</artifactId>
<name>SmallRye Common: IO</name>

<dependencies>
<dependency>
<groupId>org.jboss.shrinkwrap</groupId>
<artifactId>shrinkwrap-depchain</artifactId>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>coverage</id>
Expand Down
13 changes: 13 additions & 0 deletions io/src/main/java/io/smallrye/common/io/jar/JarEntries.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.smallrye.common.io.jar;

import java.util.jar.JarEntry;

public class JarEntries {
/**
* Returns the real name of this {@link JarEntry}. On Java 8, it returns the {@link JarEntry#getName()}
* On Java 10+, a getRealName() method was added
*/
public static String getRealName(JarEntry jarEntry) {
return jarEntry.getName();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package io.smallrye.common.io;
package io.smallrye.common.io.jar;

import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/**
* Java 8 variant of a JDK-specific class for working with {@code JarFile}s.
Expand Down Expand Up @@ -39,4 +41,21 @@ public static JarFile create(File file) throws IOException {
public static JarFile create(File file, boolean verify) throws IOException {
return new JarFile(file, verify);
}

/**
* Returns true if this {@link JarFile} is a multi-release jar. On Java 8 this is done by browsing the manifest.
* On Java 9+, there is a isMultiRelease method
*/
public static boolean isMultiRelease(JarFile jarFile) {
String value = null;
try {
Manifest manifest = jarFile.getManifest();
if (manifest != null) {
value = manifest.getMainAttributes().getValue("Multi-Release");
}
} catch (IOException e) {
throw new UncheckedIOException("Cannot read manifest attributes", e);
}
return Boolean.parseBoolean(value);
}
}
13 changes: 13 additions & 0 deletions io/src/main/java10/io/smallrye/common/io/jar/JarEntries.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.smallrye.common.io.jar;

import java.util.jar.JarEntry;

public class JarEntries {
/**
* Returns the real name of this {@link JarEntry}. On Java 8, it returns the {@link JarEntry#getName()}
* On Java 10+, a getRealName() method was added
*/
public static String getRealName(JarEntry jarEntry) {
return jarEntry.getRealName();
}
}
36 changes: 36 additions & 0 deletions io/src/main/java9/io/smallrye/common/io/jar/JarEntries.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.smallrye.common.io.jar;

import java.lang.reflect.Method;
import java.util.jar.JarEntry;

public class JarEntries {

private static final Method REAL_NAME_METHOD;

static {
Method method;
try {
method = Class.forName("java.util.jar.JarFile$JarFileEntry").getDeclaredMethod("realName");
method.setAccessible(true);
} catch (NoSuchMethodException | ClassNotFoundException e) {
method = null;
}
REAL_NAME_METHOD = method;
}

/**
* Returns the real name of this {@link JarEntry}. On Java 8, it returns the {@link JarEntry#getName()}
* On Java 10+, a getRealName() method was added
*/
public static String getRealName(JarEntry jarEntry) {
if (REAL_NAME_METHOD != null) {
try {
return REAL_NAME_METHOD.invoke(jarEntry).toString();
} catch (Exception e) {
// This should never happen
}
}
// As a safe net, fallback to the original value
return jarEntry.getName();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.smallrye.common.io;
package io.smallrye.common.io.jar;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -40,4 +40,13 @@ public static JarFile create(File file) throws IOException {
public static JarFile create(File file, boolean verify) throws IOException {
return new JarFile(file, verify, ZipFile.OPEN_READ, JarFile.runtimeVersion());
}

/**
* Returns true if this {@link JarFile} is a multi-release jar. On Java 8 this is done by browsing the manifest.
* On Java 9+, there is a isMultiRelease method
*/
public static boolean isMultiRelease(JarFile jarFile) {
return jarFile.isMultiRelease();
}

}
36 changes: 36 additions & 0 deletions io/src/test/java/io/smallrye/common/io/jar/JarEntriesIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.smallrye.common.io.jar;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.File;
import java.io.IOException;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnJre;
import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.JRE;

// This needs to be run as an integration-test
public class JarEntriesIT {

@Test
@DisabledOnJre(JRE.JAVA_8)
public void shouldUseMultiReleaseName() throws IOException {
File tmpFile = JarGenerator.generateMultiReleaseJar();
JarFile jarFile = JarFiles.create(tmpFile);
JarEntry jarEntry = jarFile.getJarEntry("foo.txt");
assertEquals("META-INF/versions/9/foo.txt", JarEntries.getRealName(jarEntry));
}

@Test
@EnabledOnJre(JRE.JAVA_8)
public void shouldUseName() throws IOException {
File tmpFile = JarGenerator.generateMultiReleaseJar();
JarFile jarFile = JarFiles.create(tmpFile);
JarEntry jarEntry = jarFile.getJarEntry("foo.txt");
assertEquals("foo.txt", JarEntries.getRealName(jarEntry));
}

}
28 changes: 28 additions & 0 deletions io/src/test/java/io/smallrye/common/io/jar/JarFilesTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.smallrye.common.io.jar;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;

import org.junit.jupiter.api.Test;

public class JarFilesTest {

@Test
public void shouldReadPlainJars() throws IOException {
File tmpFile = JarGenerator.generatePlainJar();
JarFile jarFile = JarFiles.create(tmpFile);
assertFalse(JarFiles.isMultiRelease(jarFile));
}

@Test
public void shouldReadMultiReleaseJars() throws IOException {
File tmpFile = JarGenerator.generateMultiReleaseJar();
JarFile jarFile = JarFiles.create(tmpFile);
assertTrue(JarFiles.isMultiRelease(jarFile));
}

}
29 changes: 29 additions & 0 deletions io/src/test/java/io/smallrye/common/io/jar/JarGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.smallrye.common.io.jar;

import java.io.File;
import java.io.IOException;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;

public class JarGenerator {
public static File generatePlainJar() throws IOException {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
.addAsResource(new StringAsset("Original"), "foo.txt");
File tmpFile = File.createTempFile("tmp", ".tmp");
jar.as(ZipExporter.class).exportTo(tmpFile, true);
return tmpFile;
}

public static File generateMultiReleaseJar() throws IOException {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
.addAsManifestResource(new StringAsset("Multi-Release: true\n"), "MANIFEST.MF")
.addAsResource(new StringAsset("Original"), "foo.txt")
.addAsManifestResource(new StringAsset("MultiRelease"), "versions/9/foo.txt");
File tmpFile = File.createTempFile("tmp", ".tmp");
jar.as(ZipExporter.class).exportTo(tmpFile, true);
return tmpFile;
}
}
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@
</dependency>

<!-- External test dependencies -->
<dependency>
<groupId>org.jboss.shrinkwrap</groupId>
<artifactId>shrinkwrap-bom</artifactId>
<version>1.2.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>


<!-- Internal module dependencies -->
Expand Down

0 comments on commit f6e2a6c

Please sign in to comment.