Why are uses constraints violated when both chains end in the same bundle?
Asked Answered
W

1

151

I have four bundles, each containing only a manifest. The bundles are

  • app which imports com.example.foo.fragment and com.example.bar
  • foo which exports com.example.foo;uses:=com.example.foo.cfg
  • foo.fragment which is a fragment attached to foo that exports com.example.foo.fragment and com.example.foo.fragment.cfg;uses:=com.example.foo.fragment
  • bar which exports com.example.bar and imports com.example.foo

Bundle-level dependency graph:

app -> bar
|       |
|       v
|      foo
|       |
v       v
foo.fragment

When I install these bundles all at once in JBoss AS 7.2, they work just fine. But if I install the app bundle after the others, either for the first time or after successfully starting and then uninstalling it, the following uses constraint violation occurs:

Caused by: org.osgi.service.resolver.ResolutionException: Uses constraint violation. Unable to resolve resource com.example.app [HostBundleRevision[com.example.app:0.0.
0]] because it is exposed to package 'com.example.foo.fragment' from resources com.example.foo [HostBundleRevision[com.example.foo:0.0.0]] and com.example.foo [HostBund
leRevision[com.example.foo:0.0.0]] via two dependency chains.

Chain 1:
  com.example.app [HostBundleRevision[com.example.app:0.0.0]]
    import: null
     |
    export: osgi.wiring.package=com.example.foo.fragment
  com.example.foo [HostBundleRevision[com.example.foo:0.0.0]]

Chain 2:
  com.example.app [HostBundleRevision[com.example.app:0.0.0]]
    import: null
     |
    export: osgi.wiring.package=com.example.bar; uses:=com.example.foo
  com.example.bar [HostBundleRevision[com.example.bar:0.0.0]]
    import: null
     |
    export: osgi.wiring.package=com.example.foo; uses:=com.example.foo.fragment
    export: osgi.wiring.package=com.example.foo.fragment
  com.example.foo [HostBundleRevision[com.example.foo:0.0.0]]
        at org.apache.felix.resolver.ResolverImpl.checkPackageSpaceConsistency(ResolverImpl.java:1142)
        at org.apache.felix.resolver.ResolverImpl.resolve(ResolverImpl.java:197)
        at org.jboss.osgi.resolver.felix.StatelessResolver.resolve(StatelessResolver.java:56)
        at org.jboss.osgi.framework.internal.ResolverImpl.resolveAndApply(ResolverImpl.java:137)
        at org.jboss.as.osgi.service.BundleLifecycleIntegration$BundleLifecycleImpl.activateDeferredPhase(BundleLifecycleIntegration.java:296)
        ... 31 more

The full manifests are:

app.jar/META-INF/MANIFEST.MF
----------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.example.app
Import-Package: com.example.foo.fragment,com.example.bar
----------------------------
foo.jar/META-INF/MANIFEST.MF
----------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.example.foo
Export-Package: com.example.foo;uses:="com.example.foo.cfg"
-------------------------------------
foo.fragment.jar/META-INF/MANIFEST.MF
-------------------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.example.foo.fragment
Fragment-Host: com.example.foo
Export-Package: com.example.foo.fragment,com.example.foo.cfg;uses:="co
 m.example.foo.fragment"
----------------------------
bar.jar/META-INF/MANIFEST.MF
----------------------------
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.example.bar
Export-Package: com.example.bar;uses:="com.example.foo"
Import-Package: com.example.foo

I have not been able to reproduce the above error in standalone Apache Felix 4.2.1.

What is the cause of this behaviour? If I delete the Fragment-Host: com.example.foo row from the foo.fragment manifest, I can reinstall app just fine without errors. Is this a bug in JBoss AS 7.2?

Wu answered 26/6, 2013 at 10:15 Comment(10)
I agree this is pretty weird. I'm tempted to call this a bug in the JBoss AS framework implementation, in which case it should be reported on the JBoss mailing list and/or issue tracker.Summerlin
After monkeying around with it a bit, I noticed that this only occurs if my application is not deployed when JBoss starts up. Maybe there is, after all, another bundle exporting org.hibernate.annotations, and the OSGi platform resolves that as the dependency of the Spring ORM bundle if the OSGi platform starts up without my application. Then I deploy my application, and OSGi fails to resolve it because it is not compatible with the org.hibernate.annotations bundle resolved to the Spring ORM bundle. Does that sound feasible?Wu
I have now also started a discussion in the JBoss community: community.jboss.org/thread/229824Wu
@NeilBartlett I just figured out the answer to question 2: the bundle exporting org.hibernate.annotations is a fragment with Fragment-Host: com.springsource.org.hibernate.Wu
(The above comments refer to older versions of the question, it has now been abstracted away from hibernate etc.)Wu
This looks like a bug. Fragment bundles are supposed to be act as if they are part of their host bundle.It looks like in some cases JBoss is treating the fragment as a separate bundle when performing the classpath consistency check.Indecorum
Can you provide us with a zip containing all the jars so that it is easier for us to test? Is this testable in other OSGi containers such as felix?Quinn
@Quinn certainly. It's been a year, though, let me try to reproduce the problem again first. :)Wu
Phooey, seems like JBoss 7.2 won't compile on my machine, so I don't have a clean instance to run on. I might have time to look into it sometime later. In the meantime here is a GitHub repo with the example, and here is a zip file with all the jars. Regarding other OSGi containers: As stated above, I wasn't able to reproduce this in standalone Apache Felix. I haven't tried other containers.Wu
possible duplicate of Constraints from the fragment conflict with the hostInvolucrum
F
1

You don't have to import foo.fragment in app your dependency will resolve from foo. so just remove that dependency and re-deploy that. This issue is because of cyclic dependency.

Flooded answered 28/1, 2015 at 7:31 Comment(1)
This is not a cyclic dependency. It would be cyclic if foo.fragment depended on app. However, app depends on foo.fragment, so there's no cycle. However, the explicit dependency from app to foo.fragment may be unneeded, that's true.Terreverte

© 2022 - 2024 — McMap. All rights reserved.