This is an automated email from the ASF dual-hosted git repository.

mcgilman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git


The following commit(s) were added to refs/heads/master by this push:
     new c30245f  NIFIREG-356 Fixing additional classpath resources for 
Authorizers and ensuring proper context ClassLoader is set
c30245f is described below

commit c30245f47d2e10fb34baaa13ded64f13fd553ea6
Author: Bryan Bende <bbe...@apache.org>
AuthorDate: Fri Jan 31 13:29:55 2020 -0500

    NIFIREG-356 Fixing additional classpath resources for Authorizers and 
ensuring proper context ClassLoader is set
    
    This closes #256
---
 .../registry/extension/ExtensionClassLoader.java   |  37 +++++
 .../registry/extension/ExtensionCloseable.java     |   7 +
 .../nifi/registry/extension/ExtensionManager.java  |  19 +--
 .../security/authorization/AuthorizerFactory.java  | 152 ++++++++++++++-------
 .../registry/security/util/ClassLoaderUtils.java   | 138 +++++++++++++++++++
 .../authorization/AuthorizerFactorySpec.groovy     |   3 +-
 .../provider/TestStandardProviderFactory.java      |  14 +-
 .../provider/hook/TestScriptEventHookProvider.java |   6 +-
 8 files changed, 305 insertions(+), 71 deletions(-)

diff --git 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionClassLoader.java
 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionClassLoader.java
new file mode 100644
index 0000000..1411f29
--- /dev/null
+++ 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionClassLoader.java
@@ -0,0 +1,37 @@
+/*
+ * 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.registry.extension;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+
+/**
+ * Extend URLClassLoader to keep track of the root directory.
+ */
+public class ExtensionClassLoader extends URLClassLoader {
+
+    private final String rootDir;
+
+    public ExtensionClassLoader(final String rootDir, final URL[] urls, final 
ClassLoader parent) {
+        super(urls, parent);
+        this.rootDir = rootDir;
+    }
+
+    public String getRootDir() {
+        return rootDir;
+    }
+}
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
index b24f950..0735f2c 100644
--- 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
+++ 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionCloseable.java
@@ -40,6 +40,13 @@ public class ExtensionCloseable implements Closeable {
         return closeable;
     }
 
