Warum werden Verwendungsbeschränkungen verletzt, wenn beide Ketten im selben Bündel enden?

151

Ich habe vier Bündel, die jeweils nur ein Manifest enthalten. Die Bündel sind

  • app welche Importe com.example.foo.fragment undcom.example.bar
  • foo welche exportiert com.example.foo;uses:=com.example.foo.cfg
  • foo.fragmentDas ist ein Fragment, das mit foodiesen Exporten verbunden istcom.example.foo.fragment undcom.example.foo.fragment.cfg;uses:=com.example.foo.fragment
  • barwelche Exporte com.example.barund Importecom.example.foo

Abhängigkeitsdiagramm auf Bundle-Ebene :

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

Wenn ich diese Bundles auf einmal in JBoss AS 7.2 installiere, funktionieren sie einwandfrei. Wenn ich das appBundle jedoch entweder zum ersten Mal oder nach erfolgreichem Start und anschließender Deinstallation nach den anderen installiere , tritt die folgende Verletzung der Verwendungsbeschränkung auf:

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

Die vollständigen Manifeste sind:

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

Ich konnte den obigen Fehler in eigenständigem Apache Felix 4.2.1 nicht reproduzieren.

Was ist die Ursache für dieses Verhalten? Wenn ich die Fragment-Host: com.example.fooZeile aus dem foo.fragmentManifest lösche , kann ich sie appproblemlos und ohne Fehler neu installieren . Ist dies ein Fehler in JBoss AS 7.2?

Emil Lundberg
quelle
1
Ich stimme zu, das ist ziemlich komisch. Ich bin versucht, dies als Fehler in der Implementierung des JBoss AS-Frameworks zu bezeichnen. In diesem Fall sollte dies in der JBoss-Mailingliste und / oder im Issue-Tracker gemeldet werden.
Neil Bartlett
Nachdem ich ein bisschen herumgespielt hatte, bemerkte ich, dass dies nur auftritt, wenn meine Anwendung beim Start von JBoss nicht bereitgestellt wird. Möglicherweise wird schließlich ein anderes Bundle exportiert org.hibernate.annotations, und die OSGi-Plattform löst dies als Abhängigkeit des Spring ORM-Bundles auf, wenn die OSGi-Plattform ohne meine Anwendung gestartet wird. Dann stelle ich meine Anwendung bereit und OSGi kann sie nicht auflösen, da sie nicht mit dem org.hibernate.annotationsin das Spring ORM-Bundle aufgelösten Bundle kompatibel ist. Klingt das machbar?
Emil Lundberg
4
Ich habe jetzt auch eine Diskussion in der JBoss-Community gestartet: community.jboss.org/thread/229824
Emil Lundberg
@NeilBartlett Ich habe gerade die Antwort auf Frage 2 herausgefunden: Der Bundle-Export org.hibernate.annotationsist ein Fragment mit Fragment-Host: com.springsource.org.hibernate.
Emil Lundberg
1
Das sieht aus wie ein Fehler. Fragment-Bundles sollen sich so verhalten, als wären sie Teil ihres Host-Bundles. In einigen Fällen behandelt JBoss das Fragment bei der Überprüfung der Klassenpfad-Konsistenz als separates Bundle.
Jgibson

Antworten:

1

Sie müssen foo.fragment nicht in die App importieren, Ihre Abhängigkeit wird von foo aufgelöst. Entfernen Sie einfach diese Abhängigkeit und stellen Sie sie erneut bereit. Dieses Problem ist auf die zyklische Abhängigkeit zurückzuführen.

user3555572
quelle
3
Dies ist keine zyklische Abhängigkeit . Es wäre zyklisch, wenn foo.fragment von der App abhängen würde. Die App hängt jedoch von foo.fragment ab, sodass es keinen Zyklus gibt. Die explizite Abhängigkeit von App zu foo.fragment ist jedoch möglicherweise nicht erforderlich.
Vog