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

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_r86527207
  
    --- Diff: 
nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/controller/AbstractConfiguredComponent.java
 ---
    @@ -90,47 +107,80 @@ public void setAnnotationData(final String data) {
         }
     
         @Override
    -    public void setProperty(final String name, final String value) {
    -        if (null == name || null == value) {
    -            throw new IllegalArgumentException();
    +    public void setProperties(Map<String, String> properties) {
    +        if (properties == null) {
    +            return;
             }
     
             lock.lock();
             try {
                 verifyModifiable();
     
    -            try (final NarCloseable narCloseable = 
NarCloseable.withComponentNarLoader(component.getClass())) {
    -                final PropertyDescriptor descriptor = 
component.getPropertyDescriptor(name);
    -
    -                final String oldValue = properties.put(descriptor, value);
    -                if (!value.equals(oldValue)) {
    -
    -                    if (descriptor.getControllerServiceDefinition() != 
null) {
    -                        if (oldValue != null) {
    -                            final ControllerServiceNode oldNode = 
serviceProvider.getControllerServiceNode(oldValue);
    -                            if (oldNode != null) {
    -                                oldNode.removeReference(this);
    -                            }
    -                        }
    -
    -                        final ControllerServiceNode newNode = 
serviceProvider.getControllerServiceNode(value);
    -                        if (newNode != null) {
    -                            newNode.addReference(this);
    +            try (final NarCloseable narCloseable = 
NarCloseable.withComponentNarLoader(component.getClass(), id)) {
    +                final Set<String> modulePaths = new LinkedHashSet<>();
    +                for (final Map.Entry<String, String> entry : 
properties.entrySet()) {
    +                    if (entry.getKey() != null && entry.getValue() == 
null) {
    +                        removeProperty(entry.getKey());
    +                    } else if (entry.getKey() != null) {
    +                        setProperty(entry.getKey(), entry.getValue());
    +
    +                        // for any properties that dynamically modify the 
classpath, attempt to evaluate them for expression language
    +                        final PropertyDescriptor descriptor = 
component.getPropertyDescriptor(entry.getKey());
    +                        if (descriptor.isDynamicClasspathModifier() && 
!StringUtils.isEmpty(entry.getValue())) {
    +                            final StandardPropertyValue propertyValue = 
new StandardPropertyValue(entry.getValue(), null, variableRegistry);
    +                            
modulePaths.add(propertyValue.evaluateAttributeExpressions().getValue());
                             }
                         }
    +                }
     
    -                    try {
    -                        component.onPropertyModified(descriptor, oldValue, 
value);
    -                    } catch (final Exception e) {
    -                        // nothing really to do here...
    -                    }
    +                final boolean requiresInstanceClassLoading = 
ExtensionManager.requiresInstanceClassLoading(component.getClass().getTypeName());
    +                if (requiresInstanceClassLoading) {
    +                    processClasspathModifiers(modulePaths);
    +                } else if (!requiresInstanceClassLoading && 
modulePaths.size() > 0) {
    +                    // Component has property descriptors with 
dynamicallyModifiesClasspath set to true, but the class does not have 
@RequiresInstanceClassLoading
    +                    logger.warn("One or more property descriptors intend 
to modify the classpath, " +
    +                            "but component does not contain the {} 
annotation, classpath will not be modified",
    +                            new Object[] 
{RequiresInstanceClassLoading.class.getName()});
                     }
                 }
             } finally {
                 lock.unlock();
             }
         }
     
    +    // Keep setProperty/removeProperty private so that all calls go 
through setProperties
    +    private void setProperty(final String name, final String value) {
    +        if (null == name || null == value) {
    +            throw new IllegalArgumentException();
    +        }
    --- End diff --
    
    I see, but I still think we have to fix it


> 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