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

Improve PlexusIoZipFileResourceCollection performance by using JarFile #106

Merged
merged 1 commit into from
Dec 19, 2018
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.jar.JarFile;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.codehaus.plexus.components.io.functions.SymlinkDestinationSupplier;
Expand Down Expand Up @@ -84,9 +86,10 @@ public URL getResource( String name )
};

final URL url = new URL( "jar:" + f.toURI().toURL() + "!/" );
final JarFile jarFile = new JarFile( f );
final ZipFile zipFile = new ZipFile( f, charset != null ? charset.name() : "UTF8" );
final Enumeration<ZipArchiveEntry> en = zipFile.getEntriesInPhysicalOrder();
return new ZipFileResourceIterator( en, url, zipFile, urlClassLoader );
return new ZipFileResourceIterator( en, url, jarFile, zipFile, urlClassLoader );
}

private static class ZipFileResourceIterator
Expand All @@ -96,14 +99,35 @@ private static class ZipFileResourceIterator
private class ZipFileResource
extends PlexusIoURLResource
{
private final JarFile jarFile;

private ZipFileResource( ZipArchiveEntry entry )
private ZipFileResource( JarFile jarFile, ZipArchiveEntry entry )
{
super( entry.getName(),
entry.getTime() == -1 ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : entry.getTime(),
entry.isDirectory() ? PlexusIoResource.UNKNOWN_RESOURCE_SIZE : entry.getSize(),
!entry.isDirectory(), entry.isDirectory(), true );

this.jarFile = jarFile;
}

@Override
public InputStream getContents() throws IOException {
// Uses the JarFile to get the input stream for the entry.
// The super method will do the same, why overriding it?
// But it will create new JarFile for every entry
// and that could be very expensive in some cases (when the JAR is signed).
// Enabling the URLConnection cache would solve the problem
// but the cache is global and shared during the build so
// if the AJR file changed during the causes another problem
// (see plexus-io#2).
// Using local JarFile instance solves the two issues -
// JarFile is initialized once so there is no performance penalty
// and it is local so if the file changed during the build
// would not be a problem.
// And we know the URL returned by getURL is part of the JAR
// because that is how we constructed it.
return jarFile.getInputStream( jarFile.getEntry( getName() ) );
}

@Override
Expand Down Expand Up @@ -131,9 +155,9 @@ private class ZipFileSymlinkResource

private final ZipArchiveEntry entry;

private ZipFileSymlinkResource( ZipArchiveEntry entry )
private ZipFileSymlinkResource( JarFile jarFile, ZipArchiveEntry entry )
{
super( entry );
super( jarFile, entry );

this.entry = entry;
}
Expand All @@ -157,15 +181,18 @@ public boolean isSymbolicLink()

private final URL url;

private final JarFile jarFile;

private final ZipFile zipFile;

private final URLClassLoader urlClassLoader;

public ZipFileResourceIterator( Enumeration<ZipArchiveEntry> en, URL url, ZipFile zipFile,
public ZipFileResourceIterator( Enumeration<ZipArchiveEntry> en, URL url, JarFile jarFile, ZipFile zipFile,
URLClassLoader urlClassLoader )
{
this.en = en;
this.url = url;
this.jarFile = jarFile;
this.zipFile = zipFile;
this.urlClassLoader = urlClassLoader;
}
Expand All @@ -181,8 +208,8 @@ public PlexusIoResource next()
{
final ZipArchiveEntry entry = en.nextElement();
return entry.isUnixSymlink()
? new ZipFileSymlinkResource( entry )
: new ZipFileResource( entry );
? new ZipFileSymlinkResource( jarFile, entry )
: new ZipFileResource( jarFile, entry );

}

Expand All @@ -202,7 +229,14 @@ public void close()
}
finally
{
zipFile.close();
try
{
zipFile.close();
} finally
{
jarFile.close();
}

}
}

Expand Down