Skip to content

Instantly share code, notes, and snippets.

@ecki
Created February 4, 2014 02:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ecki/8797308 to your computer and use it in GitHub Desktop.
Save ecki/8797308 to your computer and use it in GitHub Desktop.
VFS ClassLoader JAR verification
Checking with URL class loader D:\ws\no-manifest.jar exists=true
UCL class=class code.ClassToLoad signers=null domain=ProtectionDomain (file:/D:/ws/no-manifest.jar <no signer certificates>)
java.net.URLClassLoader@65b4fad5
<no principals>
java.security.Permissions@74b2002f (
(java.io.FilePermission \D:\ws\no-manifest.jar read)
)
Checking /ws/no-manifest.jar
class res=jar-file:file:///D:/ws/no-manifest.jar!/code/ClassToLoad.class (java.net.URL)
java.lang.ClassNotFoundException: code.ClassToLoad
at org.apache.commons.vfs2.impl.VFSClassLoader.findClass(VFSClassLoader.java:181)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at vfstest.VFSClassLoaderTest.findClass(VFSClassLoaderTest.java:56)
at vfstest.VFSClassLoaderTest.testFindClassVFS1(VFSClassLoaderTest.java:32)
...
Caused by: org.apache.commons.vfs2.FileSystemException: Could not retrieve the certificates of "jar-file:file:///D:/ws/no-manifest.jar!/code/ClassToLoad.class".
at org.apache.commons.vfs2.provider.DefaultFileContent.getCertificates(DefaultFileContent.java:377)
at org.apache.commons.vfs2.impl.VFSClassLoader.defineClass(VFSClassLoader.java:220)
at org.apache.commons.vfs2.impl.VFSClassLoader.findClass(VFSClassLoader.java:177)
... 28 more
Caused by: java.lang.IllegalStateException: zip file closed
at java.util.jar.JarFile.getMetaInfEntryNames(Native Method)
at java.util.jar.JarFile.maybeInstantiateVerifier(JarFile.java:279)
at java.util.jar.JarFile.access$000(JarFile.java:43)
at java.util.jar.JarFile$JarFileEntry.getCertificates(JarFile.java:245)
at org.apache.commons.vfs2.provider.jar.JarFileObject.doGetCertificates(JarFileObject.java:145)
at org.apache.commons.vfs2.provider.DefaultFileContent.getCertificates(DefaultFileContent.java:365)
... 30 more
Checking /ws/manifest.jar
class res=jar-file:file:///D:/ws/manifest.jar!/code/ClassToLoad.class (java.net.URL)
VFS class=class code.ClassToLoad signers=[Ljava.security.cert.Certificate;@7b112783 domain=ProtectionDomain (jar-file:file:///D:/ws/manifest.jar!/ <no signer certificates>)
org.apache.commons.vfs2.impl.VFSClassLoader@2c76e369
<no principals>
java.security.Permissions@23394894 (
)
diff --git a/core/src/main/java/org/apache/commons/vfs2/provider/zip/ZipFileSystem.java b/core/src/main/java/org/apache/commons/vfs2/provider/zip/ZipFileSystem.java
index 22a8933..baabc96 100644
--- a/core/src/main/java/org/apache/commons/vfs2/provider/zip/ZipFileSystem.java
+++ b/core/src/main/java/org/apache/commons/vfs2/provider/zip/ZipFileSystem.java
@@ -18,12 +18,14 @@
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.jar.JarEntry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -84,11 +86,13 @@
try
{
// Build the index
- final List<ZipFileObject> strongRef = new ArrayList<ZipFileObject>(getZipFile().size());
- final Enumeration<? extends ZipEntry> entries = getZipFile().entries();
+ final ZipFile zip = getZipFile();
+ final List<ZipFileObject> strongRef = new ArrayList<ZipFileObject>(zip.size());
+ final Enumeration<? extends ZipEntry> entries = zip.entries();
+ ZipEntry entry = null;
while (entries.hasMoreElements())
{
- final ZipEntry entry = entries.nextElement();
+ entry = entries.nextElement();
final AbstractFileName name = (AbstractFileName) getFileSystemManager().resolveName(getRootName(),
UriParser.encode(entry.getName()));
@@ -127,6 +131,22 @@
parent.attachChild(fileObj.getName());
}
}
+ // if we found a (last) entry we open it to trigger verification
+ if (entry instanceof JarEntry)
+ {
+ System.out.println("reading last...");
+ try
+ {
+ InputStream in = zip.getInputStream(entry);
+ in.close();
+ }
+ catch (IOException ignored)
+ {
+ System.out.println("ignored last ex " + ignored);
+ }
+ } else {
+ System.out.println("no last...");
+ }
}
finally
{
package vfstest;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import org.apache.commons.vfs2.CacheStrategy;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.cache.DefaultFilesCache;
import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
import org.apache.commons.vfs2.impl.VFSClassLoader;
import org.apache.commons.vfs2.provider.jar.JarFileProvider;
import org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider;
import org.apache.commons.vfs2.provider.zip.ZipFileProvider;
import org.junit.Before;
import org.junit.Test;
public class VFSClassLoaderTest
{
private static final File JARFILE1 = new File("no-manifest.jar");
private static final File JARFILE2 = new File("manifest.jar");
DefaultFileSystemManager manager;
FileObject testRoot;
@Test
public void testFindClassVFS1() throws Exception
{
findClass(JARFILE1);
}
@Test
public void testFindClassVFS2() throws Exception
{
findClass(JARFILE2);
}
private void findClass(File jarFile) throws Exception
{
FileObject fo = manager.toFileObject(jarFile);
System.out.println("Checking " + fo.getName().getPath());
assertTrue(fo.getType().hasContent());
assertTrue(manager.canCreateFileSystem(fo));
VFSClassLoader cl = new VFSClassLoader(fo, manager);
URL res = cl.getResource("code/ClassToLoad.class");
System.out.println("class res=" + res + " (" + res.getClass().getName() +")");
try
{
// this is the problem
Class< ? > c = cl.loadClass("code.ClassToLoad");
System.out.println(" VFS class=" + c + " signers=" + c.getSigners() + " domain=" + c.getProtectionDomain());
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
}
@Test
public void testFindClassUCL() throws Exception
{
File testFile = JARFILE1;
System.out.println("Checking with URL class loader " + testFile.getAbsolutePath() + " exists=" + testFile.exists());
//u.openStream();
URL[] urls = new URL[] { testFile.toURI().toURL() };
URLClassLoader ucl = new URLClassLoader(urls, null);
try
{
Class< ? > c = ucl.loadClass("code.ClassToLoad"); // works
System.out.println(" UCL class=" + c + " signers=" + c.getSigners() + " domain=" + c.getProtectionDomain());
}
catch (Exception e)
{
e.printStackTrace();
throw e;
}
}
@Before
public void startup() throws FileSystemException
{
manager = new DefaultFileSystemManager();
manager.addProvider("file", new DefaultLocalFileProvider());
manager.addProvider("jar-file", new JarFileProvider());
manager.addProvider("zip-file", new ZipFileProvider());
manager.addExtensionMap("jar", "jar-file"); // zip-file works
manager.setCacheStrategy(CacheStrategy.MANUAL);
manager.setFilesCache(new DefaultFilesCache());
manager.init();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment