OSGi/Equinox: как преобразовать URI ресурса в имя пакета?

После поиска ресурса в пути к классам я получил этот URL:

bundleresource://23.fwk1186515174/com/google/inject/Injector.class

Как узнать, в какой бандле предоставлен ресурс?

[EDIT] Я пытаюсь устранить проблему, связанную с дублированием классов в пути к классам. Вот код, который я использую:

private void debugClassPath() {
    String resource = "com/google/inject/Injector.class";
    try {
        Enumeration<URL> urls = getClass().getClassLoader().getResources( resource );

        while( urls.hasMoreElements() ) {
            System.out.println(urls.nextElement());
        }

        System.out.println("---");

        urls = XtextRunner.class.getClassLoader().getResources( resource );

        while( urls.hasMoreElements() ) {
            System.out.println(urls.nextElement());
        }
    } catch( IOException e ) {
        e.printStackTrace();
    }
}

Это дает мне несколько URL-адресов для com.google.inject.Injector, и я хочу выяснить, какие пакеты добавляют их в путь к классам.


person Aaron Digulla    schedule 09.08.2012    source источник


Ответы (3)


URL-адреса OSGi гарантируют иерархию. Поэтому просто замените com/google/inject/Injector.class на META-INF/MANIFEST.MF и прочитайте ресурс как манифест (или текстовый файл). Информация там говорит вам, на какой пакет вы смотрите.

Повторяющиеся классы могут происходить ТОЛЬКО с разделенными пакетами, что считается плохой (очень плохой имхо) практикой. В OSGi для разделенных пакетов требуется Require-Bundle с реэкспортом или Bundle-Classpath. Без них жить намного проще...

person Peter Kriens    schedule 13.08.2012
comment
У вас есть документ, в котором объясняется, что такое разделенные пакеты и как их исправить? Предыстория: мне нужно достаточно информации/понимания проблемы, чтобы сообщить задействованным проектам, как решить проблему. - person Aaron Digulla; 13.08.2012
comment
Начните использовать bnd(tools) ... bnd verifiers и кричит на вас, когда вы разделяете пакеты. Разделенные пакеты — это несколько поставщиков одного и того же пакета. В OSGi это может произойти только при использовании Require-Bundle с реэкспортом. Прекратите это делать, и ваши проблемы закончатся. Разделенные пакеты обсуждаются в спецификации на модульном уровне. - person Peter Kriens; 13.08.2012
comment
я этого не делаю; это должно быть в двух других проектах, поэтому мне нужно убедить этих двоих исправить это. - person Aaron Digulla; 13.08.2012

Один хакерский способ — проанализировать URL-адрес, но он будет работать только при работе на Equinox. Согласно источнику для BundleResourceHandler , это целое число ('23') справа от схемы URL является идентификатором пакета. Если у вас есть BundleContext (проверьте свой активатор), вы можете найти, какой это пакет с этим идентификатором, используя getBundle(long).

Однако, вероятно, есть гораздо лучший способ сделать это. Как вы ищете ресурс в пути к классам?

person Dan Gravell    schedule 09.08.2012
comment
Обычный способ: getClass().getClassLoader().getResources('com/google/inject/Injector.class'). Я пытаюсь отладить проблему с загрузкой классов, когда я получаю два URL-адреса для этого ресурса, и я хочу знать, какие пакеты их предоставляют. - person Aaron Digulla; 10.08.2012
comment
Предположительно, один пакет загружает одну версию класса, а другой загружает другую версию? Вы можете попробовать увеличить ведение журнала в контейнере Equinox, чтобы увидеть используемую проводку загрузки классов. Создайте файл .options, как описано в разделе «osgi.debug» в help.eclipse.org/galileo/index.jsp?topic=/ и включите 'org.eclipse.osgi/resolver/wiring = true' ( Есть и другие варианты) - person Dan Gravell; 10.08.2012
comment
Я думаю, что две зависимости моего пакета экспортируют один и тот же класс, но мне нужно знать, какие именно. - person Aaron Digulla; 10.08.2012
comment
Ну, журнал должен показать, как пакеты соединяются вместе. - person Dan Gravell; 10.08.2012

Стандартного способа сделать это нет. Тем не менее, для Equinox существует особый способ реализации (который может быть изменен в будущих выпусках, поскольку это особый способ реализации) путем просмотра того, как обработчик URL-адреса кодирует его в полномочиях.

person BJ Hargrave    schedule 09.08.2012
comment
Это специфично для Equinox/Eclipse. Как я могу сделать это в Equinox? - person Aaron Digulla; 10.08.2012