nifi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mcgil...@apache.org
Subject [3/7] nifi git commit: NIFI-3520 Refactoring instance class loading - Fixing FlowController to use appropriate class loader when instantiating processor - Updating ExtensionManager to leverage new flag in MANIFEST from NAR plugin - Adding ReloadComponent
Date Thu, 06 Apr 2017 17:51:50 GMT
http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java
deleted file mode 100644
index d9320b2..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockProcessorInitializationContext.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.mock;
-
-import org.apache.nifi.controller.ControllerServiceLookup;
-import org.apache.nifi.controller.NodeTypeProvider;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.processor.ProcessorInitializationContext;
-
-import java.io.File;
-
-/**
- * A Mock ProcessorInitializationContext that can be used so that Processors can
- * be initialized for the purpose of generating documentation.
- *
- *
- */
-public class MockProcessorInitializationContext implements ProcessorInitializationContext {
-
-    @Override
-    public String getIdentifier() {
-        return "mock-processor";
-    }
-
-    @Override
-    public ComponentLog getLogger() {
-        return new MockComponentLogger();
-    }
-
-    @Override
-    public ControllerServiceLookup getControllerServiceLookup() {
-        return new MockControllerServiceLookup();
-    }
-
-    @Override
-    public NodeTypeProvider getNodeTypeProvider() {
-        return new MockNodeTypeProvider();
-    }
-
-    @Override
-    public String getKerberosServicePrincipal() {
-        return null;
-    }
-
-    @Override
-    public File getKerberosServiceKeytab() {
-        return null;
-    }
-
-    @Override
-    public File getKerberosConfigurationFile() {
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java
deleted file mode 100644
index 630c657..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/mock/MockReportingInitializationContext.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.mock;
-
-import org.apache.nifi.controller.ControllerServiceLookup;
-import org.apache.nifi.logging.ComponentLog;
-import org.apache.nifi.reporting.ReportingInitializationContext;
-import org.apache.nifi.scheduling.SchedulingStrategy;
-
-import java.io.File;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A Mock ReportingInitializationContext that can be used to initialize a
- * ReportingTask for the purposes of documentation generation.
- *
- */
-public class MockReportingInitializationContext implements ReportingInitializationContext {
-
-    @Override
-    public String getIdentifier() {
-        return "mock-reporting-task";
-    }
-
-    @Override
-    public String getName() {
-        return "";
-    }
-
-    @Override
-    public long getSchedulingPeriod(TimeUnit timeUnit) {
-        return 0;
-    }
-
-    @Override
-    public ControllerServiceLookup getControllerServiceLookup() {
-        return new MockControllerServiceLookup();
-    }
-
-    @Override
-    public String getSchedulingPeriod() {
-        return "";
-    }
-
-    @Override
-    public SchedulingStrategy getSchedulingStrategy() {
-        return SchedulingStrategy.TIMER_DRIVEN;
-    }
-
-    @Override
-    public ComponentLog getLogger() {
-        return new MockComponentLogger();
-    }
-
-    @Override
-    public String getKerberosServicePrincipal() {
-        return null;
-    }
-
-    @Override
-    public File getKerberosServiceKeytab() {
-        return null;
-    }
-
-    @Override
-    public File getKerberosConfigurationFile() {
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java
deleted file mode 100644
index 1cff3af..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/ExtensionManager.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.nar;
-
-import org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading;
-import org.apache.nifi.authentication.LoginIdentityProvider;
-import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.bundle.Bundle;
-import org.apache.nifi.bundle.BundleCoordinate;
-import org.apache.nifi.bundle.BundleDetails;
-import org.apache.nifi.components.ConfigurableComponent;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.state.StateProvider;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.repository.ContentRepository;
-import org.apache.nifi.controller.repository.FlowFileRepository;
-import org.apache.nifi.controller.repository.FlowFileSwapManager;
-import org.apache.nifi.controller.status.history.ComponentStatusRepository;
-import org.apache.nifi.flowfile.FlowFilePrioritizer;
-import org.apache.nifi.init.ConfigurableComponentInitializer;
-import org.apache.nifi.init.ConfigurableComponentInitializerFactory;
-import org.apache.nifi.processor.Processor;
-import org.apache.nifi.provenance.ProvenanceRepository;
-import org.apache.nifi.reporting.InitializationException;
-import org.apache.nifi.reporting.ReportingTask;
-import org.apache.nifi.util.NiFiProperties;
-import org.apache.nifi.util.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-/**
- * Scans through the classpath to load all FlowFileProcessors, FlowFileComparators, and ReportingTasks using the service provider API and running through all classloaders (root, NARs).
- *
- * @ThreadSafe - is immutable
- */
-@SuppressWarnings("rawtypes")
-public class ExtensionManager {
-
-    private static final Logger logger = LoggerFactory.getLogger(ExtensionManager.class);
-
-    public static final BundleCoordinate SYSTEM_BUNDLE_COORDINATE = new BundleCoordinate(
-            BundleCoordinate.DEFAULT_GROUP, "system", BundleCoordinate.DEFAULT_VERSION);
-
-    // Maps a service definition (interface) to those classes that implement the interface
-    private static final Map<Class, Set<Class>> definitionMap = new HashMap<>();
-
-    private static final Map<String, List<Bundle>> classNameBundleLookup = new HashMap<>();
-    private static final Map<BundleCoordinate, Bundle> bundleCoordinateBundleLookup = new HashMap<>();
-    private static final Map<ClassLoader, Bundle> classLoaderBundleLookup = new HashMap<>();
-
-    private static final Set<String> requiresInstanceClassLoading = new HashSet<>();
-    private static final Map<String, ClassLoader> instanceClassloaderLookup = new ConcurrentHashMap<>();
-
-    static {
-        definitionMap.put(Processor.class, new HashSet<>());
-        definitionMap.put(FlowFilePrioritizer.class, new HashSet<>());
-        definitionMap.put(ReportingTask.class, new HashSet<>());
-        definitionMap.put(ControllerService.class, new HashSet<>());
-        definitionMap.put(Authorizer.class, new HashSet<>());
-        definitionMap.put(LoginIdentityProvider.class, new HashSet<>());
-        definitionMap.put(ProvenanceRepository.class, new HashSet<>());
-        definitionMap.put(ComponentStatusRepository.class, new HashSet<>());
-        definitionMap.put(FlowFileRepository.class, new HashSet<>());
-        definitionMap.put(FlowFileSwapManager.class, new HashSet<>());
-        definitionMap.put(ContentRepository.class, new HashSet<>());
-        definitionMap.put(StateProvider.class, new HashSet<>());
-    }
-
-    /**
-     * Loads all FlowFileProcessor, FlowFileComparator, ReportingTask class types that can be found on the bootstrap classloader and by creating classloaders for all NARs found within the classpath.
-     * @param narBundles the bundles to scan through in search of extensions
-     */
-    public static void discoverExtensions(final Bundle systemBundle, final Set<Bundle> narBundles) {
-        // get the current context class loader
-        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
-
-        // load the system bundle first so that any extensions found in JARs directly in lib will be registered as
-        // being from the system bundle and not from all the other NARs
-        loadExtensions(systemBundle);
-        bundleCoordinateBundleLookup.put(systemBundle.getBundleDetails().getCoordinate(), systemBundle);
-
-        // consider each nar class loader
-        for (final Bundle bundle : narBundles) {
-            // Must set the context class loader to the nar classloader itself
-            // so that static initialization techniques that depend on the context class loader will work properly
-            final ClassLoader ncl = bundle.getClassLoader();
-            Thread.currentThread().setContextClassLoader(ncl);
-            loadExtensions(bundle);
-
-            // Create a look-up from coordinate to bundle
-            bundleCoordinateBundleLookup.put(bundle.getBundleDetails().getCoordinate(), bundle);
-        }
-
-        // restore the current context class loader if appropriate
-        if (currentContextClassLoader != null) {
-            Thread.currentThread().setContextClassLoader(currentContextClassLoader);
-        }
-    }
-
-    /**
-     * Returns a bundle representing the system class loader.
-     *
-     * @param niFiProperties a NiFiProperties instance which will be used to obtain the default NAR library path,
-     *                       which will become the working directory of the returned bundle
-     * @return a bundle for the system class loader
-     */
-    public static Bundle createSystemBundle(final NiFiProperties niFiProperties) {
-        final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
-
-        final String narLibraryDirectory = niFiProperties.getProperty(NiFiProperties.NAR_LIBRARY_DIRECTORY);
-        if (StringUtils.isBlank(narLibraryDirectory)) {
-            throw new IllegalStateException("Unable to create system bundle because " + NiFiProperties.NAR_LIBRARY_DIRECTORY + " was null or empty");
-        }
-
-        final BundleDetails systemBundleDetails = new BundleDetails.Builder()
-                .workingDir(new File(narLibraryDirectory))
-                .coordinate(SYSTEM_BUNDLE_COORDINATE)
-                .build();
-
-        return new Bundle(systemBundleDetails, systemClassLoader);
-    }
-
-    /**
-     * Loads extensions from the specified bundle.
-     *
-     * @param bundle from which to load extensions
-     */
-    @SuppressWarnings("unchecked")
-    private static void loadExtensions(final Bundle bundle) {
-        for (final Map.Entry<Class, Set<Class>> entry : definitionMap.entrySet()) {
-            final boolean isControllerService = ControllerService.class.equals(entry.getKey());
-            final boolean isProcessor = Processor.class.equals(entry.getKey());
-            final boolean isReportingTask = ReportingTask.class.equals(entry.getKey());
-
-            final ServiceLoader<?> serviceLoader = ServiceLoader.load(entry.getKey(), bundle.getClassLoader());
-            for (final Object o : serviceLoader) {
-                // only consider extensions discovered directly in this bundle
-                boolean registerExtension = bundle.getClassLoader().equals(o.getClass().getClassLoader());
-
-                if (registerExtension) {
-                    final Class extensionType = o.getClass();
-                    if (isControllerService && !checkControllerServiceEligibility(extensionType)) {
-                        registerExtension = false;
-                        logger.error(String.format(
-                                "Skipping Controller Service %s because it is bundled with its supporting APIs and requires instance class loading.", extensionType.getName()));
-                    }
-
-                    final boolean canReferenceControllerService = (isControllerService || isProcessor || isReportingTask) && o instanceof ConfigurableComponent;
-                    if (canReferenceControllerService && !checkControllerServiceReferenceEligibility((ConfigurableComponent) o, bundle.getClassLoader())) {
-                        registerExtension = false;
-                        logger.error(String.format(
-                                "Skipping component %s because it is bundled with its referenced Controller Service APIs and requires instance class loading.", extensionType.getName()));
-                    }
-
-                    if (registerExtension) {
-                        registerServiceClass(o.getClass(), classNameBundleLookup, bundle, entry.getValue());
-                    }
-                }
-            }
-
-            classLoaderBundleLookup.put(bundle.getClassLoader(), bundle);
-        }
-    }
-
-    private static boolean checkControllerServiceReferenceEligibility(final ConfigurableComponent component, final ClassLoader classLoader) {
-        // if the extension does not require instance classloading, its eligible
-        final boolean requiresInstanceClassLoading = component.getClass().isAnnotationPresent(RequiresInstanceClassLoading.class);
-
-        ConfigurableComponentInitializer initializer = null;
-        try {
-            initializer = ConfigurableComponentInitializerFactory.createComponentInitializer(component.getClass());
-            initializer.initialize(component);
-
-            final Set<Class> cobundledApis = new HashSet<>();
-            try (final NarCloseable closeable = NarCloseable.withComponentNarLoader(component.getClass().getClassLoader())) {
-                final List<PropertyDescriptor> descriptors = component.getPropertyDescriptors();
-                if (descriptors != null && !descriptors.isEmpty()) {
-                    for (final PropertyDescriptor descriptor : descriptors) {
-                        final Class<? extends ControllerService> serviceApi = descriptor.getControllerServiceDefinition();
-                        if (serviceApi != null && classLoader.equals(serviceApi.getClassLoader())) {
-                            cobundledApis.add(serviceApi);
-                        }
-                    }
-                }
-            }
-
-            if (!cobundledApis.isEmpty()) {
-                logger.warn(String.format(
-                        "Component %s is bundled with its referenced Controller Service APIs %s. The service APIs should not be bundled with component implementations that reference it.",
-                        component.getClass().getName(), StringUtils.join(cobundledApis.stream().map(cls -> cls.getName()).collect(Collectors.toSet()), ", ")));
-            }
-
-            // the component is eligible when it does not require instance classloading or when the supporting APIs are bundled in a parent NAR
-            return requiresInstanceClassLoading == false || cobundledApis.isEmpty();
-        } catch (final InitializationException e) {
-            logger.warn(String.format("Unable to verify if component %s references any bundled Controller Service APIs due to %s", component.getClass().getName(), e.getMessage()));
-            return true;
-        } finally {
-            if (initializer != null) {
-                initializer.teardown(component);
-            }
-        }
-    }
-
-    private static boolean checkControllerServiceEligibility(Class extensionType) {
-        final Class originalExtensionType = extensionType;
-        final ClassLoader originalExtensionClassLoader = extensionType.getClassLoader();
-
-        // if the extension does not require instance classloading, its eligible
-        final boolean requiresInstanceClassLoading = extensionType.isAnnotationPresent(RequiresInstanceClassLoading.class);
-
-        final Set<Class> cobundledApis = new HashSet<>();
-        while (extensionType != null) {
-            for (final Class i : extensionType.getInterfaces()) {
-                if (originalExtensionClassLoader.equals(i.getClassLoader())) {
-                    cobundledApis.add(i);
-                }
-            }
-
-            extensionType = extensionType.getSuperclass();
-        }
-
-        if (!cobundledApis.isEmpty()) {
-            logger.warn(String.format("Controller Service %s is bundled with its supporting APIs %s. The service APIs should not be bundled with the implementations.",
-                    originalExtensionType.getName(), StringUtils.join(cobundledApis.stream().map(cls -> cls.getName()).collect(Collectors.toSet()), ", ")));
-        }
-
-        // the service is eligible when it does not require instance classloading or when the supporting APIs are bundled in a parent NAR
-        return requiresInstanceClassLoading == false || cobundledApis.isEmpty();
-    }
-
-    /**
-     * Registers extension for the specified type from the specified Bundle.
-     *
-     * @param type the extension type
-     * @param classNameBundleMap mapping of classname to Bundle
-     * @param bundle the Bundle being mapped to
-     * @param classes to map to this classloader but which come from its ancestors
-     */
-    private static void registerServiceClass(final Class<?> type, final Map<String, List<Bundle>> classNameBundleMap, final Bundle bundle, final Set<Class> classes) {
-        final String className = type.getName();
-
-        // get the bundles that have already been registered for the class name
-        List<Bundle> registeredBundles = classNameBundleMap.get(className);
-
-        if (registeredBundles == null) {
-            registeredBundles = new ArrayList<>();
-            classNameBundleMap.put(className, registeredBundles);
-        }
-
-        boolean alreadyRegistered = false;
-        for (final Bundle registeredBundle : registeredBundles) {
-            final BundleCoordinate registeredCoordinate = registeredBundle.getBundleDetails().getCoordinate();
-
-            // if the incoming bundle has the same coordinate as one of the registered bundles then consider it already registered
-            if (registeredCoordinate.equals(bundle.getBundleDetails().getCoordinate())) {
-                alreadyRegistered = true;
-                break;
-            }
-
-            // if the type wasn't loaded from an ancestor, and the type isn't a processor, cs, or reporting task, then
-            // fail registration because we don't support multiple versions of any other types
-            if (!multipleVersionsAllowed(type)) {
-                throw new IllegalStateException("Attempt was made to load " + className + " from "
-                        + bundle.getBundleDetails().getCoordinate().getCoordinate()
-                        + " but that class name is already loaded/registered from " + registeredBundle.getBundleDetails().getCoordinate()
-                        + " and multiple versions are not supported for this type"
-                );
-            }
-        }
-
-        // if none of the above was true then register the new bundle
-        if (!alreadyRegistered) {
-            registeredBundles.add(bundle);
-            classes.add(type);
-
-            if (type.isAnnotationPresent(RequiresInstanceClassLoading.class)) {
-                requiresInstanceClassLoading.add(className);
-            }
-        }
-
-    }
-
-    /**
-     * @param type a Class that we found from a service loader
-     * @return true if the given class is a processor, controller service, or reporting task
-     */
-    private static boolean multipleVersionsAllowed(Class<?> type) {
-        return Processor.class.isAssignableFrom(type) || ControllerService.class.isAssignableFrom(type) || ReportingTask.class.isAssignableFrom(type);
-    }
-
-    /**
-     * Determines the effective ClassLoader for the instance of the given type.
-     *
-     * @param classType the type of class to lookup the ClassLoader for
-     * @param instanceIdentifier the identifier of the specific instance of the classType to look up the ClassLoader for
-     * @param bundle the bundle where the classType exists
-     * @return the ClassLoader for the given instance of the given type, or null if the type is not a detected extension type
-     */
-    public static ClassLoader createInstanceClassLoader(final String classType, final String instanceIdentifier, final Bundle bundle) {
-        if (StringUtils.isEmpty(classType)) {
-            throw new IllegalArgumentException("Class-Type is required");
-        }
-
-        if (StringUtils.isEmpty(instanceIdentifier)) {
-            throw new IllegalArgumentException("Instance Identifier is required");
-        }
-
-        if (bundle == null) {
-            throw new IllegalArgumentException("Bundle is required");
-        }
-
-        final ClassLoader bundleClassLoader = bundle.getClassLoader();
-
-        // If the class is annotated with @RequiresInstanceClassLoading and the registered ClassLoader is a URLClassLoader
-        // then make a new InstanceClassLoader that is a full copy of the NAR Class Loader, otherwise create an empty
-        // InstanceClassLoader that has the NAR ClassLoader as a parent
-        ClassLoader instanceClassLoader;
-        if (requiresInstanceClassLoading.contains(classType) && (bundleClassLoader instanceof URLClassLoader)) {
-            final URLClassLoader registeredUrlClassLoader = (URLClassLoader) bundleClassLoader;
-            instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, registeredUrlClassLoader.getURLs(), registeredUrlClassLoader.getParent());
-        } else {
-            instanceClassLoader = new InstanceClassLoader(instanceIdentifier, classType, new URL[0], bundleClassLoader);
-        }
-
-        instanceClassloaderLookup.put(instanceIdentifier, instanceClassLoader);
-        return instanceClassLoader;
-    }
-
-    /**
-     * Retrieves the InstanceClassLoader for the component with the given identifier.
-     *
-     * @param instanceIdentifier the identifier of a component
-     * @return the instance class loader for the component
-     */
-    public static ClassLoader getInstanceClassLoader(final String instanceIdentifier) {
-        return instanceClassloaderLookup.get(instanceIdentifier);
-    }
-
-    /**
-     * Removes the ClassLoader for the given instance and closes it if necessary.
-     *
-     * @param instanceIdentifier the identifier of a component to remove the ClassLoader for
-     * @return the removed ClassLoader for the given instance, or null if not found
-     */
-    public static ClassLoader removeInstanceClassLoaderIfExists(final String instanceIdentifier) {
-        if (instanceIdentifier == null) {
-            return null;
-        }
-
-        final ClassLoader classLoader = instanceClassloaderLookup.remove(instanceIdentifier);
-        if (classLoader != null && (classLoader instanceof URLClassLoader)) {
-            final URLClassLoader urlClassLoader = (URLClassLoader) classLoader;
-            try {
-                urlClassLoader.close();
-            } catch (IOException e) {
-                logger.warn("Unable to class URLClassLoader for " + instanceIdentifier);
-            }
-        }
-        return classLoader;
-    }
-
-    /**
-     * Checks if the given class type requires per-instance class loading (i.e. contains the @RequiresInstanceClassLoading annotation)
-     *
-     * @param classType the class to check
-     * @return true if the class is found in the set of classes requiring instance level class loading, false otherwise
-     */
-    public static boolean requiresInstanceClassLoading(final String classType) {
-        if (classType == null) {
-            throw new IllegalArgumentException("Class type cannot be null");
-        }
-        return requiresInstanceClassLoading.contains(classType);
-    }
-
-    /**
-     * Retrieves the bundles that have a class with the given name.
-     *
-     * @param classType the class name of an extension
-     * @return the list of bundles that contain an extension with the given class name
-     */
-    public static List<Bundle> getBundles(final String classType) {
-        if (classType == null) {
-            throw new IllegalArgumentException("Class type cannot be null");
-        }
-        final List<Bundle> bundles = classNameBundleLookup.get(classType);
-        return bundles == null ? Collections.emptyList() : new ArrayList<>(bundles);
-    }
-
-    /**
-     * Retrieves the bundle with the given coordinate.
-     *
-     * @param bundleCoordinate a coordinate to look up
-     * @return the bundle with the given coordinate, or null if none exists
-     */
-    public static Bundle getBundle(final BundleCoordinate bundleCoordinate) {
-        if (bundleCoordinate == null) {
-            throw new IllegalArgumentException("BundleCoordinate cannot be null");
-        }
-        return bundleCoordinateBundleLookup.get(bundleCoordinate);
-    }
-
-    /**
-     * Retrieves the bundle for the given class loader.
-     *
-     * @param classLoader the class loader to look up the bundle for
-     * @return the bundle for the given class loader
-     */
-    public static Bundle getBundle(final ClassLoader classLoader) {
-        if (classLoader == null) {
-            throw new IllegalArgumentException("ClassLoader cannot be null");
-        }
-        return classLoaderBundleLookup.get(classLoader);
-    }
-
-    public static Set<Class> getExtensions(final Class<?> definition) {
-        if (definition == null) {
-            throw new IllegalArgumentException("Class cannot be null");
-        }
-        final Set<Class> extensions = definitionMap.get(definition);
-        return (extensions == null) ? Collections.<Class>emptySet() : extensions;
-    }
-
-    public static void logClassLoaderMapping() {
-        final StringBuilder builder = new StringBuilder();
-
-        builder.append("Extension Type Mapping to Bundle:");
-        for (final Map.Entry<Class, Set<Class>> entry : definitionMap.entrySet()) {
-            builder.append("\n\t=== ").append(entry.getKey().getSimpleName()).append(" Type ===");
-
-            for (final Class type : entry.getValue()) {
-                final List<Bundle> bundles = classNameBundleLookup.containsKey(type.getName())
-                        ? classNameBundleLookup.get(type.getName()) : Collections.emptyList();
-
-                builder.append("\n\t").append(type.getName());
-
-                for (final Bundle bundle : bundles) {
-                    final String coordinate = bundle.getBundleDetails().getCoordinate().getCoordinate();
-                    final String workingDir = bundle.getBundleDetails().getWorkingDirectory().getPath();
-                    builder.append("\n\t\t").append(coordinate).append(" || ").append(workingDir);
-                }
-            }
-
-            builder.append("\n\t=== End ").append(entry.getKey().getSimpleName()).append(" types ===");
-        }
-
-        logger.info(builder.toString());
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java
deleted file mode 100644
index 2a9c72d..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/InstanceClassLoader.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.nar;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-/**
- * A ClassLoader created for an instance of a component which lets a client add resources to an intermediary ClassLoader
- * that will be checked first when loading/finding classes.
- *
- * Typically an instance of this ClassLoader will be created by passing in the URLs and parent from a NARClassLoader in
- * order to create a copy of the NARClassLoader without modifying it.
- */
-public class InstanceClassLoader extends URLClassLoader {
-
-    private static final Logger logger = LoggerFactory.getLogger(InstanceClassLoader.class);
-
-    private final String identifier;
-    private final String instanceType;
-    private ShimClassLoader shimClassLoader;
-
-    /**
-     * @param identifier the id of the component this ClassLoader was created for
-     * @param urls the URLs for the ClassLoader
-     * @param parent the parent ClassLoader
-     */
-    public InstanceClassLoader(final String identifier, final String type, final URL[] urls, final ClassLoader parent) {
-        super(urls, parent);
-        this.identifier = identifier;
-        this.instanceType = type;
-    }
-
-    /**
-     * Initializes a new ShimClassLoader for the provided resources, closing the previous ShimClassLoader if one existed.
-     *
-     * @param urls the URLs for the ShimClassLoader
-     * @throws IOException if the previous ShimClassLoader existed and couldn't be closed
-     */
-    public synchronized void setInstanceResources(final URL[] urls) {
-        if (shimClassLoader != null) {
-            try {
-                shimClassLoader.close();
-            } catch (IOException e) {
-                logger.warn("Unable to close inner URLClassLoader for " + identifier);
-            }
-        }
-
-        shimClassLoader = new ShimClassLoader(urls, getParent());
-    }
-
-    /**
-     * @return the URLs for the instance resources that have been set
-     */
-    public synchronized URL[] getInstanceResources() {
-        if (shimClassLoader != null) {
-            return shimClassLoader.getURLs();
-        }
-        return new URL[0];
-    }
-
-    @Override
-    public Class<?> loadClass(String name) throws ClassNotFoundException {
-        return this.loadClass(name, false);
-    }
-
-    @Override
-    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-        Class<?> c = null;
-        // first try the shim
-        if (shimClassLoader != null) {
-            try {
-                c = shimClassLoader.loadClass(name, resolve);
-            } catch (ClassNotFoundException e) {
-                c = null;
-            }
-        }
-        // if it wasn't in the shim try our self
-        if (c == null) {
-            return super.loadClass(name, resolve);
-        } else {
-            return c;
-        }
-    }
-
-    @Override
-    protected Class<?> findClass(String name) throws ClassNotFoundException {
-        Class<?> c = null;
-        // first try the shim
-        if (shimClassLoader != null) {
-            try {
-                c = shimClassLoader.findClass(name);
-            } catch (ClassNotFoundException cnf) {
-                c = null;
-            }
-        }
-        // if it wasn't in the shim try our self
-        if (c == null) {
-            return super.findClass(name);
-        } else {
-            return c;
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (shimClassLoader != null) {
-            try {
-                shimClassLoader.close();
-            } catch (IOException e) {
-                logger.warn("Unable to close inner URLClassLoader for " + identifier);
-            }
-        }
-        super.close();
-    }
-
-    /**
-     * Extend URLClassLoader to increase visibility of protected methods so that InstanceClassLoader can delegate.
-     */
-    private static class ShimClassLoader extends URLClassLoader {
-
-        public ShimClassLoader(URL[] urls, ClassLoader parent) {
-            super(urls, parent);
-        }
-
-        public ShimClassLoader(URL[] urls) {
-            super(urls);
-        }
-
-        @Override
-        public Class<?> findClass(String name) throws ClassNotFoundException {
-            return super.findClass(name);
-        }
-
-        @Override
-        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
-            return super.loadClass(name, resolve);
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java
index a656e76..005a8fa 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarClassLoaders.java
@@ -184,6 +184,7 @@ public final class NarClassLoaders {
                     jettyClassLoader = createNarClassLoader(narDetail.getWorkingDirectory(), systemClassLoader);
 
                     // remove the jetty nar since its already loaded
+                    narDirectoryBundleLookup.put(narDetail.getWorkingDirectory().getCanonicalPath(), new Bundle(narDetail, jettyClassLoader));
                     narCoordinateClassLoaderLookup.put(narDetail.getCoordinate().getCoordinate(), jettyClassLoader);
                     narDetailsIter.remove();
                 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java
deleted file mode 100644
index 88d47ff..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarCloseable.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.nar;
-
-import java.io.Closeable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- */
-public class NarCloseable implements Closeable {
-
-    private static final Logger logger = LoggerFactory.getLogger(NarCloseable.class);
-
-    public static NarCloseable withNarLoader() {
-        final ClassLoader current = Thread.currentThread().getContextClassLoader();
-        Thread.currentThread().setContextClassLoader(NarThreadContextClassLoader.getInstance());
-        return new NarCloseable(current);
-    }
-
-    /**
-     * Sets the current thread context class loader to the specific appropriate class loader for the given
-     * component. If the component requires per-instance class loading then the class loader will be the
-     * specific class loader for instance with the given identifier, otherwise the class loader will be
-     * the NARClassLoader.
-     *
-     * @param componentClass the component class
-     * @param componentIdentifier the identifier of the component
-     * @return NarCloseable with the current thread context classloader jailed to the Nar
-     *              or instance class loader of the component
-     */
-    public static NarCloseable withComponentNarLoader(final Class componentClass, final String componentIdentifier) {
-        final ClassLoader current = Thread.currentThread().getContextClassLoader();
-
-        ClassLoader componentClassLoader = ExtensionManager.getInstanceClassLoader(componentIdentifier);
-        if (componentClassLoader == null) {
-            componentClassLoader = componentClass.getClassLoader();
-        }
-
-        Thread.currentThread().setContextClassLoader(componentClassLoader);
-        return new NarCloseable(current);
-    }
-
-    /**
-     * Sets the current thread context class loader to the provided class loader, and returns a NarCloseable that will
-     * return the current thread context class loader to it's previous state.
-     *
-     * @param componentNarLoader the class loader to set as the current thread context class loader
-     *
-     * @return NarCloseable that will return the current thread context class loader to its previous state
-     */
-    public static NarCloseable withComponentNarLoader(final ClassLoader componentNarLoader) {
-        final ClassLoader current = Thread.currentThread().getContextClassLoader();
-        Thread.currentThread().setContextClassLoader(componentNarLoader);
-        return new NarCloseable(current);
-    }
-
-    /**
-     * Creates a Closeable object that can be used to to switch to current class
-     * loader to the framework class loader and will automatically set the
-     * ClassLoader back to the previous class loader when closed
-     *
-     * @return a NarCloseable
-     */
-    public static NarCloseable withFrameworkNar() {
-        final ClassLoader frameworkClassLoader;
-        try {
-            frameworkClassLoader = NarClassLoaders.getInstance().getFrameworkBundle().getClassLoader();
-        } catch (final Exception e) {
-            // This should never happen in a running instance, but it will occur in unit tests
-            logger.error("Unable to access Framework ClassLoader due to " + e + ". Will continue without changing ClassLoaders.");
-            if (logger.isDebugEnabled()) {
-                logger.error("", e);
-            }
-
-            return new NarCloseable(null);
-        }
-
-        final ClassLoader current = Thread.currentThread().getContextClassLoader();
-        Thread.currentThread().setContextClassLoader(frameworkClassLoader);
-        return new NarCloseable(current);
-    }
-
-    private final ClassLoader toSet;
-
-    private NarCloseable(final ClassLoader toSet) {
-        this.toSet = toSet;
-    }
-
-    @Override
-    public void close() {
-        if (toSet != null) {
-            Thread.currentThread().setContextClassLoader(toSet);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java
index da54c4e..8b02742 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarManifestEntry.java
@@ -32,7 +32,7 @@ public enum NarManifestEntry {
     BUILD_BRANCH("Build-Branch"),
     BUILD_TIMESTAMP("Build-Timestamp"),
     BUILD_JDK("Build-Jdk"),
-    BUILT_BY("Built-By")
+    BUILT_BY("Built-By"),
     ;
 
     final String manifestName;

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java
deleted file mode 100644
index e7faa02..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/NarThreadContextClassLoader.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.nar;
-
-import org.apache.nifi.authentication.LoginIdentityProvider;
-import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.bundle.Bundle;
-import org.apache.nifi.components.Validator;
-import org.apache.nifi.components.state.StateProvider;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.repository.ContentRepository;
-import org.apache.nifi.controller.repository.FlowFileRepository;
-import org.apache.nifi.controller.repository.FlowFileSwapManager;
-import org.apache.nifi.controller.status.history.ComponentStatusRepository;
-import org.apache.nifi.flowfile.FlowFilePrioritizer;
-import org.apache.nifi.processor.Processor;
-import org.apache.nifi.processor.io.InputStreamCallback;
-import org.apache.nifi.processor.io.OutputStreamCallback;
-import org.apache.nifi.processor.io.StreamCallback;
-import org.apache.nifi.provenance.ProvenanceRepository;
-import org.apache.nifi.reporting.ReportingTask;
-import org.apache.nifi.util.NiFiProperties;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-
-/**
- * THREAD SAFE
- */
-public class NarThreadContextClassLoader extends URLClassLoader {
-
-    static final ContextSecurityManager contextSecurityManager = new ContextSecurityManager();
-    private final ClassLoader forward = ClassLoader.getSystemClassLoader();
-    private static final List<Class<?>> narSpecificClasses = new ArrayList<>();
-
-    static {
-        narSpecificClasses.add(Processor.class);
-        narSpecificClasses.add(FlowFilePrioritizer.class);
-        narSpecificClasses.add(ReportingTask.class);
-        narSpecificClasses.add(Validator.class);
-        narSpecificClasses.add(InputStreamCallback.class);
-        narSpecificClasses.add(OutputStreamCallback.class);
-        narSpecificClasses.add(StreamCallback.class);
-        narSpecificClasses.add(ControllerService.class);
-        narSpecificClasses.add(Authorizer.class);
-        narSpecificClasses.add(LoginIdentityProvider.class);
-        narSpecificClasses.add(ProvenanceRepository.class);
-        narSpecificClasses.add(ComponentStatusRepository.class);
-        narSpecificClasses.add(FlowFileRepository.class);
-        narSpecificClasses.add(FlowFileSwapManager.class);
-        narSpecificClasses.add(ContentRepository.class);
-        narSpecificClasses.add(StateProvider.class);
-    }
-
-    private NarThreadContextClassLoader() {
-        super(new URL[0]);
-    }
-
-    @Override
-    public void clearAssertionStatus() {
-        lookupClassLoader().clearAssertionStatus();
-    }
-
-    @Override
-    public URL getResource(String name) {
-        return lookupClassLoader().getResource(name);
-    }
-
-    @Override
-    public InputStream getResourceAsStream(String name) {
-        return lookupClassLoader().getResourceAsStream(name);
-    }
-
-    @Override
-    public Enumeration<URL> getResources(String name) throws IOException {
-        return lookupClassLoader().getResources(name);
-    }
-
-    @Override
-    public Class<?> loadClass(String name) throws ClassNotFoundException {
-        return lookupClassLoader().loadClass(name);
-    }
-
-    @Override
-    public void setClassAssertionStatus(String className, boolean enabled) {
-        lookupClassLoader().setClassAssertionStatus(className, enabled);
-    }
-
-    @Override
-    public void setDefaultAssertionStatus(boolean enabled) {
-        lookupClassLoader().setDefaultAssertionStatus(enabled);
-    }
-
-    @Override
-    public void setPackageAssertionStatus(String packageName, boolean enabled) {
-        lookupClassLoader().setPackageAssertionStatus(packageName, enabled);
-    }
-
-    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 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 class SingletonHolder {
-
-        public static final NarThreadContextClassLoader instance = new NarThreadContextClassLoader();
-    }
-
-    public static NarThreadContextClassLoader getInstance() {
-        return SingletonHolder.instance;
-    }
-
-    static class ContextSecurityManager extends SecurityManager {
-
-        Class<?>[] getExecutionStack() {
-            return getClassContext();
-        }
-    }
-
-    /**
-     * Constructs an instance of the given type using either default no args
-     * constructor or a constructor which takes a NiFiProperties object
-     * (preferred).
-     *
-     * @param <T> the type to create an instance for
-     * @param implementationClassName the implementation class name
-     * @param typeDefinition the type definition
-     * @param nifiProperties the NiFiProperties instance
-     * @return constructed instance
-     * @throws InstantiationException if there is an error instantiating the class
-     * @throws IllegalAccessException if there is an error accessing the type
-     * @throws ClassNotFoundException if the class cannot be found
-     */
-    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 List<Bundle> bundles = ExtensionManager.getBundles(implementationClassName);
-            if (bundles.size() == 0) {
-                throw new IllegalStateException(String.format("The specified implementation class '%s' is not known to this nifi.", implementationClassName));
-            }
-            if (bundles.size() > 1) {
-                throw new IllegalStateException(String.format("More than one bundle was found for the specified implementation class '%s', only one is allowed.", implementationClassName));
-            }
-
-            final Bundle bundle = bundles.get(0);
-            final ClassLoader detectedClassLoaderForType = bundle.getClassLoader();
-            final Class<?> rawClass = Class.forName(implementationClassName, true, detectedClassLoaderForType);
-
-            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);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java
new file mode 100644
index 0000000..0fb2bad
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/main/java/org/apache/nifi/nar/SystemBundle.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.nar;
+
+import org.apache.nifi.bundle.Bundle;
+import org.apache.nifi.bundle.BundleCoordinate;
+import org.apache.nifi.bundle.BundleDetails;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.util.StringUtils;
+
+import java.io.File;
+
+/**
+ * Utility to create the system bundle.
+ */
+public final class SystemBundle {
+
+    public static final BundleCoordinate SYSTEM_BUNDLE_COORDINATE = new BundleCoordinate(
+            BundleCoordinate.DEFAULT_GROUP, "system", BundleCoordinate.DEFAULT_VERSION);
+
+    /**
+     * Returns a bundle representing the system class loader.
+     *
+     * @param niFiProperties a NiFiProperties instance which will be used to obtain the default NAR library path,
+     *                       which will become the working directory of the returned bundle
+     * @return a bundle for the system class loader
+     */
+    public static Bundle create(final NiFiProperties niFiProperties) {
+        final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
+
+        final String narLibraryDirectory = niFiProperties.getProperty(NiFiProperties.NAR_LIBRARY_DIRECTORY);
+        if (StringUtils.isBlank(narLibraryDirectory)) {
+            throw new IllegalStateException("Unable to create system bundle because " + NiFiProperties.NAR_LIBRARY_DIRECTORY + " was null or empty");
+        }
+
+        final BundleDetails systemBundleDetails = new BundleDetails.Builder()
+                .workingDir(new File(narLibraryDirectory))
+                .coordinate(SYSTEM_BUNDLE_COORDINATE)
+                .build();
+
+        return new Bundle(systemBundleDetails, systemClassLoader);
+    }
+}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java
index aa526c6..df6a361 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarBundleUtilTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.nifi.nar;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
 import org.apache.nifi.bundle.BundleCoordinate;
 import org.apache.nifi.bundle.BundleDetails;
 import org.junit.Test;
@@ -26,6 +23,9 @@ import org.junit.Test;
 import java.io.File;
 import java.io.IOException;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
 public class NarBundleUtilTest {
 
     @Test

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java
deleted file mode 100644
index 4528c0a..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarThreadContextClassLoaderTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.nar;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.nifi.bundle.Bundle;
-import org.apache.nifi.processor.AbstractProcessor;
-import org.apache.nifi.processor.ProcessContext;
-import org.apache.nifi.processor.ProcessSession;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.util.NiFiProperties;
-import org.junit.Test;
-
-public class NarThreadContextClassLoaderTest {
-
-    @Test
-    public void validateWithPropertiesConstructor() throws Exception {
-        NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null);
-        Bundle systemBundle = ExtensionManager.createSystemBundle(properties);
-        ExtensionManager.discoverExtensions(systemBundle, Collections.emptySet());
-
-        Object obj = NarThreadContextClassLoader.createInstance(WithPropertiesConstructor.class.getName(),
-                WithPropertiesConstructor.class, properties);
-        assertTrue(obj instanceof WithPropertiesConstructor);
-        WithPropertiesConstructor withPropertiesConstructor = (WithPropertiesConstructor) obj;
-        assertNotNull(withPropertiesConstructor.properties);
-    }
-
-    @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);
-        Bundle systemBundle = ExtensionManager.createSystemBundle(properties);
-        ExtensionManager.discoverExtensions(systemBundle, Collections.emptySet());
-        NarThreadContextClassLoader.createInstance(WithPropertiesConstructor.class.getName(), WithPropertiesConstructor.class, properties);
-    }
-
-    @Test
-    public void validateWithDefaultConstructor() throws Exception {
-        NiFiProperties properties = NiFiProperties.createBasicNiFiProperties("src/test/resources/nifi.properties", null);
-        Bundle systemBundle = ExtensionManager.createSystemBundle(properties);
-        ExtensionManager.discoverExtensions(systemBundle, Collections.emptySet());
-        assertTrue(NarThreadContextClassLoader.createInstance(WithDefaultConstructor.class.getName(),
-                WithDefaultConstructor.class, properties) instanceof WithDefaultConstructor);
-    }
-
-    public static class WithPropertiesConstructor extends AbstractProcessor {
-        private NiFiProperties properties;
-
-        public WithPropertiesConstructor() {
-
-        }
-
-        public WithPropertiesConstructor(NiFiProperties properties) {
-            if (properties.getProperty("fail") != null) {
-                throw new RuntimeException("Intentional failure");
-            }
-            this.properties = properties;
-        }
-
-        @Override
-        public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
-
-        }
-    }
-
-    public static class WithDefaultConstructor extends AbstractProcessor {
-        public WithDefaultConstructor() {
-
-        }
-
-        @Override
-        public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
-
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
deleted file mode 100644
index 8cc2ccd..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/java/org/apache/nifi/nar/NarUnpackerTest.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.nar;
-
-import org.apache.nifi.util.NiFiProperties;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-public class NarUnpackerTest {
-
-    @BeforeClass
-    public static void copyResources() throws IOException {
-
-        final Path sourcePath = Paths.get("./src/test/resources");
-        final Path targetPath = Paths.get("./target");
-
-        Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
-
-            @Override
-            public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
-                    throws IOException {
-
-                Path relativeSource = sourcePath.relativize(dir);
-                Path target = targetPath.resolve(relativeSource);
-
-                Files.createDirectories(target);
-
-                return FileVisitResult.CONTINUE;
-
-            }
-
-            @Override
-            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
-                    throws IOException {
-
-                Path relativeSource = sourcePath.relativize(file);
-                Path target = targetPath.resolve(relativeSource);
-
-                Files.copy(file, target, REPLACE_EXISTING);
-
-                return FileVisitResult.CONTINUE;
-            }
-        });
-    }
-
-    @Test
-    public void testUnpackNars() {
-
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", Collections.EMPTY_MAP);
-
-        assertEquals("./target/NarUnpacker/lib/",
-                properties.getProperty("nifi.nar.library.directory"));
-        assertEquals("./target/NarUnpacker/lib2/",
-                properties.getProperty("nifi.nar.library.directory.alt"));
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties));
-
-        assertEquals(2, extensionMapping.getAllExtensionNames().size());
-
-        assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.one"));
-        assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.two"));
-        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
-        File[] extensionFiles = extensionsWorkingDir.listFiles();
-
-        Set<String> expectedNars = new HashSet<>();
-        expectedNars.add("dummy-one.nar-unpacked");
-        expectedNars.add("dummy-two.nar-unpacked");
-        assertEquals(expectedNars.size(), extensionFiles.length);
-
-        for (File extensionFile : extensionFiles) {
-            Assert.assertTrue(expectedNars.contains(extensionFile.getName()));
-        }
-    }
-
-    @Test
-    public void testUnpackNarsFromEmptyDir() throws IOException {
-
-        final File emptyDir = new File("./target/empty/dir");
-        emptyDir.delete();
-        emptyDir.deleteOnExit();
-        assertTrue(emptyDir.mkdirs());
-
-        final Map<String, String> others = new HashMap<>();
-        others.put("nifi.nar.library.directory.alt", emptyDir.toString());
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others);
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties));
-
-        assertEquals(1, extensionMapping.getAllExtensionNames().size());
-        assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.one"));
-
-        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
-        File[] extensionFiles = extensionsWorkingDir.listFiles();
-
-        assertEquals(1, extensionFiles.length);
-        assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
-    }
-
-    @Test
-    public void testUnpackNarsFromNonExistantDir() {
-
-        final File nonExistantDir = new File("./target/this/dir/should/not/exist/");
-        nonExistantDir.delete();
-        nonExistantDir.deleteOnExit();
-
-        final Map<String, String> others = new HashMap<>();
-        others.put("nifi.nar.library.directory.alt", nonExistantDir.toString());
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others);
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties));
-
-        assertTrue(extensionMapping.getAllExtensionNames().keySet().contains("org.apache.nifi.processors.dummy.one"));
-
-        assertEquals(1, extensionMapping.getAllExtensionNames().size());
-
-        final File extensionsWorkingDir = properties.getExtensionsWorkingDirectory();
-        File[] extensionFiles = extensionsWorkingDir.listFiles();
-
-        assertEquals(1, extensionFiles.length);
-        assertEquals("dummy-one.nar-unpacked", extensionFiles[0].getName());
-    }
-
-    @Test
-    public void testUnpackNarsFromNonDir() throws IOException {
-
-        final File nonDir = new File("./target/file.txt");
-        nonDir.createNewFile();
-        nonDir.deleteOnExit();
-
-        final Map<String, String> others = new HashMap<>();
-        others.put("nifi.nar.library.directory.alt", nonDir.toString());
-        NiFiProperties properties = loadSpecifiedProperties("/NarUnpacker/conf/nifi.properties", others);
-
-        final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, ExtensionManager.createSystemBundle(properties));
-
-        assertNull(extensionMapping);
-    }
-
-    private NiFiProperties loadSpecifiedProperties(final String propertiesFile, final Map<String, String> others) {
-        String filePath;
-        try {
-            filePath = NarUnpackerTest.class.getResource(propertiesFile).toURI().getPath();
-        } catch (URISyntaxException ex) {
-            throw new RuntimeException("Cannot load properties file due to " + ex.getLocalizedMessage(), ex);
-        }
-        return NiFiProperties.createBasicNiFiProperties(filePath, others);
-    }
-}

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor
deleted file mode 100644
index 9d180b6..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/META-INF/services/org.apache.nifi.processor.Processor
+++ /dev/null
@@ -1,16 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-org.apache.nifi.nar.NarThreadContextClassLoaderTest$WithPropertiesConstructor
-org.apache.nifi.nar.NarThreadContextClassLoaderTest$WithDefaultConstructor

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties
deleted file mode 100644
index 0559752..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/conf/nifi.properties
+++ /dev/null
@@ -1,124 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Core Properties #
-nifi.flow.configuration.file=./target/flow.xml.gz
-nifi.flow.configuration.archive.dir=./target/archive/
-nifi.flowcontroller.autoResumeState=true
-nifi.flowcontroller.graceful.shutdown.period=10 sec
-nifi.flowservice.writedelay.interval=2 sec
-nifi.administrative.yield.duration=30 sec
-
-nifi.reporting.task.configuration.file=./target/reporting-tasks.xml
-nifi.controller.service.configuration.file=./target/controller-services.xml
-nifi.templates.directory=./target/templates
-nifi.ui.banner.text=UI Banner Text
-nifi.ui.autorefresh.interval=30 sec
-nifi.nar.library.directory=./target/NarUnpacker/lib/
-nifi.nar.library.directory.alt=./target/NarUnpacker/lib2/
-
-nifi.nar.working.directory=./target/work/nar/
-
-# H2 Settings
-nifi.database.directory=./target/database_repository
-nifi.h2.url.append=;LOCK_TIMEOUT=25000;WRITE_DELAY=0;AUTO_SERVER=FALSE
-
-# FlowFile Repository
-nifi.flowfile.repository.directory=./target/test-repo
-nifi.flowfile.repository.partitions=1
-nifi.flowfile.repository.checkpoint.interval=2 mins
-nifi.queue.swap.threshold=20000
-nifi.swap.storage.directory=./target/test-repo/swap
-nifi.swap.in.period=5 sec
-nifi.swap.in.threads=1
-nifi.swap.out.period=5 sec
-nifi.swap.out.threads=4
-
-# Content Repository
-nifi.content.claim.max.appendable.size=10 MB
-nifi.content.claim.max.flow.files=100
-nifi.content.repository.directory.default=./target/content_repository
-
-# Provenance Repository Properties
-nifi.provenance.repository.storage.directory=./target/provenance_repository
-nifi.provenance.repository.max.storage.time=24 hours
-nifi.provenance.repository.max.storage.size=1 GB
-nifi.provenance.repository.rollover.time=30 secs
-nifi.provenance.repository.rollover.size=100 MB
-
-# Site to Site properties
-nifi.remote.input.socket.port=9990
-nifi.remote.input.secure=true
-
-# web properties #
-nifi.web.war.directory=./target/lib
-nifi.web.http.host=
-nifi.web.http.port=8080
-nifi.web.https.host=
-nifi.web.https.port=
-nifi.web.jetty.working.directory=./target/work/jetty
-
-# security properties #
-nifi.sensitive.props.key=key
-nifi.sensitive.props.algorithm=PBEWITHMD5AND256BITAES-CBC-OPENSSL
-nifi.sensitive.props.provider=BC
-
-nifi.security.keystore=
-nifi.security.keystoreType=
-nifi.security.keystorePasswd=
-nifi.security.keyPasswd=
-nifi.security.truststore=
-nifi.security.truststoreType=
-nifi.security.truststorePasswd=
-nifi.security.needClientAuth=
-nifi.security.user.authorizer=
-
-# cluster common properties (cluster manager and nodes must have same values) #
-nifi.cluster.protocol.heartbeat.interval=5 sec
-nifi.cluster.protocol.is.secure=false
-nifi.cluster.protocol.socket.timeout=30 sec
-nifi.cluster.protocol.connection.handshake.timeout=45 sec
-# if multicast is used, then nifi.cluster.protocol.multicast.xxx properties must be configured #
-nifi.cluster.protocol.use.multicast=false
-nifi.cluster.protocol.multicast.address=
-nifi.cluster.protocol.multicast.port=
-nifi.cluster.protocol.multicast.service.broadcast.delay=500 ms
-nifi.cluster.protocol.multicast.service.locator.attempts=3
-nifi.cluster.protocol.multicast.service.locator.attempts.delay=1 sec
-
-# cluster node properties (only configure for cluster nodes) #
-nifi.cluster.is.node=false
-nifi.cluster.node.address=
-nifi.cluster.node.protocol.port=
-nifi.cluster.node.protocol.threads=2
-# if multicast is not used, nifi.cluster.node.unicast.xxx must have same values as nifi.cluster.manager.xxx #
-nifi.cluster.node.unicast.manager.address=
-nifi.cluster.node.unicast.manager.protocol.port=
-nifi.cluster.node.unicast.manager.authority.provider.port=
-
-# cluster manager properties (only configure for cluster manager) #
-nifi.cluster.is.manager=false
-nifi.cluster.manager.address=
-nifi.cluster.manager.protocol.port=
-nifi.cluster.manager.authority.provider.port=
-nifi.cluster.manager.authority.provider.threads=10
-nifi.cluster.manager.node.firewall.file=
-nifi.cluster.manager.node.event.history.size=10
-nifi.cluster.manager.node.api.connection.timeout=30 sec
-nifi.cluster.manager.node.api.read.timeout=30 sec
-nifi.cluster.manager.node.api.request.threads=10
-nifi.cluster.manager.flow.retrieval.delay=5 sec
-nifi.cluster.manager.protocol.threads=10
-nifi.cluster.manager.safemode.duration=0 sec

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar
deleted file mode 100644
index 598b27f..0000000
Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/dummy-one.nar and /dev/null differ

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar
deleted file mode 100644
index d2a8b96..0000000
Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib/nifi-framework-nar.nar and /dev/null differ

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar
deleted file mode 100644
index a1021ba..0000000
Binary files a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-nar-utils/src/test/resources/NarUnpacker/lib2/dummy-two.nar and /dev/null differ

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
index 44ec7ea..f97cc69 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/pom.xml
@@ -44,11 +44,6 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.nifi</groupId>
-            <artifactId>nifi-documentation</artifactId>
-            <scope>compile</scope>
-        </dependency>
-        <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>jul-to-slf4j</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java
index 32cbeba..902b088 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFi.java
@@ -17,11 +17,10 @@
 package org.apache.nifi;
 
 import org.apache.nifi.bundle.Bundle;
