Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[SHRINKWRAP-445] possibility to export uncompressed Zip archives #69

Open
wants to merge 3 commits into from

4 participants

@mmatloka

https://issues.jboss.org/browse/SHRINKWRAP-445

Usage

archive.as(ZipExporter.class).uncompressed().exportAsInputStream();
@ALRubinger

How about "setCompression(boolean)" with default to true? And a companion "isCompressionEnabled()".

It feels a bit like it would be the first setXXX type method in SW API?:P

maybe:

ZipExporter compressionEnabled(boolean)
ZipExporter compressionEnabled() // by default enabled
ZipExporter compressionDisabled()
boolean isCompressionEnabled()

So in practice it would look like this

webArchive.as(ZipExporter.class).compressionDisabled().exportTo(file1, true);

What do you think?

@lowecg

Hello,

Thank you for considering this functionality.

Is it possible to specify the default compression level using a system property/singleton?

In my use case, I do not wish shrinkwrap to compress what is produced by Arquillian. So to access the compression controls I'd have to produce a custom build of Arquillian. Or is that beyond the scope of this modification?

Regards,

Chris.

@mmatloka

Hello Chris,

Probably it would be better to create next simply a feature request for Arquillian to allow defining compression in arquillian.xml . But after this pull request will be closed and the appropriate shrinkwrap version will be released.

@ALRubinger
Owner

Michal: Yes, your last proposal looks like the winner. "Make it so"." :)

@ALRubinger
Owner

Chris: In general we avoid the use of singletons and system properties as they made for JVM-wide settings, which are too coarsely-scoped (also they bypass the API entirely and aren't very intuitive). However, if you'd like to open a feature request for us to provide some mechanism to set the compression level rather than some on/off boolean, please feel free to open an JIRA and make your case.

@ALRubinger
Owner

I've put this into upstream/SHRINKWRAP-445.

Now failing on *nix system locally:

testExportUncompressedImportExport(org.jboss.shrinkwrap.impl.base.exporter.ZipExporterTestCase) Time elapsed: 0.038 sec <<< ERROR!
java.lang.InternalError: jzentry == 0,
jzfile = 1103971568,
total = 3,
name = target/testExportImportExport1.war,
i = 2,
message = invalid LOC header (bad signature)
at java.util.zip.ZipFile$3.nextElement(ZipFile.java:429)
at java.util.zip.ZipFile$3.nextElement(ZipFile.java:415)
at org.jboss.shrinkwrap.impl.base.importer.zip.ZipImporterImpl.importFrom(ZipImporterImpl.java:165)
at org.jboss.shrinkwrap.api.ArchiveFactory.createFromZipFile(ArchiveFactory.java:199)
at org.jboss.shrinkwrap.api.ShrinkWrap.createFromZipFile(ShrinkWrap.java:185)
at org.jboss.shrinkwrap.impl.base.exporter.ZipExporterTestCase.testExportUncompressedImportExport(ZipExporterTestCase.java:242)

@ALRubinger
Owner

Ping on this issue.

@mmatloka

Rechecked - on windows still works. On ubuntu also it works!. Both with sun/oracle jdk 5 and 7 installed.

@ALRubinger
Owner

Hmm, fails with above error on:

mvn -version
Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; 2013-02-19 08:51:28-0500)
Maven home: /home/alr/opt/apache/maven/apache-maven-3.0.5
Java version: 1.7.0_25, vendor: Oracle Corporation
Java home: /home/alr/opt/oracle/java/jdk1.7.0_25/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.8.0-19-generic", arch: "amd64", family: "unix"

@mmatloka

Maybe @kpiwko you could check this to verify as a third person?:)

@ALRubinger
Owner

All it takes is a failure on one machine to be a failure. :)

I'll set up a CI job for this to see if we can get an authoritative example to share.

@mmatloka

"All it takes is a failure on one machine to be a failure. :)" nah, its a can't reproduce type issue -> ignore ;))

@ALRubinger
Owner

Passes CI on CloudBees Hudson: https://shrinkwrap.ci.cloudbees.com/view/ShrinkWrap/job/ShrinkWrap_upstream-SHRINKWRAP-445/1/

Still failing locally for me when using various JDKs in the runtime (as set by JAVA5_HOME env var) - 5, 7, and 8.

@ALRubinger
Owner

The failing build I have locally and the passing one on Jenkins CI both using jdk1.5.0_22

