Create OSGi compatible components

If you want to create an OSGi compatible component in a separate bundle then you should be aware about several aspects: * Making OSGi compatible jar * Whether you have classes which need to be discovered by Vaadin * Static resource registration

All those aspects are already shortly covered in the basic tutorial Vaadin OSGi Support since there are common parts, but we’ll go through them here in more depth and in regards to component bundle creation.

In all simplicity, an OSGi compatible bundle is just a jar file with the proper manifest file.

Making OSGi compatible jar

Every OSGi compatible jar should have a proper manifest file which is located by the path /META-INF/MANIFEST.MF.

You can hardcode this file or use a maven plugin which generates the manifest for you from a template file. Here is the code snippet for your pom.xml which generates the /META-INF/MANIFEST.MF file and tells maven Jar plugin to use this manifest.

 <build>
    <plugins>
        <plugin>
            <groupId>biz.aQute.bnd</groupId>
            <artifactId>bnd-maven-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <goals>
                        <goal>bnd-process</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.0.2</version>
            <configuration>
                <archive>
                    <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

It requires a bnd.bnd file which needs to be located in your project root folder:

Bundle-Name: ${project.name}
Bundle-Version: ${project.version}
Bundle-SymbolicName: ${project.groupId}.${project.artifactId}
Export-Package: com.example.mycomponent
Import-Package: *

Making Java classes being discovered by Flow

If you want to extend somehow a Vaadin application behavior in your bundle then you should mark your bundle using Vaadin-OSGi-Extender manifest header. E.g. you may want to provide a HasErrorParameter implementation class which handles your own exception type (or you are making an extension which has some routes). You bundle won’t be scanned for such classes if there is no Vaadin-OSGi-Extender header. So you should include this header if there are extension classes:

...
Export-Package: com.example.mycomponent
Import-Package: *
Vaadin-OSGi-Extender: true
...

Static resource registration

Your component may requires some static files which should be available via HTTP. E.g. this component relies on JavaScript file:

@JavaScript("src/my-component.js")
public class MyCoponent extends Div {

}

You normally use standard locations for static resources since your jar should work also in non OSGi environment. So let’s assume your resource folder is META-INF/resources.

Note
If you use maven then all resources are located inside src/main/resources folder. So the full path of the static resources directory is src/main/resources/META-INF/resources.

This resource should be registered via the way provided by Vaadin OSGi integration. We are using OsgiVaadinStaticResource service interface since there is only one resource. The resource path in the jar file is /META-INF/resources/frontend/src/my-component.js and it should be registered to be available by URI /frontend/src/my-component.js (so the full URL e.g. is "http://localhost:8080/frontend/src/my-component.js"):

@Component
public class MyComponentResource implements OsgiVaadinStaticResource {

    public String getPath(){
        return "/META-INF/resources/frontend/src/my-component.js";
    }

    public String getAlias(){
        return "/frontend/src/my-component.js";
    }

}
Note
Your component project will most likely use webjars (see Integrating a Web Component). You should be aware of the fact that webjars are not OSGi compatible. So webjar archive is not an OSGi bundle and cannot be deployed to an OSGi container. So resources in webjar won’t be available via HTTP out of the box for you. Here Vaadin OSGi Support we have a working suggestion for this issue via repackaging.