/** * Hook method called by the running thread whenever a runnable task is given to the thread to run. * * @param thread thread * @param runnable runnable */ @Override protected void beforeExecute(final Thread thread, final Runnable runnable) { // Ensure classloader is correct thread.setContextClassLoader(NarThreadContextClassLoader.getInstance()); super.beforeExecute(thread, runnable); }
private Class<?> findNarClass(final Class<?> cls) { for (final Class<?> narClass : narSpecificClasses) { if (narClass.isAssignableFrom(cls)) { return cls; } else if (cls.getEnclosingClass() != null) { return findNarClass(cls.getEnclosingClass()); } } return null; }
@Override public InputStream getResourceAsStream(String name) { return lookupClassLoader().getResourceAsStream(name); }
private ProvenanceRepository createProvenanceRepository(final NiFiProperties properties) throws InstantiationException, IllegalAccessException, ClassNotFoundException { final String implementationClassName = properties.getProperty(NiFiProperties.PROVENANCE_REPO_IMPLEMENTATION_CLASS, DEFAULT_PROVENANCE_REPO_IMPLEMENTATION); if (implementationClassName == null) { throw new RuntimeException("Cannot create Provenance Repository because the NiFi Properties is missing the following property: " + NiFiProperties.PROVENANCE_REPO_IMPLEMENTATION_CLASS); } try { return NarThreadContextClassLoader.createInstance(extensionManager, implementationClassName, ProvenanceRepository.class, properties); } catch (final Exception e) { throw new RuntimeException(e); } }
private ComponentStatusRepository createComponentStatusRepository() { final String implementationClassName = nifiProperties.getProperty(NiFiProperties.COMPONENT_STATUS_REPOSITORY_IMPLEMENTATION, DEFAULT_COMPONENT_STATUS_REPO_IMPLEMENTATION); if (implementationClassName == null) { throw new RuntimeException("Cannot create Component Status Repository because the NiFi Properties is missing the following property: " + NiFiProperties.COMPONENT_STATUS_REPOSITORY_IMPLEMENTATION); } try { return NarThreadContextClassLoader.createInstance(extensionManager, implementationClassName, ComponentStatusRepository.class, nifiProperties); } catch (final Exception e) { throw new RuntimeException(e); } }
@Override public Class<?> loadClass(String name) throws ClassNotFoundException { return lookupClassLoader().loadClass(name); }
public static NarCloseable withNarLoader() { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); return new NarCloseable(current); }
private ClassLoader lookupClassLoader() { final Class<?>[] classStack = contextSecurityManager.getExecutionStack(); for (Class<?> currentClass : classStack) { final Class<?> narClass = findNarClass(currentClass); if (narClass != null) { final ClassLoader desiredClassLoader = narClass.getClassLoader(); // When new Threads are created, the new Thread inherits the ClassLoaderContext of // the caller. However, the call stack of that new Thread may not trace back to any NiFi-specific // code. Therefore, the NarThreadContextClassLoader will be unable to find the appropriate NAR // ClassLoader. As a result, we want to set the ContextClassLoader to the NAR ClassLoader that // contains the class or resource that we are looking for. // This locks the current Thread into the appropriate NAR ClassLoader Context. The framework will change // the ContextClassLoader back to the NarThreadContextClassLoader as appropriate via the // {@link FlowEngine.beforeExecute(Thread, Runnable)} and // {@link FlowEngine.afterExecute(Thread, Runnable)} methods. if (desiredClassLoader instanceof NarClassLoader) { Thread.currentThread().setContextClassLoader(desiredClassLoader); } return desiredClassLoader; } } return forward; }
private ContentRepository createContentRepository(final NiFiProperties properties) throws InstantiationException, IllegalAccessException, ClassNotFoundException { final String implementationClassName = properties.getProperty(NiFiProperties.CONTENT_REPOSITORY_IMPLEMENTATION, DEFAULT_CONTENT_REPO_IMPLEMENTATION); if (implementationClassName == null) { throw new RuntimeException("Cannot create Content Repository because the NiFi Properties is missing the following property: " + NiFiProperties.CONTENT_REPOSITORY_IMPLEMENTATION); } try { final ContentRepository contentRepo = NarThreadContextClassLoader.createInstance(extensionManager, implementationClassName, ContentRepository.class, properties); synchronized (contentRepo) { contentRepo.initialize(resourceClaimManager); } return contentRepo; } catch (final Exception e) { throw new RuntimeException(e); } }
@Override public URL getResource(String name) { return lookupClassLoader().getResource(name); }
throws InstantiationException, IllegalAccessException, ClassNotFoundException { final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); try { final List<Bundle> bundles = extensionManager.getBundles(implementationClassName);
private Class<?> findNarClass(final Class<?> cls) { for (final Class<?> narClass : narSpecificClasses) { if (narClass.isAssignableFrom(cls)) { return cls; } else if (cls.getEnclosingClass() != null) { return findNarClass(cls.getEnclosingClass()); } } return null; }
private static FlowFileRepository createFlowFileRepository(final NiFiProperties properties, final ExtensionManager extensionManager, final ResourceClaimManager contentClaimManager) { final String implementationClassName = properties.getProperty(NiFiProperties.FLOWFILE_REPOSITORY_IMPLEMENTATION, DEFAULT_FLOWFILE_REPO_IMPLEMENTATION); if (implementationClassName == null) { throw new RuntimeException("Cannot create FlowFile Repository because the NiFi Properties is missing the following property: " + NiFiProperties.FLOWFILE_REPOSITORY_IMPLEMENTATION); } try { final FlowFileRepository created = NarThreadContextClassLoader.createInstance(extensionManager, implementationClassName, FlowFileRepository.class, properties); synchronized (created) { created.initialize(contentClaimManager); } return created; } catch (final Exception e) { throw new RuntimeException(e); } }
@Override public Enumeration<URL> getResources(String name) throws IOException { return lookupClassLoader().getResources(name); }
public static NarCloseable withNarLoader() { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); return new NarCloseable(current); }
private Class<?> findNarClass(final Class<?> cls) { for (final Class<?> narClass : narSpecificClasses) { if (narClass.isAssignableFrom(cls)) { return cls; } else if (cls.getEnclosingClass() != null) { return findNarClass(cls.getEnclosingClass()); } } return null; }
public FlowFileSwapManager createSwapManager() { final String implementationClassName = nifiProperties.getProperty(NiFiProperties.FLOWFILE_SWAP_MANAGER_IMPLEMENTATION, DEFAULT_SWAP_MANAGER_IMPLEMENTATION); if (implementationClassName == null) { return null; } try { final FlowFileSwapManager swapManager = NarThreadContextClassLoader.createInstance(extensionManager, implementationClassName, FlowFileSwapManager.class, nifiProperties); final EventReporter eventReporter = createEventReporter(); try (final NarCloseable narCloseable = NarCloseable.withNarLoader()) { final SwapManagerInitializationContext initializationContext = new SwapManagerInitializationContext() { @Override public ResourceClaimManager getResourceClaimManager() { return resourceClaimManager; } @Override public FlowFileRepository getFlowFileRepository() { return flowFileRepository; } @Override public EventReporter getEventReporter() { return eventReporter; } }; swapManager.initialize(initializationContext); } return swapManager; } catch (final Exception e) { throw new RuntimeException(e); } }
@Override public void setPackageAssertionStatus(String packageName, boolean enabled) { lookupClassLoader().setPackageAssertionStatus(packageName, enabled); }
public static NarCloseable withNarLoader() { final ClassLoader current = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance()); return new NarCloseable(current); }
private ClassLoader lookupClassLoader() { final Class<?>[] classStack = contextSecurityManager.getExecutionStack(); for (Class<?> currentClass : classStack) { final Class<?> narClass = findNarClass(currentClass); if (narClass != null) { final ClassLoader desiredClassLoader = narClass.getClassLoader(); // When new Threads are created, the new Thread inherits the ClassLoaderContext of // the caller. However, the call stack of that new Thread may not trace back to any NiFi-specific // code. Therefore, the NarThreadContextClassLoader will be unable to find the appropriate NAR // ClassLoader. As a result, we want to set the ContextClassLoader to the NAR ClassLoader that // contains the class or resource that we are looking for. // This locks the current Thread into the appropriate NAR ClassLoader Context. The framework will change // the ContextClassLoader back to the NarThreadContextClassLoader as appropriate via the // {@link FlowEngine.beforeExecute(Thread, Runnable)} and // {@link FlowEngine.afterExecute(Thread, Runnable)} methods. if (desiredClassLoader instanceof NarClassLoader) { Thread.currentThread().setContextClassLoader(desiredClassLoader); } return desiredClassLoader; } } return forward; }