@ALRubinger
Owner

File in question from failing system:

$ file impl-base/target/testExportImportExport1.war
impl-base/target/testExportImportExport1.war: Zip archive data, at least v2.0 to extract

@ALRubinger
Owner

"unzip" command works on failing system:

$ ls -laR
.:
total 12
drwxr-xr-x 3 alr alr 4096 Aug 19 14:53 .
drwxr-xr-x 14 alr alr 4096 Aug 19 14:53 ..
drwxr-xr-x 2 alr alr 4096 Aug 19 14:53 lib

./lib:
total 708
drwxr-xr-x 2 alr alr 4096 Aug 19 14:53 .
drwxr-xr-x 3 alr alr 4096 Aug 19 14:53 ..
-rw-r--r-- 1 alr alr 706710 Aug 19 14:51 hsqldb.jar

@ALRubinger
Owner

Works here in IntelliJ runner.

@ALRubinger
Owner

More odd: from my command-line, passes when I just run impl-base. Fails when run as part of the aggregator parent POM.

@kpiwko
Owner

@mmatloka Fails here, it seems the be the same problem as mentioned above.

java.lang.InternalError: jzentry == 0,
 jzfile = 1098732368,
 total = 3,
 name = target/testExportImportExport1.war,
 i = 2,
 message = invalid LOC header (bad signature)
    at java.util.zip.ZipFile$3.nextElement(ZipFile.java:429)
    at java.util.zip.ZipFile$3.nextElement(ZipFile.java:415)
    at org.jboss.shrinkwrap.impl.base.importer.zip.ZipImporterImpl.importFrom(ZipImporterImpl.java:165)
    at org.jboss.shrinkwrap.api.ArchiveFactory.createFromZipFile(ArchiveFactory.java:199)
    at org.jboss.shrinkwrap.api.ShrinkWrap.createFromZipFile(ShrinkWrap.java:185)
    at org.jboss.shrinkwrap.impl.base.exporter.ZipExporterTestCase.testExportUncompressedImportExport(ZipExporterTestCase.java:242)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:81)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
@mmatloka

@ALRubinger @kpiwko do you have the same linux distribution?

@ALRubinger
Owner
@kpiwko
Owner

RHEL 6.4 64bit, Oracle JDK 1.7.0_25

@ALRubinger
Owner
@mmatloka

and how was it @ALRubinger ?

@ALRubinger
Owner
@mmatloka

what about OpenJDK e.g. ?

@mmatloka

