Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce JarEntries, tests and io.smallrye.common.io.jar package #37

Merged
merged 8 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
Ladicek marked this conversation as resolved.
Show resolved Hide resolved
<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));
gastaldi marked this conversation as resolved.
Show resolved Hide resolved
}

@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