felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Julian Sedding (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (FELIX-4477) Sporadic failure to resolve jar files embedded in fragment bundles
Date Thu, 03 Apr 2014 12:47:15 GMT

     [ 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)

Mime
View raw message