Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to convert existing java projects to osgi bundles

We have lot of components out of which we want to modularize only a few to start with. Wondering what is the best way (in the context of my build environment) to create bundles out of all these components?

My environment: Java 6, Maven 2.2.1, Hudson

Technologies: Spring 3.0.5, WebSphere 7, Hibernate 3.2.x and most of apache commons.

Requirements

  1. Modularize only few components. Rest of the components can export all of the packages.
  2. When imported into eclipse, I should be able to see the bundles of imported-packages as dependencies in build path (mvn eclipse:eclipse doesn't seem to do this)
like image 424
Aravind Yarram Avatar asked May 03 '12 17:05

Aravind Yarram


3 Answers

Start by only changing the MANIFEST.MF entries such that all your artifacts become bundles - they obviously won't magically work but it's a good non-destructive first step.

When using the maven-bundle-plugin ensure you set extensions and supportedProjectTypes as you may have problems with CI builds, Maven repos and m2e failing if the packaging type is bundle (see end).

Test your riskiest/core external dependencies early on - for example if you're using JPA for persistence then ensure that the provider works in an OSGi environment with your domain bundle and JDBC driver.

If you're migrating from Java EE/spring look at Karaf or Virgo. But if your components are for embedded systems or have no external dependencies the Felix or Equinox may be enough (though check out the pax-url project if that's the case).

Might be worth editing your question to be a bit more specific about the domain/technologies?


eclipse:eclipse only generates that when the project is first configured, m2e's lifecycle problems might be a bit of pain but it's far better than using the old eclipse plug.


The following will add manifest entries to your existing artifacts without changing them in any other way. It tells the standard maven jar and war plugins to use the MANIFEST.MF generated by maven-bundle-plugin.

Put this in the parent POM:

<pluginManagement>
<plugin>
    <groupId>org.apache.felix</groupId>
    <artifactId>maven-bundle-plugin</artifactId>
    <version>2.3.7</version>
    <extensions>true</extensions>
    <configuration>
        <archive>
            <addMavenDescriptor>true</addMavenDescriptor>
        </archive>
        <supportedProjectTypes>
            <supportedProjectType>jar</supportedProjectType>
            <supportedProjectType>war</supportedProjectType>
        </supportedProjectTypes>
        <instructions>
            <Built-By>${project.organization.name}</Built-By>
            <Bundle-Vendor>${project.organization.name}</Bundle-Vendor>
            <Bundle-ContactAddress>${project.organization.url}</Bundle-ContactAddress>
            <Bundle-Description>${project.description}</Bundle-Description>
            <Bundle-DocURL>${bundle.doc.url}</Bundle-DocURL>
            <Bundle-Category>${bundle.category}</Bundle-Category>
            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
            <Bundle-Version>${project.version}</Bundle-Version>

            <Import-Package>*</Import-Package>
            <Export-Package>*</Export-Package>
        </instructions>
    </configuration>
    <executions>
        <execution>
            <id>bundle</id>
            <goals>
                <goal>manifest</goal>
            </goals>
            <phase>prepare-package</phase>
            <inherited>true</inherited>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
        <archive>
            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
        </archive>
    </configuration>
</plugin>

<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <executions>
        <execution>
            <id>create-war</id>
            <phase>package</phase>
            <goals>
                <goal>war</goal>
            </goals>
            <inherited>true</inherited>
        </execution>
    </executions>
    <configuration>
        <archive>
            <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
        </archive>
    </configuration>
</plugin>
</pluginManagement>

Then in child POMs, you may simply do:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
        </plugin>
        <!-- Below is mutually exclusive: Either jar or war plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
        </plugin>
    </plugins>
</build>
like image 59
earcam Avatar answered Oct 20 '22 01:10

earcam


Take a look at bndtools, it has excellent support for creating projects that wrap bundles. It provides a lot of insight how JARs are structured and how they depend on other things.

like image 28
Peter Kriens Avatar answered Oct 20 '22 01:10

Peter Kriens


Use the maven bundle plugin. It will add the required import and export statements to you manifest based on scanning your code and the dependencies defined in the pom. This will require the least amount of effort to convert.

I also recommend you use M2Eclipse instead of mvn eclipse:eclipse. It will keep your maven config and workspace in sync.

like image 38
Robin Avatar answered Oct 19 '22 23:10

Robin