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