[ 
https://issues.apache.org/jira/browse/NIFI-2909?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15629250#comment-15629250
 ] 

ASF GitHub Bot commented on NIFI-2909:
--------------------------------------

Github user olegz commented on a diff in the pull request:

    https://github.com/apache/nifi/pull/1156#discussion_r86157718
  
    --- Diff: 
nifi-commons/nifi-utils/src/main/java/org/apache/nifi/util/file/classloader/ClassLoaderUtils.java
 ---
    @@ -24,23 +24,57 @@
     import java.net.URL;
     import java.net.URLClassLoader;
     import java.util.Arrays;
    +import java.util.LinkedHashSet;
     import java.util.LinkedList;
     import java.util.List;
    +import java.util.Set;
     import java.util.stream.Collectors;
     
     public class ClassLoaderUtils {
     
         public static ClassLoader getCustomClassLoader(String modulePath, 
ClassLoader parentClassLoader, FilenameFilter filenameFilter) throws 
MalformedURLException {
    -        // Split and trim the module path(s)
    -        List<String> modules = (modulePath == null)
    +        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
    +     * @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 {
    +        Set<String> modules = (modulePath == null)
                     ? null
    -                : 
Arrays.stream(modulePath.split(",")).filter(StringUtils::isNotBlank).map(String::trim).collect(Collectors.toList());
    +                : 
Arrays.stream(modulePath.split(",")).filter(StringUtils::isNotBlank).map(String::trim).collect(Collectors.toSet());
     
    -        URL[] classpaths = getURLsForClasspath(modules, filenameFilter);
    -        return createModuleClassLoader(classpaths, parentClassLoader);
    +        return getURLsForClasspathHelper(modules, filenameFilter, 
suppressExceptions);
         }
     
    -    protected static URL[] getURLsForClasspath(List<String> modulePaths, 
FilenameFilter filenameFilter) throws MalformedURLException {
    +    /**
    +     *
    +     * @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 {
    +        Set<String> modules = new LinkedHashSet<>();
    +        if (modulePaths != null) {
    +            for (String modulePath : modulePaths) {
    +                modules.addAll(Arrays.stream(modulePath.split(","))
    +                        .filter(StringUtils::isNotBlank)
    +                        .map(String::trim)
    +                        .collect(Collectors.toSet()));
    +            }
    +        }
    +
    +        return getURLsForClasspathHelper(modules, filenameFilter, 
suppressExceptions);
    +    }
    --- End diff --
    
    Since we're getting more into functional programming style and in spirit of 
removing duplication consider the following improvements to both versions of 
```getURLsForClasspath(..)``` methods.
    ```
    public static URL[] getURLsForClasspath(String modulePath, FilenameFilter 
filenameFilter, boolean suppressExceptions) throws MalformedURLException {
            return getURLsForClasspath(modulePath == null ? 
Collections.emptySet() : Collections.singleton(modulePath), filenameFilter, 
suppressExceptions);
    }
    
    public static URL[] getURLsForClasspath(Set<String> modulePaths, 
FilenameFilter filenameFilter, boolean suppressExceptions) throws 
MalformedURLException {
            Set<String> modules = modulePaths == null ? null : 
modulePaths.stream()
                    .flatMap(path -> Arrays.stream(path.split(",")))
                    .filter(StringUtils::isNotBlank)
                    .map(String::trim)
                    .collect(Collectors.toSet());
            return getURLsForClasspathHelper(modules, filenameFilter, 
suppressExceptions);
    }
    ```


> Provide a framework mechanism for loading additional classpath resources
> ------------------------------------------------------------------------
>
>                 Key: NIFI-2909
>                 URL: https://issues.apache.org/jira/browse/NIFI-2909
>             Project: Apache NiFi
>          Issue Type: Improvement
>            Reporter: Bryan Bende
>            Assignee: Bryan Bende
>             Fix For: 1.1.0
>
>
> We currently have several components with a property for specifying 
> additional classpath resources (DBCP connection pool, scripting processors, 
> JMS). Each of these components is responsible for handling this in its own 
> way. 
> The framework should provide a more integrated solution to make it easier for 
> component developers to deal with this scenario. Some requirements that need 
> to be met by this solution:
> - Multiple instances of the same component with different resources added to 
> the classpath and not interfering with each other (i.e. two DBCP connection 
> pools using different drivers)
> - Ability to modify the actual ClassLoader of the component to deal with 
> frameworks that use Class.forName() without passing in a ClassLoader, meaning 
> if a processor loads class A and class A calls Class.forName(classBName), 
> then class B needs to be available in the ClassLoader that loaded the 
> processor's class which in turn loaded class A
> - A component developer should be able to indicate that a given 
> PropertyDescriptor represents a classpath resource and the framework should 
> take care of the ClassLoader manipulation



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to