### Question:
NarThreadContextClassLoader extends URLClassLoader { public static <T> T createInstance(final String implementationClassName, final Class<T> typeDefinition, final NiFiProperties nifiProperties) throws InstantiationException, IllegalAccessException, ClassNotFoundException { final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); try { final ClassLoader detectedClassLoaderForType = ExtensionManager.getClassLoader(implementationClassName); final Class<?> rawClass; if (detectedClassLoaderForType == null) { rawClass = Class.forName(implementationClassName); } else { rawClass = Class.forName(implementationClassName, true, ExtensionManager.getClassLoader(implementationClassName)); } Thread.currentThread().setContextClassLoader(detectedClassLoaderForType); final Class<?> desiredClass = rawClass.asSubclass(typeDefinition); if(nifiProperties == null){ return typeDefinition.cast(desiredClass.newInstance()); } Constructor<?> constructor = null; try { constructor = desiredClass.getConstructor(NiFiProperties.class); } catch (NoSuchMethodException nsme) { try { constructor = desiredClass.getConstructor(); } catch (NoSuchMethodException nsme2) { throw new IllegalStateException("Failed to find constructor which takes NiFiProperties as argument as well as the default constructor on " + desiredClass.getName(), nsme2); } } try { if (constructor.getParameterTypes().length == 0) { return typeDefinition.cast(constructor.newInstance()); } else { return typeDefinition.cast(constructor.newInstance(nifiProperties)); } } catch (InvocationTargetException ite) { throw new IllegalStateException("Failed to instantiate a component due to (see target exception)", ite); } } finally { Thread.currentThread().setContextClassLoader(originalClassLoader); } } private  NarThreadContextClassLoader(); @Override void clearAssertionStatus(); @Override URL getResource(String name); @Override InputStream getResourceAsStream(String name); @Override Enumeration<URL> getResources(String name); @Override Class<?> loadClass(String name); @Override void setClassAssertionStatus(String className, boolean enabled); @Override void setDefaultAssertionStatus(boolean enabled); @Override void setPackageAssertionStatus(String packageName, boolean enabled); static NarThreadContextClassLoader getInstance(); static T createInstance(final String implementationClassName, final Class<T> typeDefinition, final NiFiProperties nifiProperties);  }### Answer:
@Test public void validateWithPropertiesConstructor() throws Exception { NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null); assertTrue(NarThreadContextClassLoader.createInstance(WithPropertiesConstructor.class.getName(), WithPropertiesConstructor.class, properties) instanceof WithPropertiesConstructor); }
@Test(expected = IllegalStateException.class) public void validateWithPropertiesConstructorInstantiationFailure() throws Exception { Map<String, String> additionalProperties = new HashMap<>(); additionalProperties.put("fail", "true"); NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", additionalProperties); NarThreadContextClassLoader.createInstance(WithPropertiesConstructor.class.getName(), WithPropertiesConstructor.class, properties); }
@Test public void validateWithDefaultConstructor() throws Exception { NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null); assertTrue(NarThreadContextClassLoader.createInstance(WithDefaultConstructor.class.getName(), WithDefaultConstructor.class, properties) instanceof WithDefaultConstructor); }
@Test(expected = IllegalStateException.class) public void validateWithWrongConstructor() throws Exception { NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null); NarThreadContextClassLoader.createInstance(WrongConstructor.class.getName(), WrongConstructor.class, properties); }