Maven Eclipse Plugin and Eclipse PDE: The Right Configuration

pom.xml

As noted on the Maven Eclipse plugin website, a two additional plugins need to be added to the project‘s pom. These copy the dependencies‘ jar files into the project folder and remove them on the eclipse:clean command. I found it helpful to add a further antrun plugin, which copies the MANIFEST.MF file generated by the maven bundle plugin. Therewith, the following additions can be made to the pom.xml

<!– MAVEN ECLIPSE PLUGIN –>
<!–

                                Dependency Plugin used to copy the dependency JARs into the root
                                project folder. There the Maven eclipse plugin will add them to the
                                classpath of PDE projects.
                        –>
                        <plugin>
                                <artifactId>maven-dependency-plugin</artifactId>
                                <executions>
                                        <execution>
                                                <id>copy-dependencies</id>
                                                <phase>process-sources</phase>
                                                <goals>
                                                        <goal>copy-dependencies</goal>
                                                </goals>
                                                <configuration>
                                                        <outputDirectory>${basedir}</outputDirectory>
                                                        <overWriteReleases>false</overWriteReleases>
                                                        <overWriteSnapshots>false</overWriteSnapshots>
                                                        <overWriteIfNewer>true</overWriteIfNewer>
                                                </configuration>
                                        </execution>
                                </executions>
                        </plugin>

                        <!–
                                Cleanup necessary because of PDE tweaks, clear the project directory
                        –>
                        <plugin>
                                <artifactId>maven-clean-plugin</artifactId>
                                <version>2.3</version>
                                <configuration>
                                        <filesets>
                                                <fileset>
                                                        <directory>${basedir}</directory>
                                                        <includes>
                                                                <include>*.jar</include>
                                                        </includes>
                                                        <followSymlinks>false</followSymlinks>
                                                </fileset>
                                        </filesets>
                                </configuration>
                        </plugin>

                        <!–
                                Keep the MANIFEST.MF used by eclipse in sync with the MANIFEST.MF
                                created by the maven bundle plugin
                        –>
                        <plugin>
                                <artifactId>mavenantrunplugin</artifactId>
                                <executions>
                                        <execution>
                                                <phase>package</phase>
                                                <goals>
                                                        <goal>run</goal>
                                                </goals>
                                                <configuration>
                                                        <tasks>
                                                                <delete file=“${basedir}/META-INF/MANIFEST.MF” />
                                                                <copy file=“target/classes/META-INF/MANIFEST.MF” tofile=“${basedir}/META-INF/MANIFEST.MF” />
                                                        </tasks>
                                                </configuration>
                                        </execution>
                                </executions>
                        </plugin>

Maven arguments

As mentioned before, Maven should be called with an additional argument to assure that the eclipse plugin does not attempt to define links between the eclipse plugins. One way of generating the eclipse meta-data is the following:

mvn eclipse:clean clean package eclipse:eclipse -Declipse.pde -Declipse.useProjectReferences=false install

Google Docs API: UnsupportedDataTypeException MIME type application/atom+xml

Problem

When trying to use the Google Docs API inside an OSGi bundle, the following exception is thrown, for instance when trying to upload a document:

javax.activation.UnsupportedDataTypeException: no object DCH for MIME type application/atom+xml
        at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:877)
        at javax.activation.DataHandler.writeTo(DataHandler.java:302)

Solution

Again this problem requires some tweaking with classloaders. The following code added before and after updateMedia helped in my case:

Thread cur = Thread.currentThread();
                
ClassLoader ccl = cur.getContextClassLoader();
                 ClassLoader classLoader = this.getClass().getClassLoader();
                 cur.setContextClassLoader(classLoader);
MediaMultipart.loadMimeMappings();

entry.setMediaSource(source);
entry.setEtag(“*”);

DocumentListEntry e = entry.updateMedia(true);

cur.setContextClassLoader(ccl);

XStream: Cannot create java.beans.PropertyChangeSupport by JDK serialization

Problem

When attempting to serialize a bean, which uses property change support, XStream throws the following exepection.

message : Cannot create java.beans.PropertyChangeSupport by JDK serialization : null
cause-exception : com.thoughtworks.xstream.converters.reflection.ObjectAccessException

Solution

The only solution I found was to ignore the field pointing to the PropertyChangeSupport class in the class, which is to be serialized by adding „transient“.

private transient PropertyChangeSupport propertySupport;

Maven-Eclipse-Plugin: Problem with Project Dependencies

Problem

When creating eclipse meta-data with the maven-eclipse-plugin for plug-in projects, other related projects, which are part of the same eclipse workspace are not added to the project‘s classpath.