-import org.apache.nifi.documentation.DocGenerator;
-import org.apache.nifi.nar.ExtensionManager;
 import org.apache.nifi.nar.ExtensionMapping;
 import org.apache.nifi.nar.NarClassLoaders;
 import org.apache.nifi.nar.NarUnpacker;
+import org.apache.nifi.nar.SystemBundle;
 import org.apache.nifi.util.FileUtils;
 import org.apache.nifi.util.NiFiProperties;
 import org.slf4j.Logger;
@@ -126,7 +125,7 @@ public class NiFi {
         SLF4JBridgeHandler.removeHandlersForRootLogger();
         SLF4JBridgeHandler.install();
 
-        final Bundle systemBundle = ExtensionManager.createSystemBundle(properties);
+        final Bundle systemBundle = SystemBundle.create(properties);
 
         // expand the nars
         final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, systemBundle);
@@ -140,12 +139,7 @@ public class NiFi {
             throw new IllegalStateException("Unable to find the framework NAR ClassLoader.");
         }
 
-        // discover the extensions
         final Set<Bundle> narBundles = NarClassLoaders.getInstance().getBundles();
-        ExtensionManager.discoverExtensions(systemBundle, narBundles);
-        ExtensionManager.logClassLoaderMapping();
-
-        DocGenerator.generate(properties, extensionMapping);
 
         // load the server from the framework classloader
         Thread.currentThread().setContextClassLoader(frameworkClassLoader);
