0

My project directory structure (in 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

I would like to use in the CSS file style.css contained in the OSGi bundle MyProjectContainingCSS in the other OSGi bundle MyProjectContainingCSS in the class StyleImpl.java,

Something like:

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

How can I go about using a CSS resource file in one OSGi bundle from another OSGi bundle?

Thank you all in advance.

UPDATE

The bnd.bnd file

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: *

Run Descriptor

-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
Program-Me-Rev
  • 6,184
  • 18
  • 58
  • 142
  • Create a class in the CSS bundle to expose the InputStream to CSS file and import this class in another bundle. – 11thdimension Apr 02 '16 at 19:12
  • How does one bundle know that a specific resource with a specific name will be found in another bundle? That kind of assumption means you are violating modular encapsulation. Try to find a solution that doesn't make assumptions about other modules. Why not describe the *real* problem you are trying to solve? – Neil Bartlett Apr 03 '16 at 22:39

1 Answers1

0

To get the file from your own bundle, you can do:

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

If you can find the other OSGi bundle object, you can do the same. I would try something like this:

    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();
    }
Marcos Zolnowski
  • 2,751
  • 1
  • 24
  • 29
  • Thanks so much @Marcos Zolnowski I've put your code in one of my classes called **MainScreen**, but I'm unable to use the method `FrameworkUtil.getBundle`. It gets an error highlight with the warning `The method getBundle(Class) is undefined for the type FrameworkUtil`. What could be the problem. – Program-Me-Rev Apr 03 '16 at 18:04
  • FrameworkUtil is a class from the org.osgi.framework package. The same package of Bundle. What version of OSGi you use? – Marcos Zolnowski Apr 03 '16 at 18:11
  • I'm totally new to OSGi. I'm not sure how to check for the OSGi version. I'm using BND tools in eclipse Mars.2 Release (4.5.2) – Program-Me-Rev Apr 03 '16 at 18:16
  • No problem, because the system doesn't tell you. Can you tell me the version of `org.osgi.framework` package? – Marcos Zolnowski Apr 03 '16 at 18:22
  • I just updated the Question with some new info, while I try to find out about the `org.osgi.framework package` – Program-Me-Rev Apr 03 '16 at 18:29
  • 1
    Some versions of bndtools has issues with generics. But I am not sure now. You could try to cast: `FrameworkUtil.getBundle((Class) myClass)` – Marcos Zolnowski Apr 03 '16 at 18:36
  • I've moved this issue to [this question : **The method getBundle(Class) is undefined for the type FrameworkUtil**](http://stackoverflow.com/questions/36389583/the-method-getbundleclasscapture1-of-extends-myclass-is-undefined-for-the). I'll accept your answer shortly. First let me try getting `FrameworkUtil.getBundle` and `bundle.getBundleContext()` to work. Thank you so much for the help so far. – Program-Me-Rev Apr 03 '16 at 18:56
  • The only way I can think of loading the CSS onto a JavaFx scene is by passing the URL to an `OutputStream` then creating a *temporary* css file to load onto the scene. Can you think of another simpler way to do this? – Program-Me-Rev Apr 03 '16 at 22:18
  • Rather than using static hacks like `FrameworkUtil.getBundle`, it's *much* better to obtain your `BundleContext` by implementing a bundle activator or DS component with an `activate` method. – Neil Bartlett Apr 03 '16 at 22:38
  • A static field holding the context, or something with XML, is not **much** better to me. – Marcos Zolnowski Apr 05 '16 at 17:16