Почему ограничения использования нарушаются, когда обе цепочки заканчиваются в одном и том же пакете?

151

У меня есть четыре пакета, каждый из которых содержит только манифест. Расслоения

  • appкоторый импортирует com.example.foo.fragmentиcom.example.bar
  • foo который экспортирует com.example.foo;uses:=com.example.foo.cfg
  • foo.fragmentкоторый является фрагментом, прикрепленным к fooэтому экспорту com.example.foo.fragmentиcom.example.foo.fragment.cfg;uses:=com.example.foo.fragment
  • barкоторый экспортирует com.example.barи импортируетcom.example.foo

Граф зависимостей на уровне пакета :

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

Когда я устанавливаю эти пакеты сразу в JBoss AS 7.2, они работают просто отлично. Но если я устанавливаю appпакет после других, либо в первый раз, либо после успешного запуска, а затем удаляю его, происходит следующее нарушение ограничений:

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

Полные манифесты:

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

Я не смог воспроизвести вышеуказанную ошибку в автономном Apache Felix 4.2.1.

В чем причина этого поведения? Если я удаляю Fragment-Host: com.example.fooстроку из foo.fragmentманифеста, я могу appнормально переустановить без ошибок. Это ошибка в JBoss AS 7.2?

Эмиль Лундберг
источник
1
Я согласен, что это довольно странно. Я испытываю желание назвать это ошибкой в ​​реализации фреймворка JBoss AS, и в этом случае об этом следует сообщать в списке рассылки JBoss и / или трекере ошибок.
Нил Бартлетт
Немного повозившись с ним, я заметил, что это происходит только в том случае, если мое приложение не развертывается при запуске JBoss. Возможно, в конце концов, существует другой экспорт пакета org.hibernate.annotations, и платформа OSGi решает это как зависимость пакета Spring ORM, если платформа OSGi запускается без моего приложения. Затем я развертываю свое приложение, и OSGi не может его разрешить, потому что оно несовместимо с org.hibernate.annotationsпакетом, разрешенным для Spring ORM. Это звучит выполнимо?
Эмиль Лундберг
4
Теперь я также начал обсуждение в сообществе JBoss: community.jboss.org/thread/229824
Эмиль Лундберг,
@NeilBartlett Я только что нашел ответ на вопрос 2: экспорт пакета org.hibernate.annotations- это фрагмент с Fragment-Host: com.springsource.org.hibernate.
Эмиль Лундберг
1
Это похоже на ошибку. Предполагается, что пакеты фрагментов действуют так, как если бы они были частью их хост-пакета. В некоторых случаях JBoss рассматривает фрагмент как отдельный пакет при выполнении проверки согласованности пути класса.
Джибсон

Ответы:

1

Вам не нужно импортировать foo.fragment в приложение, ваша зависимость будет разрешена из foo. так что просто удалите эту зависимость и повторно разверните ее. Эта проблема из-за циклической зависимости.

user3555572
источник
3
Это не циклическая зависимость . Это было бы циклично, если бы foo.fragment зависел от приложения. Однако приложение зависит от foo.fragment, поэтому цикл отсутствует. Однако явная зависимость от приложения до foo.fragment может быть ненужной, это правда.
Vog