@@ -155,6 +149,7 @@ public class NiFi {
         final long startTime = System.nanoTime();
         nifiServer = (NiFiServer) jettyConstructor.newInstance(properties, narBundles);
         nifiServer.setExtensionMapping(extensionMapping);
+        nifiServer.setBundles(systemBundle, narBundles);
 
         if (shutdown) {
             LOGGER.info("NiFi has been shutdown via NiFi Bootstrap. Will not start Controller");

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java
index 952a926..edb8f45 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-runtime/src/main/java/org/apache/nifi/NiFiServer.java
@@ -16,8 +16,11 @@
  */
 package org.apache.nifi;
 
+import org.apache.nifi.bundle.Bundle;
 import org.apache.nifi.nar.ExtensionMapping;
 
+import java.util.Set;
+
 /**
  *
  */
@@ -27,5 +30,7 @@ public interface NiFiServer {
 
     void setExtensionMapping(ExtensionMapping extensionMapping);
 
+    void setBundles(Bundle systemBundle, Set<Bundle> bundles);
+
     void stop();
 }

http://git-wip-us.apache.org/repos/asf/nifi/blob/556f309d/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
index 90db844..cf75ddf 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
@@ -35,6 +35,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.nifi</groupId>
+            <artifactId>nifi-documentation</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.nifi</groupId>
             <artifactId>nifi-nar-utils</artifactId>
             <scope>compile</scope>
         </dependency>


Mime
View raw message