We have still this to solve ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
24 api/src/main/java/org/jboss/shrinkwrap/api/exporter/ZipExporter.java
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
@@ -25,8 +25,30 @@
* @author <a href="mailto:baileyje@gmail.com">John Bailey</a>
* @author <a href="mailto:aslak@conduct.no">Aslak Knutsen</a>
* @author <a href="mailto:andrew.rubinger@jboss.org">ALR</a>
+ * @author <a href="mailto:mmatloka@gmail.com">Michal Matloka</a>
* @version $Revision: $
*/
public interface ZipExporter extends StreamExporter {
+ /**
+ * @param enabled
+ * enable compression of content in ZIP format. True by default.
+ * @return exporter with set given compression setting.
+ */
+ ZipExporter compressionEnabled(boolean enabled);
+
+ /**
+ * @return exporter of compressed content in ZIP format.
+ */
+ ZipExporter compressionEnabled();
+
+ /**
+ * @return exporter of uncompressed content in ZIP format.
+ */
+ ZipExporter compressionDisabled();
+
+ /**
+ * @return true if compression is enabled.
+ */
+ boolean isCompressionEnabled();
}
View
4 impl-base/pom.xml
@@ -63,6 +63,10 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ </dependency>
</dependencies>
<!-- Build Configuration -->
View
19 impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/zip/ZipExporterDelegate.java
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source
- * Copyright 2012, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
@@ -16,15 +16,14 @@
*/
package org.jboss.shrinkwrap.impl.base.exporter.zip;
+import java.io.InputStream;
+import java.util.zip.ZipOutputStream;
+
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate;
-import java.util.zip.ZipOutputStream;
-
-import java.io.InputStream;
-
/**
* Implementation of a ZIP exporter. Cannot handle archives with no content (as there'd be no
* {@link java.util.zip.ZipEntry} s to write to the {@link ZipOutputStream}
@@ -33,7 +32,13 @@
*/
class ZipExporterDelegate extends AbstractExporterDelegate<InputStream> {
+ private final boolean compressed;
+
protected ZipExporterDelegate(final Archive<?> archive) {
+ this(archive, true);
+ }
+
+ protected ZipExporterDelegate(final Archive<?> archive, boolean compressed) {
super(archive);
// Precondition check
@@ -42,6 +47,8 @@ protected ZipExporterDelegate(final Archive<?> archive) {
"[SHRINKWRAP-93] Cannot use this JDK-based implementation to export as ZIP an archive with no content: "
+ archive.toString());
}
+
+ this.compressed = compressed;
}
@Override
@@ -51,6 +58,6 @@ protected void processNode(final ArchivePath path, final Node node) {
@Override
protected InputStream getResult() {
- return new ZipOnDemandInputStream(getArchive());
+ return new ZipOnDemandInputStream(getArchive(), compressed);
}
}
View
29 impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/zip/ZipExporterImpl.java
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
@@ -19,6 +19,7 @@
import java.io.InputStream;
import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.exporter.StreamExporter;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.impl.base.exporter.AbstractExporterDelegate;
import org.jboss.shrinkwrap.impl.base.exporter.AbstractStreamExporterImpl;
@@ -33,6 +34,8 @@
*/
public class ZipExporterImpl extends AbstractStreamExporterImpl implements ZipExporter {
+ private boolean compressed = true;
+
public ZipExporterImpl(final Archive<?> archive) {
super(archive);
}
@@ -45,9 +48,31 @@ public ZipExporterImpl(final Archive<?> archive) {
@Override
public InputStream exportAsInputStream() {
// Create export delegate
- final AbstractExporterDelegate<InputStream> exportDelegate = new ZipExporterDelegate(this.getArchive());
+ final AbstractExporterDelegate<InputStream> exportDelegate = new ZipExporterDelegate(this.getArchive(),
+ compressed);
// Export and get result
return exportDelegate.export();
}
+
+ @Override
+ public ZipExporter compressionEnabled(final boolean enabled) {
+ this.compressed = enabled;
+ return this;
+ }
+
+ @Override
+ public ZipExporter compressionEnabled() {
+ return this.compressionEnabled(true);
+ }
+
+ @Override
+ public ZipExporter compressionDisabled() {
+ return this.compressionEnabled(false);
+ }
+
+ @Override
+ public boolean isCompressionEnabled() {
+ return this.compressed;
+ }
}
View
17 ...ase/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/zip/ZipOnDemandInputStream.java
@@ -1,6 +1,6 @@
/*
* JBoss, Home of Professional Open Source
- * Copyright 2012, Red Hat Middleware LLC, and individual contributors
+ * Copyright 2013, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
@@ -31,18 +31,31 @@
*/
class ZipOnDemandInputStream extends AbstractOnDemandInputStream<ZipOutputStream> {
+ private final boolean compressed;
+
/**
* Creates stream directly from archive.
*
* @param archive
*/
ZipOnDemandInputStream(final Archive<?> archive) {
+ this(archive, true);
+ }
+
+ ZipOnDemandInputStream(final Archive<?> archive, boolean compressed) {
super(archive);
+ this.compressed = compressed;
}
@Override
protected ZipOutputStream createOutputStream(final OutputStream outputStream) {
- return new ZipOutputStream(outputStream);
+ final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
+
+ if (!compressed) {
+ zipOutputStream.setLevel(ZipOutputStream.STORED);
+ }
+
+ return zipOutputStream;
}
@Override
View
118 impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterTestCase.java
@@ -16,23 +16,27 @@
*/
package org.jboss.shrinkwrap.impl.base.exporter;
+import static org.mockito.Mockito.mock;
+
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
+import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.Asset;
import org.jboss.shrinkwrap.api.asset.FileAsset;
-import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.exporter.StreamExporter;
import org.jboss.shrinkwrap.api.exporter.ZipExporter;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.impl.base.exporter.zip.ZipExporterImpl;
import org.jboss.shrinkwrap.impl.base.io.IOUtil;
import org.jboss.shrinkwrap.impl.base.path.PathUtil;
import org.junit.Assert;
@@ -193,6 +197,118 @@ public void testExportImportExport() {
Assert.assertEquals(file1.length(), file2.length());
}
+ /**
+ * Export uncompressed zip
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testUncompressedExport() throws Exception {
+ // Get an archive instance
+ final Archive<?> archive = createArchiveWithAssets();
+
+ // Export as InputStream
+ final InputStream exportStream = archive.as(ZipExporter.class).compressionDisabled().exportAsInputStream();
+
+ // Validate
+ final File tempDirectory = createTempDirectory("testUncompressedExport");
+ final File serialized = new File(tempDirectory, archive.getName());
+ final FileOutputStream out = new FileOutputStream(serialized);
+ IOUtil.copyWithClose(exportStream, out);
+ ensureInExpectedForm(serialized);
+ }
+
+ /**
+ * Export uncompressed -> Import -> Export compressed
+ */
+ @Test
+ public void testExportUncompressedImportExport() {
+ // Preconditions
+ final long uncompressedArchiveSize = 707212L;
+ final long compressedArchiveSize = 668292L;
+
+ final File target = new File("target");
+ final File testClasses = new File(target, "test-classes");
+ final File hsqldbJar = new File(testClasses, "hsqldb.jar");
+ Assert.assertTrue("test JAR must exist to run this test", hsqldbJar.exists() && !hsqldbJar.isDirectory());
+
+ final File file1 = new File(target, "testExportImportExport1.war");
+ final File file2 = new File(target, "testExportImportExport2.war");
+ final WebArchive webArchive = ShrinkWrap.create(WebArchive.class).add(new FileAsset(hsqldbJar),
+ "/WEB-INF/lib/hsqldb.jar");
+
+ // when
+ webArchive.as(ZipExporter.class).compressionDisabled().exportTo(file1, true);
+ final WebArchive webArchive2 = ShrinkWrap.createFromZipFile(WebArchive.class, file1);
+ webArchive2.as(ZipExporter.class).exportTo(file2, true);
+
+ // then check sizes
+ Assert.assertEquals(uncompressedArchiveSize, file1.length());
+ Assert.assertEquals(compressedArchiveSize, file2.length());
+ }
+
+ /**
+ * Method level test for compression enabling method
+ */
+ @Test
+ public void testCompressionEnabledByArgument() {
+ // given
+ final Archive<?> archive = mock(Archive.class);
+ final boolean compression = true;
+
+ // when
+ final ZipExporter zipExporter = new ZipExporterImpl(archive).compressionEnabled(compression);
+
+ // then
+ Assert.assertEquals(compression, zipExporter.isCompressionEnabled());
+ }
+
+ /**
+ * Method level test for compression enabling method
+ */
+ @Test
+ public void testCompressionEnabled() {
+ // given
+ final Archive<?> archive = mock(Archive.class);
+
+ // when
+ final ZipExporter zipExporter = new ZipExporterImpl(archive).compressionEnabled();
+
+ // then
+ Assert.assertEquals(true, zipExporter.isCompressionEnabled());
+ }
+
+ /**
+ * Method level test for compression enabling method
+ */
+ @Test
+ public void testCompressionDisabled() {
+ // given
+ final Archive<?> archive = mock(Archive.class);
+
+ // when
+ final ZipExporter zipExporter = new ZipExporterImpl(archive).compressionDisabled();
+
+ // then
+ Assert.assertEquals(false, zipExporter.isCompressionEnabled());
+ }
+
+ /**
+ * Method level test for compression enabling method
+ */
+ @Test
+ public void testCompressionDisabledByArgument() {
+ // given
+ final Archive<?> archive = mock(Archive.class);
+ final boolean compression = false;
+
+ // when
+ final ZipExporter zipExporter = new ZipExporterImpl(archive).compressionEnabled(compression);
+
+ // then
+ Assert.assertEquals(compression, zipExporter.isCompressionEnabled());
+ }
+
// -------------------------------------------------------------------------------------||
// Internal Helper Methods ------------------------------------------------------------||
// -------------------------------------------------------------------------------------||
View
7 pom.xml
@@ -28,6 +28,7 @@
<!-- Versioning -->
<version.junit_junit>4.8.2</version.junit_junit>
+ <version.mockito>1.9.5</version.mockito>
<version.org.apache.maven.plugins_maven-site-plugin>3.0-beta-3</version.org.apache.maven.plugins_maven-site-plugin>
</properties>
@@ -241,6 +242,12 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>${version.mockito}</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
Something went wrong with that request. Please try again.