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

Guillaume Nodet updated FELIX-5450:
-----------------------------------
    Fix Version/s: resolver-1.10.2

> Fragments with multiple hosts can cause 
> java.lang.ArrayIndexOutOfBoundsException
> --------------------------------------------------------------------------------
>
>                 Key: FELIX-5450
>                 URL: https://issues.apache.org/jira/browse/FELIX-5450
>             Project: Felix
>          Issue Type: Bug
>          Components: Resolver
>    Affects Versions: resolver-1.10.0
>            Reporter: Thomas Watson
>            Assignee: Thomas Watson
>             Fix For: resolver-1.10.2
>
>
> The fix in FELIX-5389 for ShadowList is not complete.  There are still cases 
> where the underlying ArrayList from the CandidateSelector is reused in the 
> ShadowList when it is not intended.  This leads to exceptions like the 
> following:
> java.lang.ArrayIndexOutOfBoundsException: -1
>       at java.util.ArrayList.elementData(ArrayList.java:418)
>       at java.util.ArrayList.set(ArrayList.java:446)
>       at org.apache.felix.resolver.util.ShadowList.replace(ShadowList.java:81)
>       at org.apache.felix.resolver.Candidates.prepare(Candidates.java:915)
>       at 
> org.apache.felix.resolver.ResolverImpl.getInitialCandidates(ResolverImpl.java:502)
>       at 
> org.apache.felix.resolver.ResolverImpl.doResolve(ResolverImpl.java:387)
>       at org.apache.felix.resolver.ResolverImpl.resolve(ResolverImpl.java:375)
>       at org.apache.felix.resolver.ResolverImpl.resolve(ResolverImpl.java:368)
> This is happening when there are multiple hosts for a single fragment and the 
> fragment has a requirement that is getting resolved to a candidate from 
> another host resource that also has at least one fragment.
> The issue comes up when replacing the capability from the host with a wrapped 
> capability for the fragment requirement which is a payload requirement for 
> more than one host.  It should do this for each WrappedRequirement that is 
> wrapping the payload requirement from the fragment to each host.  The first 
> WrappedRequirement has its candidates modified, but that changes the shared 
> ArrayList of the candidates for each of the other WrappedRequirements for the 
> other hosts.  The fix for this is to ensure the ArrayList from a 
> CandidateSelector is never shared with a ShadowList.
> But once I fixed this I ran into another strange issue that ended up causing 
> Uses constraint errors like this:
> org.osgi.service.resolver.ResolutionException: Uses constraint violation. 
> Unable to resolve resource host [osgi.identity; host] because it is exposed 
> to package 'exporter' from resources exporter [osgi.identity; exporter] and 
> exporter [osgi.identity; exporter] via two dependency chains.
> Chain 1:
>   host [osgi.identity; host]
>     import: (osgi.wiring.package=exporter)
>      |
>     export: osgi.wiring.package: exporter
>   exporter [osgi.identity; exporter]
> Chain 2:
>   host [osgi.identity; host]
>     import: (osgi.wiring.package=exporter)
>      |
>     export: osgi.wiring.package: exporter
>   exporter [osgi.identity; exporter]
> This only happens if a fragment has more than one host and the fragment and 
> host have a requirement for a the same package.  Additionally the capability 
> that satisfies the payload requirement must come from a host that also has at 
> least one fragment.  The issue here is how we are finding CandidateSelectors 
> of depending requirements when we need to replace a capability with a wrapped 
> capability.  There is a loop in the Candidates.prepare method which is says 
> "Copy candidates for fragment requirements to the host.".  This loop 
> basically copies the candidates from the original requirement from the 
> fragment to a CandidateSelector for the WrappedRequirement for the host.  But 
> it also removes the original requirement from the dependents for the 
> capability.  If there are multiple hosts this becomes problematic because 
> this dependency set is used to find CandidateSelectors that need to be 
> modified when wrapping a host.  But since we remove the original requirement 
> from the fragment that means any other hosts the fragment is attached to will 
> not be discovered and therefore will not have the original capability 
> properly replaced with the WrappedCapability.  That makes the consistency 
> check fail and give this bogus message that make it look like there are 2 
> identical chains leading to the identical capability.  But the two 
> capabilities are different because one is wrapped and one is not.
> The fix is to separate out the inner loop that "Copy candidates for fragment 
> requirements to the host." to a outer loop that is done before the main loop 
> over the hostResources.  This way we properly setup all the CandidateSelector 
> for the payload WrappedRequirements before actually modifying the 
> CandidateSelector capabilities with the WrappedCapabilities.
> Super long story short:  Fragments are just horribly complex. 



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)

Reply via email to