ShimBridgingClassloader extends ClassLoader implements BundleReference { @Override public Class<?> loadClass( String name, boolean resolve ) throws ClassNotFoundException { Class<?> result = null; synchronized ( this ) { result = findLoadedClass( name ); } if ( result == null ) { try { result = findClass( name ); } catch ( Exception e ) { } } if ( result == null ) { try { Class<?> osgiProvidedClass = bundleWiringClassloader.loadClass( name, resolve ); if ( osgiProvidedClass.getClassLoader() == PluginRegistry.class.getClassLoader() ) { try { return super.loadClass( name, resolve ); } catch ( Exception e ) { } } return osgiProvidedClass; } catch ( Exception e ) { } } if ( result == null ) { return super.loadClass( name, resolve ); } if ( resolve ) { resolveClass( result ); } return result; } ShimBridgingClassloader( ClassLoader parentClassLoader, BundleContext bundleContext ); static Object create( BundleContext bundleContext, String className, List<Object> arguments ); @Override URL getResource( String name ); @Override Class<?> loadClass( String name, boolean resolve ); @Override Bundle getBundle(); static final String HADOOP_SPOON_PLUGIN; }
@Test public void testLoadClassFromBothOSGiAndParent() throws ClassNotFoundException { String testName = "testName"; when( parentClassLoader.loadClass( testName, false ) ).thenReturn( (Class) Object.class ); when( bundleWiringClassloader.loadClass( testName, false ) ).thenReturn( (Class) PluginRegistry.class ); assertEquals( Object.class, shimBridgingClassloader.loadClass( testName ) ); }
@Test public void testLoadClassFromBothOSGiAndParentParentException() throws ClassNotFoundException { String testName = "testName"; when( parentClassLoader.loadClass( testName, false ) ).thenThrow( new RuntimeException() ); when( bundleWiringClassloader.loadClass( testName, false ) ).thenReturn( (Class) PluginRegistry.class ); assertEquals( PluginRegistry.class, shimBridgingClassloader.loadClass( testName ) ); }
@Test public void testLoadClassFromOSGi() throws ClassNotFoundException { String testName = "testName"; when( bundleWiringClassloader.loadClass( testName, false ) ).thenReturn( (Class) Object.class ); assertEquals( Object.class, shimBridgingClassloader.loadClass( testName ) ); }
@Test public void testLoadClassFromParent() throws ClassNotFoundException { String testName = "testName"; when( parentClassLoader.loadClass( testName, false ) ).thenReturn( (Class) Object.class ); assertEquals( Object.class, shimBridgingClassloader.loadClass( testName ) ); }
@Test public void testLoadClassFindClass() throws ClassNotFoundException, IOException, KettleFileException { String canonicalName = ShimBridgingClassloader.class.getCanonicalName(); FileObject myFile = KettleVFS.getFileObject( "ram: try ( FileObject fileObject = myFile ) { try ( OutputStream outputStream = fileObject.getContent().getOutputStream( false ) ) { IOUtils.copy( getClass().getClassLoader().getResourceAsStream( canonicalName.replace( ".", "/" ) + ".class" ), outputStream ); } String packageName = ShimBridgingClassloader.class.getPackage().getName(); when( bundleWiring.findEntries( "/" + packageName.replace( ".", "/" ), ShimBridgingClassloader.class.getSimpleName() + ".class", 0 ) ) .thenReturn( Arrays.asList( fileObject.getURL() ) ); when( parentClassLoader.loadClass( anyString(), anyBoolean() ) ).thenAnswer( new Answer<Class<?>>() { @Override public Class<?> answer( InvocationOnMock invocation ) throws Throwable { Object[] arguments = invocation.getArguments(); return new ShimBridgingClassloader.PublicLoadResolveClassLoader( getClass().getClassLoader() ) .loadClass( (String) arguments[ 0 ], (boolean) arguments[ 1 ] ); } } ); Class<?> shimBridgingClassloaderClass = shimBridgingClassloader.loadClass( canonicalName, true ); assertEquals( canonicalName, shimBridgingClassloaderClass.getCanonicalName() ); assertEquals( shimBridgingClassloader, shimBridgingClassloaderClass.getClassLoader() ); assertEquals( packageName, shimBridgingClassloaderClass.getPackage().getName() ); Class<?> shimBridgingClassloaderClass2 = shimBridgingClassloader.loadClass( canonicalName, false ); assertEquals( shimBridgingClassloaderClass, shimBridgingClassloaderClass2 ); } finally { myFile.delete(); } }