+    public static ExtensionCloseable withClassLoader(final ClassLoader 
componentClassLoader) {
+        final ClassLoader current = 
Thread.currentThread().getContextClassLoader();
+        final ExtensionCloseable closeable = new ExtensionCloseable(current);
+        Thread.currentThread().setContextClassLoader(componentClassLoader);
+        return closeable;
+    }
+
     @Override
     public void close() throws IOException {
         if (toSet != null) {
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionManager.java
 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionManager.java
index 455c833..edb3350 100644
--- 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionManager.java
+++ 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/extension/ExtensionManager.java
@@ -33,7 +33,6 @@ import javax.annotation.PostConstruct;
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -88,7 +87,7 @@ public class ExtensionManager {
         }
     }
 
-    public ClassLoader getExtensionClassLoader(final String 
canonicalClassName) {
+    public ExtensionClassLoader getExtensionClassLoader(final String 
canonicalClassName) {
         if (StringUtils.isBlank(canonicalClassName)) {
             throw new IllegalArgumentException("Class name can not be null");
         }
@@ -199,20 +198,4 @@ public class ExtensionManager {
         return new ExtensionClassLoader(dir, urls, parentClassLoader);
     }
 
-    /**
-     * Extend URLClassLoader to keep track of the root directory.
-     */
-    private static class ExtensionClassLoader extends URLClassLoader {
-
-        private final String rootDir;
-
-        public ExtensionClassLoader(final String rootDir, final URL[] urls, 
final ClassLoader parent) {
-            super(urls, parent);
-            this.rootDir = rootDir;
-        }
-
-        public String getRootDir() {
-            return rootDir;
-        }
-    }
 }
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerFactory.java
 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerFactory.java
index a819e97..959e29e 100644
--- 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerFactory.java
+++ 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/authorization/AuthorizerFactory.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.registry.security.authorization;
 
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.registry.extension.ExtensionClassLoader;
 import org.apache.nifi.registry.extension.ExtensionCloseable;
 import org.apache.nifi.registry.extension.ExtensionManager;
 import org.apache.nifi.registry.properties.NiFiRegistryProperties;
@@ -30,6 +31,7 @@ import 
org.apache.nifi.registry.security.authorization.generated.Authorizers;
 import org.apache.nifi.registry.security.authorization.generated.Prop;
 import 
org.apache.nifi.registry.security.exception.SecurityProviderCreationException;
 import 
org.apache.nifi.registry.security.exception.SecurityProviderDestructionException;
+import org.apache.nifi.registry.security.util.ClassLoaderUtils;
 import org.apache.nifi.registry.security.util.XmlUtils;
 import org.apache.nifi.registry.service.RegistryService;
 import org.slf4j.Logger;
@@ -55,7 +57,11 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -201,11 +207,12 @@ public class AuthorizerFactory implements 
UserGroupProviderLookup, AccessPolicyP
 
                         // configure each authorizer
                         for (final 
org.apache.nifi.registry.security.authorization.generated.Authorizer provider : 
authorizerConfiguration.getAuthorizer()) {
+                            if 
(provider.getIdentifier().equals(authorizerIdentifier)) {
+                                continue;
+                            }
                             final Authorizer instance = 
authorizers.get(provider.getIdentifier());
-                            final Class authorizerClass = instance instanceof 
WrappedAuthorizer
-                                    ? ((WrappedAuthorizer) 
instance).getBaseAuthorizer().getClass()
-                                    : instance.getClass();
-                            try (ExtensionCloseable extCloseable = 
ExtensionCloseable.withComponentClassLoader(extensionManager, authorizerClass)) 
{
+                            final ClassLoader instanceClassLoader = 
instance.getClass().getClassLoader();
+                            try (final ExtensionCloseable extClosable = 
ExtensionCloseable.withClassLoader(instanceClassLoader)) {
                                 
instance.onConfigured(loadAuthorizerConfiguration(provider.getIdentifier(), 
provider.getProperty()));
                             }
                         }
@@ -216,7 +223,37 @@ public class AuthorizerFactory implements 
UserGroupProviderLookup, AccessPolicyP
                         // ensure it was found
                         if (authorizer == null) {
                             throw new 
AuthorizerFactoryException(String.format("The specified authorizer '%s' could 
not be found.", authorizerIdentifier));
+                        } else {
+                            // get the ClassLoader of the Authorizer before 
wrapping it with anything
+                            final ClassLoader authorizerClassLoader = 
authorizer.getClass().getClassLoader();
+
+                            // install integrity checks
+                            authorizer = 
AuthorizerFactory.installIntegrityChecks(authorizer);
+
+                            // load the configuration context for the selected 
authorizer
+                            AuthorizerConfigurationContext 
authorizerConfigurationContext = null;
+                            for (final 
org.apache.nifi.registry.security.authorization.generated.Authorizer provider : 
authorizerConfiguration.getAuthorizer()) {
+                                if 
(provider.getIdentifier().equals(authorizerIdentifier)) {
+                                    authorizerConfigurationContext = 
loadAuthorizerConfiguration(provider.getIdentifier(), provider.getProperty());
+                                    break;
+                                }
+                            }
+
+                            if (authorizerConfigurationContext == null) {
+                                throw new IllegalStateException("Unable to 
load configuration for authorizer with id: " + authorizerIdentifier);
+                            }
+
+                            // configure the authorizer that is wrapped with 
integrity checks
+                            // set the context ClassLoader the wrapped 
authorizer's ClassLoader
+                            try (final ExtensionCloseable extClosable = 
ExtensionCloseable.withClassLoader(authorizerClassLoader)) {
+                                
authorizer.onConfigured(authorizerConfigurationContext);
+                            }
+
+                            // wrap the integrity checked Authorizer with the 
FrameworkAuthorizer
+                            authorizer = createFrameworkAuthorizer(authorizer);
                         }
+
+
                     } catch (AuthorizerFactoryException e) {
                         throw e;
                     } catch (Exception e) {
@@ -281,7 +318,6 @@ public class AuthorizerFactory implements 
UserGroupProviderLookup, AccessPolicyP
     }
 
     private UserGroupProvider createUserGroupProvider(final String identifier, 
final String userGroupProviderClassName) throws Exception {
-
         final UserGroupProvider instance;
 
         final ClassLoader classLoader = 
extensionManager.getExtensionClassLoader(userGroupProviderClassName);
@@ -289,22 +325,24 @@ public class AuthorizerFactory implements 
UserGroupProviderLookup, AccessPolicyP
             throw new IllegalStateException("Extension not found in any of the 
configured class loaders: " + userGroupProviderClassName);
         }
 
-        // attempt to load the class
-        Class<?> rawUserGroupProviderClass = 
Class.forName(userGroupProviderClassName, true, classLoader);
-        Class<? extends UserGroupProvider> userGroupProviderClass = 
rawUserGroupProviderClass.asSubclass(UserGroupProvider.class);
+        try (final ExtensionCloseable closeable = 
ExtensionCloseable.withClassLoader(classLoader)) {
+            // attempt to load the class
+            Class<?> rawUserGroupProviderClass = 
Class.forName(userGroupProviderClassName, true, classLoader);
+            Class<? extends UserGroupProvider> userGroupProviderClass = 
rawUserGroupProviderClass.asSubclass(UserGroupProvider.class);
 
-        // otherwise create a new instance
-        Constructor constructor = userGroupProviderClass.getConstructor();
-        instance = (UserGroupProvider) constructor.newInstance();
+            // otherwise create a new instance
+            Constructor constructor = userGroupProviderClass.getConstructor();
+            instance = (UserGroupProvider) constructor.newInstance();
 
-        // method injection
-        performMethodInjection(instance, userGroupProviderClass);
+            // method injection
+            performMethodInjection(instance, userGroupProviderClass);
 
-        // field injection
-        performFieldInjection(instance, userGroupProviderClass);
+            // field injection
+            performFieldInjection(instance, userGroupProviderClass);
 
-        // call post construction lifecycle event
-        instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this, this, this));
+            // call post construction lifecycle event
+            instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this, this, this));
+        }
 
         return instance;
     }
@@ -317,22 +355,24 @@ public class AuthorizerFactory implements 
UserGroupProviderLookup, AccessPolicyP
             throw new IllegalStateException("Extension not found in any of the 
configured class loaders: " + accessPolicyProviderClassName);
         }
 
-        // attempt to load the class
-        Class<?> rawAccessPolicyProviderClass = 
Class.forName(accessPolicyProviderClassName, true, classLoader);
-        Class<? extends AccessPolicyProvider> accessPolicyClass = 
rawAccessPolicyProviderClass.asSubclass(AccessPolicyProvider.class);
+        try (final ExtensionCloseable closeable = 
ExtensionCloseable.withClassLoader(classLoader)) {
+            // attempt to load the class
+            Class<?> rawAccessPolicyProviderClass = 
Class.forName(accessPolicyProviderClassName, true, classLoader);
+            Class<? extends AccessPolicyProvider> accessPolicyClass = 
rawAccessPolicyProviderClass.asSubclass(AccessPolicyProvider.class);
 
-        // otherwise create a new instance
-        Constructor constructor = accessPolicyClass.getConstructor();
-        instance = (AccessPolicyProvider) constructor.newInstance();
+            // otherwise create a new instance
+            Constructor constructor = accessPolicyClass.getConstructor();
+            instance = (AccessPolicyProvider) constructor.newInstance();
 
-        // method injection
-        performMethodInjection(instance, accessPolicyClass);
+            // method injection
+            performMethodInjection(instance, accessPolicyClass);
 
-        // field injection
-        performFieldInjection(instance, accessPolicyClass);
+            // field injection
+            performFieldInjection(instance, accessPolicyClass);
 
-        // call post construction lifecycle event
-        instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this, this, this));
+            // call post construction lifecycle event
+            instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this, this, this));
+        }
 
         return instance;
     }
