You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Francois Valdy (JIRA)" <ji...@apache.org> on 2012/05/07 12:33:49 UTC

[jira] [Updated] (FELIX-3500) InstanceManager concurrency issue: "A methodID cannot be associated with a method from the POJO class"

     [ https://issues.apache.org/jira/browse/FELIX-3500?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Francois Valdy updated FELIX-3500:
----------------------------------

    Description: 
InstanceManager.getMethodByID(String) claims to be thread-safe (or not to require synchronization) but is not.
It results in random messages "A methodID cannot be associated with a method from the POJO class" (which were downgraded from ERROR to INFO), but has unknown side effect bugs (as it returns null for valid methods when that happens).

If 2 threads call this method with the same parameter:
- both won't find it in the cache (m_methods.get(methodId) == null)
- one will register it: !m_methods.containsValue(mets[i]) is true
- second thread will NOT register it (because the first one did, hence the value is in the map), and will return null <-- bug

Other issues may occur from the fact that an HashMap (unsafe) is used without synchronization, for instance a well-known infinite loop.

I think one fix (to keep the same method semantics) under J2SE 1.3 would be to:
- use Hashtable instead of HashMap (safe as the value is never null)
- replace the code within the loop by:
                if (m_methods.containsValue(mets[i]))
                {
                    method = (Method) m_methods.get(methodId);
                    if (method != null)
                    {
                        return method;
                    }
                }
                else if (MethodMetadata.computeMethodId(mets[i]).equals(methodId))
                {
                    // Store the new methodId
                    m_methods.put(methodId, mets[i]);
                    return mets[i];
                }

However I'm not sure about the purpose of the containsValue check purpose (which is also very expensive as it traverses the entire map).

Thanks.

  was:
InstanceManager.getMethodByID(String) claims to be thread-safe (or not to require synchronization) but is not.
It results in random messages "A methodID cannot be associated with a method from the POJO class" (which were downgraded from ERROR to INFO), but has unknown side effect bugs (as it returns null for valid methods when that happens).

If 2 threads call this method with the same parameter:
- both won't find it in the cache (m_methods.get(methodId) == null)
- one will register it: !m_methods.containsValue(mets[i]) is true
- second thread will NOT register it (because the first one did, hence the vamue is in the map), and will return null <-- bug

Other issues may occur from the fact that an HashMap (unsafe) is used without synchronization, for instance a well-known infinite loop.

I think one fix (to keep the same method semantics) under J2SE 1.3 would be to:
- use Hashtable instead of HashMap (safe as the value is never null)
- replace the code within the loop by:
                if (m_methods.containsValue(mets[i]))
                {
                    method = (Method) m_methods.get(methodId);
                    if (method != null)
                    {
                        return method;
                    }
                }
                else if (MethodMetadata.computeMethodId(mets[i]).equals(methodId))
                {
                    // Store the new methodId
                    m_methods.put(methodId, mets[i]);
                    return mets[i];
                }

However I'm not sure about the purpose of the containsValue check purpose (which is also very expensive as it traverses the entire map).

Thanks.

    
> InstanceManager concurrency issue: "A methodID cannot be associated with a method from the POJO class"
> ------------------------------------------------------------------------------------------------------
>
>                 Key: FELIX-3500
>                 URL: https://issues.apache.org/jira/browse/FELIX-3500
>             Project: Felix
>          Issue Type: Bug
>          Components: iPOJO
>    Affects Versions: ipojo-core-1.8.2
>            Reporter: Francois Valdy
>
> InstanceManager.getMethodByID(String) claims to be thread-safe (or not to require synchronization) but is not.
> It results in random messages "A methodID cannot be associated with a method from the POJO class" (which were downgraded from ERROR to INFO), but has unknown side effect bugs (as it returns null for valid methods when that happens).
> If 2 threads call this method with the same parameter:
> - both won't find it in the cache (m_methods.get(methodId) == null)
> - one will register it: !m_methods.containsValue(mets[i]) is true
> - second thread will NOT register it (because the first one did, hence the value is in the map), and will return null <-- bug
> Other issues may occur from the fact that an HashMap (unsafe) is used without synchronization, for instance a well-known infinite loop.
> I think one fix (to keep the same method semantics) under J2SE 1.3 would be to:
> - use Hashtable instead of HashMap (safe as the value is never null)
> - replace the code within the loop by:
>                 if (m_methods.containsValue(mets[i]))
>                 {
>                     method = (Method) m_methods.get(methodId);
>                     if (method != null)
>                     {
>                         return method;
>                     }
>                 }
>                 else if (MethodMetadata.computeMethodId(mets[i]).equals(methodId))
>                 {
>                     // Store the new methodId
>                     m_methods.put(methodId, mets[i]);
>                     return mets[i];
>                 }
> However I'm not sure about the purpose of the containsValue check purpose (which is also very expensive as it traverses the entire map).
> Thanks.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira