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:47:15 UTC

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

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

Julian Sedding updated FELIX-4477:
----------------------------------

    Description: 
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:

        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);
            }
        }


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 type, which happens to be a HashSet and thus has no defined order.

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

  was:
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}}.


> 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:
>         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);
>             }
>         }
> 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 type, which happens to be a HashSet and thus has no defined order.
> A 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)