@@ -340,33 +380,51 @@ public class AuthorizerFactory implements 
UserGroupProviderLookup, AccessPolicyP
     private Authorizer createAuthorizer(final String identifier, final String 
authorizerClassName, final String classpathResources) throws Exception {
         final Authorizer instance;
 
-        final ClassLoader classLoader = 
extensionManager.getExtensionClassLoader(authorizerClassName);
-        if (classLoader == null) {
+        ClassLoader classLoader;
+
+        final ExtensionClassLoader extensionClassLoader = 
extensionManager.getExtensionClassLoader(authorizerClassName);
+        if (extensionClassLoader == null) {
             throw new IllegalStateException("Extension not found in any of the 
configured class loaders: " + authorizerClassName);
         }
 
-        // attempt to load the class
-        Class<?> rawAuthorizerClass = Class.forName(authorizerClassName, true, 
classLoader);
-        Class<? extends Authorizer> authorizerClass = 
rawAuthorizerClass.asSubclass(Authorizer.class);
+        // if additional classpath resources were specified, replace with a 
new ClassLoader that contains
+        // the combined resources of the original ClassLoader + the additional 
resources
+        if (StringUtils.isNotEmpty(classpathResources)) {
+            logger.info(String.format("Replacing Authorizer ClassLoader for 
'%s' to include additional resources: %s", identifier, classpathResources));
+            final URL[] originalUrls = extensionClassLoader.getURLs();
+            final URL[] additionalUrls = 
ClassLoaderUtils.getURLsForClasspath(classpathResources, null, true);
 
-        // otherwise create a new instance
-        Constructor constructor = authorizerClass.getConstructor();
-        instance = (Authorizer) constructor.newInstance();
+            final Set<URL> combinedUrls = new HashSet<>();
+            combinedUrls.addAll(Arrays.asList(originalUrls));
+            combinedUrls.addAll(Arrays.asList(additionalUrls));
 
-        // method injection
-        performMethodInjection(instance, authorizerClass);
+            final URL[] urls = combinedUrls.toArray(new 
URL[combinedUrls.size()]);
+            classLoader = new URLClassLoader(urls, 
extensionClassLoader.getParent());
+        } else {
+            // no additional resources so just use the ExtensionClassLoader
+            classLoader = extensionClassLoader;
+        }
+
+        try (final ExtensionCloseable closeable = 
ExtensionCloseable.withClassLoader(classLoader)) {
+            // attempt to load the class
+            Class<?> rawAuthorizerClass = Class.forName(authorizerClassName, 
true, classLoader);
+            Class<? extends Authorizer> authorizerClass = 
rawAuthorizerClass.asSubclass(Authorizer.class);
 
-        // field injection
-        performFieldInjection(instance, authorizerClass);
+            // otherwise create a new instance
+            Constructor constructor = authorizerClass.getConstructor();
+            instance = (Authorizer) constructor.newInstance();
 
-        // call post construction lifecycle event
-        instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this, this, this));
+            // method injection
+            performMethodInjection(instance, authorizerClass);
 
-        // wrap the instance Authorizer with checks to ensure integrity of data
-        final Authorizer integrityCheckAuthorizer = 
installIntegrityChecks(instance);
+            // field injection
+            performFieldInjection(instance, authorizerClass);
 
-        // wrap the integrity checked Authorizer with the FrameworkAuthorizer
-        return createFrameworkAuthorizer(integrityCheckAuthorizer);
+            // call post construction lifecycle event
+            instance.initialize(new 
StandardAuthorizerInitializationContext(identifier, this, this, this));
+        }
+
+        return instance;
     }
 
     private Authorizer createFrameworkAuthorizer(final Authorizer 
baseAuthorizer) {
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/util/ClassLoaderUtils.java
 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/util/ClassLoaderUtils.java
new file mode 100644
index 0000000..1f05cd3
--- /dev/null
+++ 
b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/security/util/ClassLoaderUtils.java
@@ -0,0 +1,138 @@
+/*
+ * 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.registry.security.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+public class ClassLoaderUtils {
+
+    static final Logger LOGGER = 
LoggerFactory.getLogger(ClassLoaderUtils.class);
+
+    public static ClassLoader getCustomClassLoader(String modulePath, 
ClassLoader parentClassLoader, FilenameFilter filenameFilter) throws 
MalformedURLException {
+        URL[] classpaths = getURLsForClasspath(modulePath, filenameFilter, 
false);
+        return createModuleClassLoader(classpaths, parentClassLoader);
+    }
+
+    /**
+     *
+     * @param modulePath a module path to get URLs from, the module path may be
+     * a comma-separated list of paths
+     * @param filenameFilter a filter to apply when a module path is a 
directory
+     * and performs a listing, a null filter will return all matches
+     * @param suppressExceptions indicates whether to suppress exceptions
+     * @return an array of URL instances representing all of the modules
+     * resolved from processing modulePath
+     * @throws MalformedURLException if a module path does not exist
+     */
+    public static URL[] getURLsForClasspath(String modulePath, FilenameFilter 
filenameFilter, boolean suppressExceptions) throws MalformedURLException {
+        return getURLsForClasspath(modulePath == null ? Collections.emptySet() 
: Collections.singleton(modulePath), filenameFilter, suppressExceptions);
+    }
+
+    /**
+     *
+     * @param modulePaths one or modules paths to get URLs from, each module
+     * path may be a comma-separated list of paths
+     * @param filenameFilter a filter to apply when a module path is a 
directory
+     * and performs a listing, a null filter will return all matches
+     * @param suppressExceptions if true then all modules will attempt to be
+     * resolved even if some throw an exception, if false the first exception
+     * will be thrown
+     * @return an array of URL instances representing all of the modules
+     * resolved from processing modulePaths
+     * @throws MalformedURLException if a module path does not exist
+     */
+    public static URL[] getURLsForClasspath(Set<String> modulePaths, 
FilenameFilter filenameFilter, boolean suppressExceptions) throws 
MalformedURLException {
+        // use LinkedHashSet to maintain the ordering that the incoming paths 
are processed
+        Set<String> modules = new LinkedHashSet<>();
+        if (modulePaths != null) {
+            modulePaths.stream()
+                    .flatMap(path -> Arrays.stream(path.split(",")))
+                    .filter(path -> isNotBlank(path))
+                    .map(String::trim)
+                    .forEach(m -> modules.add(m));
+        }
+        return toURLs(modules, filenameFilter, suppressExceptions);
+    }
+
+    private static boolean isNotBlank(final String value) {
+        return value != null && !value.trim().isEmpty();
+    }
+
+    protected static URL[] toURLs(Set<String> modulePaths, FilenameFilter 
filenameFilter, boolean suppressExceptions) throws MalformedURLException {
+        List<URL> additionalClasspath = new LinkedList<>();
+        if (modulePaths != null) {
+            for (String modulePathString : modulePaths) {
+                // If the path is already a URL, just add it (but don't check 
if it exists, too expensive and subject to network availability)
+                boolean isUrl = true;
+                try {
+                    additionalClasspath.add(new URL(modulePathString));
+                } catch (MalformedURLException mue) {
+                    isUrl = false;
+                }
+                if (!isUrl) {
+                    try {
+                        File modulePath = new File(modulePathString);
+
+                        if (modulePath.exists()) {
+
+                            
additionalClasspath.add(modulePath.toURI().toURL());
+
+                            if (modulePath.isDirectory()) {
+                                File[] files = 
modulePath.listFiles(filenameFilter);
+
+                                if (files != null) {
+                                    for (File classpathResource : files) {
+                                        if (classpathResource.isDirectory()) {
+                                            LOGGER.warn("Recursive directories 
are not supported, skipping " + classpathResource.getAbsolutePath());
+                                        } else {
+                                            
additionalClasspath.add(classpathResource.toURI().toURL());
+                                        }
+                                    }
+                                }
+                            }
+                        } else {
+                            throw new MalformedURLException("Path specified 
does not exist");
+                        }
+                    } catch (MalformedURLException e) {
+                        if (!suppressExceptions) {
+                            throw e;
+                        }
+                    }
+                }
+            }
+        }
+        return additionalClasspath.toArray(new 
URL[additionalClasspath.size()]);
+    }
+
+    protected static ClassLoader createModuleClassLoader(URL[] modules, 
ClassLoader parentClassLoader) {
+        return new URLClassLoader(modules, parentClassLoader);
+    }
+
+}
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/test/groovy/org/apache/nifi/registry/security/authorization/AuthorizerFactorySpec.groovy
 
b/nifi-registry-core/nifi-registry-framework/src/test/groovy/org/apache/nifi/registry/security/authorization/AuthorizerFactorySpec.groovy
index 34dfe6b..bd79e55 100644
--- 
a/nifi-registry-core/nifi-registry-framework/src/test/groovy/org/apache/nifi/registry/security/authorization/AuthorizerFactorySpec.groovy
+++ 
b/nifi-registry-core/nifi-registry-framework/src/test/groovy/org/apache/nifi/registry/security/authorization/AuthorizerFactorySpec.groovy
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.registry.security.authorization
 
+import org.apache.nifi.registry.extension.ExtensionClassLoader
 import org.apache.nifi.registry.extension.ExtensionManager
 import org.apache.nifi.registry.properties.NiFiRegistryProperties
 import org.apache.nifi.registry.security.authorization.resource.ResourceFactory
@@ -32,7 +33,7 @@ class AuthorizerFactorySpec extends Specification {
 
     // runs before every feature method
     def setup() {
-        mockExtensionManager.getExtensionClassLoader(_) >> 
this.getClass().getClassLoader()
+        mockExtensionManager.getExtensionClassLoader(_) >> new 
ExtensionClassLoader("/tmp", new URL[0],this.getClass().getClassLoader())
         mockProperties.getPropertyKeys() >> new HashSet<String>() // Called by 
IdentityMappingUtil.getIdentityMappings()
 
         authorizerFactory = new AuthorizerFactory(mockProperties, 
mockExtensionManager, null, mockRegistryService)
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java
 
b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java
index 0d23110..7fb8dee 100644
--- 
a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java
+++ 
b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java
@@ -17,6 +17,7 @@
 package org.apache.nifi.registry.provider;
 
 import org.apache.nifi.registry.extension.BundlePersistenceProvider;
+import org.apache.nifi.registry.extension.ExtensionClassLoader;
 import org.apache.nifi.registry.extension.ExtensionManager;
 import org.apache.nifi.registry.flow.FlowPersistenceProvider;
 import org.apache.nifi.registry.properties.NiFiRegistryProperties;
@@ -24,6 +25,7 @@ import org.junit.Test;
 import org.mockito.Mockito;
 
 import javax.sql.DataSource;
+import java.net.URL;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -38,7 +40,8 @@ public class TestStandardProviderFactory {
         props.setProperty(NiFiRegistryProperties.PROVIDERS_CONFIGURATION_FILE, 
"src/test/resources/provider/providers-good.xml");
 
         final ExtensionManager extensionManager = 
Mockito.mock(ExtensionManager.class);
-        
when(extensionManager.getExtensionClassLoader(any(String.class))).thenReturn(this.getClass().getClassLoader());
+        when(extensionManager.getExtensionClassLoader(any(String.class)))
+                .thenReturn(new ExtensionClassLoader("/tmp", new 
URL[0],this.getClass().getClassLoader()));
 
         final DataSource dataSource = Mockito.mock(DataSource.class);
 
@@ -68,7 +71,8 @@ public class TestStandardProviderFactory {
         props.setProperty(NiFiRegistryProperties.PROVIDERS_CONFIGURATION_FILE, 
"src/test/resources/provider/providers-good.xml");
 
         final ExtensionManager extensionManager = 
Mockito.mock(ExtensionManager.class);
-        
when(extensionManager.getExtensionClassLoader(any(String.class))).thenReturn(this.getClass().getClassLoader());
+        when(extensionManager.getExtensionClassLoader(any(String.class)))
+                .thenReturn(new ExtensionClassLoader("/tmp", new 
URL[0],this.getClass().getClassLoader()));
 
         final DataSource dataSource = Mockito.mock(DataSource.class);
 
@@ -82,7 +86,8 @@ public class TestStandardProviderFactory {
         props.setProperty(NiFiRegistryProperties.PROVIDERS_CONFIGURATION_FILE, 
"src/test/resources/provider/providers-does-not-exist.xml");
 
         final ExtensionManager extensionManager = 
Mockito.mock(ExtensionManager.class);
-        
when(extensionManager.getExtensionClassLoader(any(String.class))).thenReturn(this.getClass().getClassLoader());
+        when(extensionManager.getExtensionClassLoader(any(String.class)))
+                .thenReturn(new ExtensionClassLoader("/tmp", new 
URL[0],this.getClass().getClassLoader()));
 
         final DataSource dataSource = Mockito.mock(DataSource.class);
 
@@ -96,7 +101,8 @@ public class TestStandardProviderFactory {
         props.setProperty(NiFiRegistryProperties.PROVIDERS_CONFIGURATION_FILE, 
"src/test/resources/provider/providers-class-not-found.xml");
 
         final ExtensionManager extensionManager = 
Mockito.mock(ExtensionManager.class);
-        
when(extensionManager.getExtensionClassLoader(any(String.class))).thenReturn(this.getClass().getClassLoader());
+        when(extensionManager.getExtensionClassLoader(any(String.class)))
+                .thenReturn(new ExtensionClassLoader("/tmp", new 
URL[0],this.getClass().getClassLoader()));
 
         final DataSource dataSource = Mockito.mock(DataSource.class);
 
diff --git 
a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/hook/TestScriptEventHookProvider.java
 
b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/hook/TestScriptEventHookProvider.java
index b7d241b..39d45ae 100644
--- 
a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/hook/TestScriptEventHookProvider.java
+++ 
b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/hook/TestScriptEventHookProvider.java
@@ -16,6 +16,7 @@
  */
 package org.apache.nifi.registry.provider.hook;
 
+import org.apache.nifi.registry.extension.ExtensionClassLoader;
 import org.apache.nifi.registry.extension.ExtensionManager;
 import org.apache.nifi.registry.properties.NiFiRegistryProperties;
 import org.apache.nifi.registry.provider.ProviderCreationException;
@@ -26,6 +27,8 @@ import org.mockito.Mockito;
 
 import javax.sql.DataSource;
 
+import java.net.URL;
+
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
 
@@ -37,7 +40,8 @@ public class TestScriptEventHookProvider {
         props.setProperty(NiFiRegistryProperties.PROVIDERS_CONFIGURATION_FILE, 
"src/test/resources/provider/hook/bad-script-provider.xml");
 
         final ExtensionManager extensionManager = 
Mockito.mock(ExtensionManager.class);
-        
when(extensionManager.getExtensionClassLoader(any(String.class))).thenReturn(this.getClass().getClassLoader());
+        when(extensionManager.getExtensionClassLoader(any(String.class)))
+                .thenReturn(new ExtensionClassLoader("/tmp", new 
URL[0],this.getClass().getClassLoader()));
 
         final DataSource dataSource = Mockito.mock(DataSource.class);
 

Reply via email to