Mengapa kendala penggunaan dilanggar ketika kedua rantai berakhir di bundel yang sama?

151

Saya memiliki empat bundel, masing-masing hanya berisi manifes. Bundelnya adalah

  • appyang mengimpor com.example.foo.fragmentdancom.example.bar
  • foo yang mengekspor com.example.foo;uses:=com.example.foo.cfg
  • foo.fragmentyang merupakan fragmen yang melekat pada fooekspor itu com.example.foo.fragmentdancom.example.foo.fragment.cfg;uses:=com.example.foo.fragment
  • baryang ekspor com.example.bardan imporcom.example.foo

Grafik ketergantungan tingkat bundel :

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

Ketika saya menginstal bundel ini sekaligus di JBoss AS 7.2, mereka bekerja dengan baik. Tetapi jika saya menginstal appbundel setelah yang lain, baik untuk pertama kalinya atau setelah berhasil memulai dan kemudian mencopotnya, hal berikut ini menggunakan pelanggaran kendala:

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

Manifes lengkapnya adalah:

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

Saya belum dapat mereproduksi kesalahan di atas di standalone Apache Felix 4.2.1.

Apa penyebab perilaku ini? Jika saya menghapus Fragment-Host: com.example.foobaris dari foo.fragmentmanifes, saya dapat menginstal ulang dengan appbaik tanpa kesalahan. Apakah ini bug di JBoss AS 7.2?

Emil Lundberg
sumber
1
Saya setuju ini sangat aneh. Saya tergoda untuk menyebutnya bug dalam implementasi kerangka kerja JBoss AS, dalam hal ini bug tersebut harus dilaporkan di milis JBoss dan / atau pelacak masalah.
Neil Bartlett
Setelah sedikit berkeliaran, saya perhatikan bahwa ini hanya terjadi jika aplikasi saya tidak digunakan ketika JBoss dijalankan. Mungkin ada, setelah semua, bundel lain yang mengekspororg.hibernate.annotations , dan platform OSGi memutuskan bahwa sebagai ketergantungan dari bundel ORM Musim Semi jika platform OSGi dijalankan tanpa aplikasi saya. Lalu saya menggunakan aplikasi saya, dan OSGi gagal menyelesaikannya karena tidak kompatibel dengan org.hibernate.annotationsbundel yang diselesaikan ke bundel ORM Musim Semi. Apakah itu terdengar masuk akal?
Emil Lundberg
4
Saya sekarang juga telah memulai diskusi di komunitas JBoss: community.jboss.org/thread/229824
Emil Lundberg
@ NeilBartlett Saya baru saja menemukan jawaban untuk pertanyaan 2: ekspor bundel org.hibernate.annotationsadalah sebuah fragmen dengan Fragment-Host: com.springsource.org.hibernate.
Emil Lundberg
1
Ini terlihat seperti bug. Bundel fragmen seharusnya bertindak seolah-olah mereka adalah bagian dari bundel host mereka. Sepertinya dalam beberapa kasus JBoss memperlakukan fragmen sebagai bundel terpisah ketika melakukan pemeriksaan konsistensi classpath.
jgibson

Jawaban:

1

Anda tidak perlu mengimpor foo.fragment di aplikasi, ketergantungan Anda akan diselesaikan dari foo. jadi hapus saja ketergantungan itu dan gunakan kembali itu. Masalah ini karena ketergantungan siklik.

pengguna3555572
sumber
3
Ini bukan ketergantungan siklik . Ini akan menjadi siklus jika froo.fragment tergantung pada aplikasi. Namun, aplikasi tergantung pada foo.fragment, jadi tidak ada siklus. Namun, ketergantungan eksplisit dari aplikasi ke foo.fragment mungkin tidak diperlukan, itu benar.
vog