You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Julian Sedding (JIRA)" <ji...@apache.org> on 2014/04/03 14:43:17 UTC

[jira] [Created] (FELIX-4477) Sporadic failure to resolve jar files embedded in fragment bundles

Julian Sedding created FELIX-4477:
-------------------------------------

             Summary: Sporadic failure to resolve jar files embedded in fragment bundles
                 Key: FELIX-4477
                 URL: https://issues.apache.org/jira/browse/FELIX-4477
             Project: Felix
          Issue Type: Bug
          Components: Framework
    Affects Versions: framework-4.2.0
            Reporter: Julian Sedding


Scenario:
- two fragment bundles, {{f1}} and {{f2}}, are attached to the same host bundle
- at least one fragment bundle embeds a jar file, which is mentioned in its {{Bundle-ClassPath}} header
- when resolving the host bundle during startup, sometimes the embedded jar file cannot be found (at felix.log.level=3 this causes "INFO Class path entry not found: enbedded-file.jar" to be logged)

The consequence is that functionality provided by the embedded jar file is unavailable.

Analysis:
When calculating the "contentPath" in {{BundleRevisionImpl#initializeContentPath()}} the implementation assumes that the local lists {{fragments}} and {{fragmentContents}} are sorted and in sync (i.e. the same index refers to the same fragment bundle).

However, this assumption does not hold if two or more fragment bundles are attached to the same host bundle.
The following excerpt from {{BundleRevisionImpl#initializeContentPath()}} illustrates the problem:
{code:java}
        List<BundleRevision> fragments = null;
        List<Content> fragmentContents = null;
        if (m_wiring != null)
        {
            fragments = Util.getFragments(m_wiring);
            fragmentContents = m_wiring.getFragmentContents();
        }
        if (fragments != null)
        {
            for (int i = 0; i < fragments.size(); i++)
            {
                calculateContentPath(
                    fragments.get(i), fragmentContents.get(i), contentList, false);
            }
        }
{code}

{{fragments}} is initialized via {{Util.getFragments(m_wiring)}}, while {{fragmentContents}} is set to {{m_wiring.getFragmentContents()}}. Later on, in the for loop, the assumption is made that both lists are in sync.

Looking into {{m_wiring.getFragmentContents()}} quickly reveals that {{fragmentContents}} is sorted using string-comparison of {{BundleRevisionImpl#getId()}}.

Looking into {{Util.getFragments(m_wiring)}} eventually leads to {{BundleRevisionDependencies#m_dependentsMap}}, which is a {{Map<BundleRevision, Map<BundleCapability, Set<BundleWire>>>}}. The value of the {{fragments}} list above is sorted according to the {{Set<BundleWire>}} part of that signature, which happens to be a {{HashSet}} and thus no defined order.

An quick fix (albeit not necessarily the best?) would be to sort {{fragments}} after retrieving it, in order to match the order of {{fragmentContents}}.



--
This message was sent by Atlassian JIRA
(v6.2#6252)