Therewith, the project, although it compiles without problems in maven, shows syntax errors such as „[class] cannot be resolved“ and „No available bundle exports […]“.

Solution

One way is to manually disable the feature of the plugin, which tries to configure the project references. You can create the projects using the following command:

mvn eclipse:clean clean package eclipse:eclipse -Declipse.pde -Declipse.useProjectReferences=false install

Another way is to change the way you name your projects. Apparently, the plugin expects the project names to be equal to the Maven artifactIds.

You can also provide your own template for project names using -DprojectNameTemplate=[groupId]-[artifactId].

Resources

Project dependency issue with maven-eclipse-plugin 2.6 (Func Community)
JIRA bug on autodiscovery of project dependencies with the plugin
maven-eclipse-plugin 2.6 project references (Mail)

Cannot find lifecycle mapping for packaging: ‘bundle’.

Problem

When trying to package or install a project using the maven-bundle-plugin, an error message as the following is given:

[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Cannot find lifecycle mapping for packaging: 'bundle'.
Component descriptor cannot be found in the component repository: org.apache.maven.lifecycle.mapping.LifecycleMappingbundle.

Solution

I could resolved the problem by including the element <extensions>true</extensions> to the plugin definition for the maven-bundle-plugin.

<plugin>
                                <groupId>org.apache.felix</groupId>
                                <artifactId>maven-bundle-plugin</artifactId>
                                <extensions>true</extensions>
                                <configuration>
                                        <instructions>
                                                <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
                                                <Bundle-Version>${pom.version}</Bundle-Version>
                                                <Embed-Dependency>${module.embeddedDependencies}
                                                </Embed-Dependency>
                                                <Embed-Directory>target/dependency</Embed-Directory>
                                                <Import-Package>${module.importedPackages}</Import-Package>
                                                <Export-Package>${module.exportedPackages}</Export-Package>
                                        </instructions>
                                </configuration>
                        </plugin>

Resources

Probblem with maven-bundle-plugin (“Cannot find lifecycle mapping for packaging: ‘bundle”) (Felix Mailing list)

Version Ranges in OSGi and Maven

Version ranges have slightly different meaning in OSGi and Maven.

in OSGi: 1.0.0 is an earlier version than 1.0.0-SNAPSHOT, therewith 1.0.0-SNAPSHOT is in [1.0,2.0)

in Maven: 1.0.0 is a later version than 1.0.0-SNAPSHOT, therewith 1.0.0-SNAPSHOT is not in [1.0,2.0)

The usual practice in Maven is the following:
(1) Artifact is released in version 1.0.0
(2) Development is continued with version 1.0.1-SNAPSHOT
(3) Artifact is released with version 1.0.1

Resources

EclipseCon presentation Maven, Eclipse and OSGi working together

Module Pattern

Design patterns are a well-established concept for the design of classes and their relationships in object oriented programming. Build tools like Maven can encourage us to think of similar patterns for modules or libraries. In Maven, every module or library (a project in Maven terms) is described by a project model (pom file). Modules which share similar pom files can be the building blocks of pattern of modules.

Below are a number of ideas of different types of modules, which could constitute module patterns (these are no patterns as yet, although some patterns emerge naturally from these types)

Architecture Based

Type
Description
Interface-Module Contains only interface definitions. They can only depend on other Interface-Modules.
Plain-Module Module does not depend on any other modules.
Proxy-Module Module works as a facade to the functionality of other modules. But modules does not add much additional functionality.
Application-Module Module, which uses other modules and adds its own functionality.
Included-Module Module, which must be executed inside another module.
XPlain-Module Plain modules, which only depends on Interface modules.
Module-Execution-Environment This is not really a module but the framework, which provides the execution environment for the modules
Module-Launcher This is a application, which decides on, which modules are to be started and provides an interface to the surrounding execution environment. E.g. event such as drag and drop of files on the application icon.

Functionality Based

Type
Description
Utility A module which provides simple but many functions, which are used by many other modules.
Extension A module, which provides additional functionality for the application but must not be there. Can be grouped with other extension modules. It can be specified whether another module needs 0..n, 1..1, or 1..n of these group to operate.
Third-Party A module which contains code or reference to libraries from third parties. It is not assumed that there will be very little changes to this third party code in order to assure upgradability.
Playground Modules which are not meant to become part of the core application but are used to explore and test new features.
Test A module, whose primary purpose is to test other modules.
Facade Module which wraps one or more Third-Party modules and simplifies, abstracts and standardizes the interaction with these module.
Domain Module providing logic for a particular domain.