Dlaczego ograniczenia użycia są naruszane, gdy oba łańcuchy kończą się w tym samym pakiecie?

151

Mam cztery pakiety, z których każdy zawiera tylko manifest. Pakiety są

  • appktóre importują com.example.foo.fragmenticom.example.bar
  • foo który eksportuje com.example.foo;uses:=com.example.foo.cfg
  • foo.fragmentktóry jest fragmentem dołączonym do footego eksportu com.example.foo.fragmenticom.example.foo.fragment.cfg;uses:=com.example.foo.fragment
  • barktóre eksportują com.example.bari importującom.example.foo

Wykres zależności na poziomie pakietu :

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

Kiedy instaluję te pakiety naraz w JBoss AS 7.2, działają dobrze. Ale jeśli zainstaluję apppakiet po innych, albo po raz pierwszy, albo po pomyślnym uruchomieniu i odinstalowaniu go, następuje naruszenie ograniczeń:

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

Pełne manifesty to:

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

Nie udało mi się odtworzyć powyższego błędu w samodzielnym Apache Felix 4.2.1.

Jaka jest przyczyna tego zachowania? Jeśli usunę Fragment-Host: com.example.foowiersz z foo.fragmentmanifestu, mogę ponownie zainstalować appdobrze bez błędów. Czy to błąd w JBoss AS 7.2?

Emil Lundberg
źródło
1
Zgadzam się, to dość dziwne. Kusi mnie, aby nazwać to błędem w implementacji frameworka JBoss AS, w którym to przypadku powinien zostać zgłoszony na liście mailingowej JBoss i / lub trackerze problemów.
Neil Bartlett
Po trochę małpowaniu zauważyłem, że dzieje się tak tylko wtedy, gdy moja aplikacja nie jest wdrażana podczas uruchamiania JBoss. Być może w końcu istnieje inny eksport pakietów org.hibernate.annotations, a platforma OSGi rozwiązuje to jako zależność pakietu Spring ORM, jeśli platforma OSGi uruchamia się bez mojej aplikacji. Następnie wdrażam moją aplikację i OSGi nie rozwiązuje jej, ponieważ nie jest zgodna z org.hibernate.annotationspakietem rozwiązanym do pakietu Spring ORM. Czy to brzmi wykonalne?
Emil Lundberg
4
Zacząłem teraz także dyskusję w społeczności JBoss: community.jboss.org/thread/229824
Emil Lundberg.
@NeilBartlett Właśnie znalazłem odpowiedź na pytanie 2: eksport pakietu org.hibernate.annotationsto fragment z Fragment-Host: com.springsource.org.hibernate.
Emil Lundberg
1
To wygląda na błąd. Pakiety fragmentów mają zachowywać się tak, jakby były częścią paczki hostów. Wygląda na to, że w niektórych przypadkach JBoss traktuje fragment jako oddzielny pakiet podczas sprawdzania spójności ścieżki klas.
jgibson

Odpowiedzi:

1

Nie musisz importować foo.fragment do aplikacji, w której twoja zależność zostanie rozwiązana z foo. więc po prostu usuń tę zależność i ponownie ją wdróż. Ten problem wynika z cyklicznej zależności.

user3555572
źródło
3
To nie jest zależność cykliczna . Byłoby to cykliczne, gdyby foo.fragment zależało od ok. Jednak aplikacja zależy od foo.fragment, więc nie ma cyklu. Jednak jawna zależność między aplikacją a foo.fragment może być niepotrzebna, to prawda.
vog