Как я могу использовать файл ресурсов **CSS** в одном пакете OSGi из другого пакета OSGi

Структура каталогов моего проекта (в Eclipse):

MyProjectContainingCSS/
    src/        --> "source directory" on Eclipse's classpath/buildpath
        com.me.myapp
            style.css


MyProjectInheritingCSS/
    src/        --> "source directory" on Eclipse's classpath/buildpath
        com.me.myapp
            StyleImpl.java

Я хотел бы использовать в файле CSS style.css, содержащемся в пакете OSGi MyProjectContainingCSS, в другом пакете OSGi MyProjectContainingCSS в классе StyleImpl.java,

Что-то типа:

public class StyleImpl {
    public static void main(String[] args) {
        css = this.getClass().getResource("/com/me/myapp/style.css").toExternalForm();
        scene.getStylesheets().add(css);
    }
}

Как я могу использовать файл ресурсов CSS в одном пакете OSGi из другого пакета OSGi?

Спасибо всем заранее.

ОБНОВЛЕНИЕ

Файл bnd.bnd

Bundle-Version: 0.0.0.${tstamp}
-buildpath: \
    ../cnf/plugins/org.apache.felix.dependencymanager.annotation-3.2.0.jar;version=file,\
    org.apache.felix.dependencymanager,\
    osgi.core,\
    launcher;version=latest,\
    libs/commons-io-2.4.jar;version=file
Private-Package: ui.impl
Export-Package: ui
Import-Package: *

Дескриптор запуска

-runfw: org.apache.felix.framework;version='[4,5)'
-runee: JavaSE-1.8
-runsystemcapabilities: ${native_capability}

-resolve.effective: active;skip:="osgi.service"
-runbundles: \
    org.apache.felix.dependencymanager,\
    org.apache.felix.dependencymanager.runtime,\
    org.apache.felix.dependencymanager.shell,\
    org.apache.felix.metatype,\
    org.apache.felix.eventadmin,\
    org.apache.felix.configadmin,\
    org.apache.felix.log,\
    org.apache.felix.gogo.command,\
    org.apache.felix.gogo.runtime,\
    org.apache.felix.gogo.shell,\
    launcher;version=latest,\
    ui;version=latest,\
    mainscreen;version=latest
-runsystempackages: javafx.application,javafx.scene,javafx.stage,javafx.scene.layout,javafx.event,javafx.collections,javafx.scene.control,javafx.scene.paint,javafx.scene.shape

person Program-Me-Rev    schedule 02.04.2016    source источник
comment
Создайте класс в пакете CSS, чтобы открыть файл InputStream для CSS, и импортируйте этот класс в другой пакет.   -  person 11thdimension    schedule 02.04.2016
comment
Как один пакет узнает, что конкретный ресурс с определенным именем будет найден в другом пакете? Такое предположение означает, что вы нарушаете модульную инкапсуляцию. Попробуйте найти решение, которое не делает предположений о других модулях. Почему бы не описать реальную проблему, которую вы пытаетесь решить?   -  person Neil Bartlett    schedule 04.04.2016


Ответы (1)


Чтобы получить файл из собственного пакета, вы можете сделать:

Bundle bundle = FrameworkUtil.getBundle(this.getClass());
Enumeration<URL> resources = bundle.getResources("/com/me/myapp/style.css");   
if (resources != null) {
    URL myCSS = resources.nextElement();
}            

Если вы можете найти другой объект пакета OSGi, вы можете сделать то же самое. Я бы попробовал что-то вроде этого:

    Bundle bundle = FrameworkUtil.getBundle(this.getClass());
    Bundle[] bArray = bundle.getBundleContext().getBundles();
    Bundle cssBundle = null;
    for (Bundle b : bArray){
        if(b.getSymbolicName().equals("com.me.myapp")) {
            cssBundle = b;
            break; 
        }
    }
    Enumeration<URL> resources = cssBundle.getResources("/com/me/myapp/style.css");   
    if (resources != null) {
        URL myCSS = resources.nextElement();
    }
person Marcos Zolnowski    schedule 03.04.2016
comment
Большое спасибо, @Marcos Zolnowski. Я поместил ваш код в один из своих классов под названием MainScreen, но не могу использовать метод FrameworkUtil.getBundle. Он получает подсветку ошибки с предупреждением The method getBundle(Class<capture#1-of ? extends MainScreen>) is undefined for the type FrameworkUtil. В чем может быть проблема. - person Program-Me-Rev; 03.04.2016
comment
FrameworkUtil — это класс из пакета org.osgi.framework. Тот же пакет Bundle. Какую версию OSGi вы используете? - person Marcos Zolnowski; 03.04.2016
comment
Я совершенно новичок в OSGi. Я не уверен, как проверить версию OSGi. Я использую инструменты BND в eclipse Mars.2 Release (4.5.2) - person Program-Me-Rev; 03.04.2016
comment
Нет проблем, потому что система не говорит вам. Можете ли вы сказать мне версию пакета org.osgi.framework? - person Marcos Zolnowski; 03.04.2016
comment
Я только что обновил Вопрос, добавив новую информацию, пока пытаюсь узнать о org.osgi.framework package - person Program-Me-Rev; 03.04.2016
comment
Некоторые версии bndtools имеют проблемы с дженериками. Но сейчас я не уверен. Вы можете попробовать бросить: FrameworkUtil.getBundle((Class) myClass) - person Marcos Zolnowski; 03.04.2016
comment
Я переместил эту проблему в этот вопрос: Метод getBundle(Class‹capture#1-of ? extends MyClass›) не определен для типа FrameworkUtil. Я приму ваш ответ в ближайшее время. Сначала позвольте мне попробовать заставить работать FrameworkUtil.getBundle и bundle.getBundleContext(). Большое спасибо за помощь до сих пор. - person Program-Me-Rev; 03.04.2016
comment
Единственный способ загрузить CSS на сцену JavaFx — это передать URL-адрес OutputStream, а затем создать временный файл css для загрузки на сцену. Можете ли вы придумать другой более простой способ сделать это? - person Program-Me-Rev; 04.04.2016
comment
Вместо использования статических приемов, таких как FrameworkUtil.getBundle, намного лучше получить BundleContext, внедрив активатор пакета или компонент DS с методом activate. - person Neil Bartlett; 04.04.2016
comment
Статическое поле, содержащее контекст, или что-то связанное с XML, для меня не намного лучше. - person Marcos Zolnowski; 05.04.2016