Don’t get me wrong I really like Maven. It’s a great and technically mature build system. Nevertheless I try to avoid it in all my RCP and OSGi projects because all that POM declarations are redundant and unnecessary in some way. Inter bundle dependencies are expressed by means of OSGi manifests and the build process provided by the Eclipse environment respectively the headless PDE build is more than adequate. Obviously this is just a matter of taste and if you use Tycho or other IDEs with the better Maven support, maybe you will not agree.
Anyway there are many existing OSGi bundles (e.g. Jetty, Vaadin, log4j, Knopflerfish) available in Maven Central and manually downloading them together with all their dependencies is a cumbersome task. Also Maven dependencies without proper OSGi metadata information can be transformed via the maven-bundle-plugin if required.
So during my experiments with the embedded XULRunner, I tried to find a mechanism that automatically adds bundles from Maven repositories to my active target platform. If you are not familiar with the concept of Eclipse target platforms read this tutorial first.
This is my best solution so far. If you have better ideas please let me know!
Create a simple project named target_platform in your workspace. In the new project create a sub folder named maven_libs. Later this sub folder is the location of all jar files fetched by Maven. Select New->Other->Target Definition and add the maven_libs folder to the list of required locations.
The path ${project_loc:/target_platform}/maven_libs works fine even if the target_platform project is outside the current workspace. Of course you can still add further locations like environment variables, folders or p2 repositories.
Create the following pom.xml definition that lists all required dependencies in your target platform project and configure the outputDirectory accordingly.
<project> <modelVersion>4.0.0</modelVersion> <name>Target Platform Project</name> <groupId>com.javahacks.sample</groupId> <artifactId>target_platform</artifactId> <version>1.0</version> <packaging>pom</packaging> <properties> <outputDirectory>maven_libs</outputDirectory> </properties> <dependencies> <!--Configure dependencies here --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.8</version> <executions> <execution> <id>copy-dependencies</id> <phase>initialize</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <overWriteReleases>false</overWriteReleases> <overWriteSnapshots>false</overWriteSnapshots> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
Now run mvn install from within Eclipse or on the command line inside the ‘target_platform’ location to fetch all libraries configured in the POM configuration.
Reopen the target definition and select Set as Target Platform. If you run Maven outside your IDE refresh the target platform project first.
This approach is also useful for the POM dependency resolution explained here. Now you have the same bundle resolution at the build and development time and running the Maven installation to setup the target platform on your build server (without Tycho) is no problem.