package mil.nga.giat.geowave.core.store.spi; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.Iterator; import java.util.ServiceLoader; import mil.nga.giat.geowave.core.store.data.field.FieldSerializationProviderSpi; import org.apache.commons.vfs2.CacheStrategy; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.cache.SoftRefFilesCache; 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.junit.Test; public class SPIServiceRegistryTest { @Test public void test() throws FileSystemException, MalformedURLException { DefaultFileSystemManager fsManager = new DefaultFileSystemManager(); fsManager.setCacheStrategy(CacheStrategy.MANUAL); fsManager.setFilesCache(new SoftRefFilesCache()); fsManager.addProvider( "file", new DefaultLocalFileProvider()); fsManager.addProvider( "jar", new JarFileProvider()); fsManager.setBaseFile(new File( ".")); // fsManager.addProvider("jar", new JarFileProvider()); fsManager.init(); FileObject jarFile = fsManager.resolveFile("jar:src/test/test.jar"); final VFSClassLoader cl = new VFSClassLoader( jarFile, fsManager); final FileObject[] fileObjs = cl.getFileObjects(); final URL[] fileUrls = new URL[fileObjs.length]; for (int i = 0; i < fileObjs.length; i++) { fileUrls[i] = new URL( fileObjs[i].toString()); } SPIServiceRegistry registry = new SPIServiceRegistry( FieldSerializationProviderSpi.class); registry.registerLocalClassLoader(java.security.AccessController .doPrivileged(new java.security.PrivilegedAction<URLClassLoader>() { public URLClassLoader run() { final URLClassLoader ucl = new URLClassLoader( fileUrls, cl); return ucl; } })); // Proves that the VFS Classloader SPI loading bug exists Iterator<FieldSerializationProviderSpi> it1 = ServiceLoader.load( FieldSerializationProviderSpi.class).iterator(); boolean found = false; while (it1.hasNext()) { found |= it1.next().getClass().equals( BooleanSerializationProvider.class); } assertFalse(found); Iterator<FieldSerializationProviderSpi> it = registry.load(FieldSerializationProviderSpi.class); found = false; try { while (it.hasNext()) { found |= it.next().getClass().equals( BooleanSerializationProvider.class); } } catch (Throwable ex) { assertTrue(ex instanceof NoClassDefFoundError && ex.getLocalizedMessage().contains( "FieldSerializationProviderSpi")); return; } assertTrue( "The class not found exception is expected since the JAR file was not registered", false); } }