Saturday, 16 February 2008

A Maven Eclipse RCP Product build at last!

My sincere thanks to René Gröschke and Patrick Paulin for putting me on the right track. These notes were developed using Eclipse RCP Developer (version 3.3.1.1 "Europa").

Below, I have documented the required steps in some detail, based largely on René's tutorial. Some gotchas to watch out for include:

  • Contrary to popular belief, it is not necessary to install the Maven 2 Integration feature in Eclipse - in fact we found it confusing and removed it again, preferring to invoke various Maven goals through External Tool configurations under the Run menu
  • The build.properties file is very literal in its interpretation of properties you specify. In particular, when specifying a pathname, you must use forward slashes even under Windows, you must not have spaces in the pathname and you cannot enclose it in quotation marks. And most particularly, you cannot use symbolic references to any other property or environment variable (although the template supplied with the Eclipse PDE build plug-in misleads you here by suggesting that you can use ${user.home} as part of the buildDirectory property) - otherwise you will see the dreaded error message: Content Provider not set for Site: "{0}".
  • You must specify a target platform in the base location that has had the Eclipse RCP Delta Pack installed, otherwise you may be able to build using PDE but you won't generate an executable.

It is recommended to download both the RCP Runtime for your expected target platform architecture(s) and the RCP Delta Pack. Install each target platform RCP runtime into its own location - e.g. if you have installed Eclipse in C:\tools\eclipse, I would suggest unzipping the RCP Runtime for 32-bit Windows on Intel x86 processors to C:\tools\eclipse\win32.win32.x86\eclipse. Unzip the delta pack into each of the targets. Let it overwrite all clashing filenames. Afterwards, if you are short of space, you can go through each Eclipse target platform and safely delete any plugins or features that don't correspond to the selected target architecture.

Having installed the target platform(s), it is probably a good idea to set the default Eclipse workspace target platform to the one for the type of workstation you are running on - e.g. if you're using a 32-bit Windows / Intel x86 computer, select Window -> Preferences -> Plugin Development -> Target Platform and browse to C:\tools\eclipse\win32.win32.x86\eclipse (vary this path depending on the location of your Eclipse target platform). This ensures that native Eclipse builds and product exports will correspond as closely as possible to those built by the PDE in "headless" mode.

Another thing you need to do is to doctor the POM of the pde-maven-plugin (snapshot) so that it doesn't depend on outdated versions of org.eclipse.pde.core and org.apache.maven.shared.maven-osgi. Here is one way to do it:

    <dependency>
<groupId>org.eclipse.pde</groupId>
<artifactId>core</artifactId>
<version>[3.3.0,4.0.0)</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-osgi</artifactId>
<version>[0.1.9,)</version>
</dependency>

Make sure you catch all copies of the POM. You can do this in your local Maven repository after a first attempt to build, or more permanently on your project repository. You can use the eclipse:to-maven goal to get Eclipse plugins from the target platform folder into your local and/or project repository.

Let's work through a complete though simple example of creating an Eclipse RCP application that can be built from the command line using Maven. Broadly, this has the following stages:

  1. Create the RCP application
  2. Create a product configuration file
  3. Create a build.properties file
  4. Make a Maven POM
  5. Run it and test the result

Steps A-C are identical to what you would do if you wanted to create a project capable of supporting headless PDE builds. The only concessions to Maven are the layout of the source and output directories and the fact that we do not specify an eclipseLocation property in the build.properties file - this is instead configured in the Maven POM as the eclipseInstall parameter.

Now, are you sitting comfortably in front of your Eclipse IDE? Then follow the bouncing ball...

A. Create the RCP application

  1. Start a new project: File -> New -> Project -> Plug-In Project
  2. Set project name = "com.breskeby.tutorial.rcp.withMaven"
  3. Uncheck "Default location"
  4. Specify a location outside the Eclipse workspace, e.g. C:\data\eclipseProjects\plugins\com.breskeby. tutorial.rcp.withMaven
  5. Set Source folder = src/main/java (following the Maven convention)
  6. Set Output folder = target/classes
  7. Next
  8. Check "Generate an Activator" and "This plugin will contribute to the UI"
  9. Check "Create an RCP Application"
  10. Next
  11. Select the template "Hello RCP"
  12. Next
  13. Change the application window title to "Hello RCP with Maven"
  14. Finish
  15. If asked, decide whether to open the Plugin Developer perspective (it probably is not worth it at this stage)
  16. Test the new plugin by clicking "Launch an Eclipse Application"

B. Create a product configuration file

  1. File -> New -> Other -> Product Configuration
  2. Parent folder = com.breskeby.tutorial.rcp.withMaven
  3. Filename = withmaven.product
  4. Check "Create a configuration file"
  5. Finish - the product overview is displayed
  6. Set Product Name = "RCP with Maven Example"
  7. Product ID: click New...
  8. Accept default values except Product Application
  9. Set Application = "com.breskeby.tutorial.rcp.withMaven"
  10. Finish
  11. Check "Product Configuration based on plug-ins"
  12. Click on the Configuration tab and click "Add..."
  13. Select com.breskeby.tutorial.rcp.withMaven and click OK
  14. Click "Add required plug-ins"
  15. Save the product configuration
  16. Test by right-clicking on the withmaven.product file in the package explorer and selecting "run as..." -> "Eclipse Application"

C. Create a build-properties file

  1. Right-click the project folder com.breskeby.tutorial.rcp.withMaven and select New -> Folder: name the folder "buildConfiguration"
  2. In Windows Explorer or equivalent, find your Eclipse installation and navigate down to eclipse/plugins/org.eclipse.pde.build_*/template/headless-build. Copy build.properties from this file to the clipboard. Paste it into your new buildConfiguration folder in Eclipse. The asterisk in the above path stands for the version number of the Eclipse PDE builder. Make a note of it, as you'll need it in step D
  3. Open the build.properties copy in an Eclipse text editor and click on the build.properties tab. Change the following properties:
    1. product=withmaven.product
    2. archivePrefix=withMaven
    3. configs=win32, win32, x86 or change depending on your desired target(s) - but René has noted that only one target architecture can be built at a time
    4. buildDirectory=[project directory]/target/eclipse.build (substitute the pathname of your project directory - see step A4 above - but use forward slashes)
    5. buildId=withMaven
    6. base=C:/tools/eclipse/win32.win32.x86 (depends on where you installed the target platform and which configuration you specified in configs - item c above). The base directory must contain a folder called "eclipse", which contains folders named "features" and "plugins"
    7. pluginPath=.
    The plugin path is the list of places to be searched for features and plugins needed during the build. In this case, the current working directory (i.e. the project directory) is fine, since the product build first creates the plugin in a plugins subdirectory.

D. Make a Maven Project Object Model (POM)

  1. Right-click the project folder com.breskeby.tutorial.rcp.withMaven and select New -> File: name the file "pom.xml"
  2. Into the new file, copy the template XML below
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.breskeby.tutorials.rcp</groupId>
    <artifactId>withMaven</artifactId>
    <packaging>zip</packaging>
    <name>RCP With Maven Example</name>
    <version>1.0-SNAPSHOT</version>
    <description>A Simple Product PDE Example</description>
    <build>
    <plugins>
    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>pde-maven-plugin</artifactId>
    <version>1.0-alpha-2-SNAPSHOT</version>
    <extensions>true</extensions>
    <configuration>
    <eclipseInstall>${env.M2_HOME}/../eclipse</eclipseInstall>
    <pdeProductFilename>withmaven.product</pdeProductFilename>
    <pdeBuildVersion>3.3.2.R331_v20071019</pdeBuildVersion>
    </configuration>
    </plugin>
    </plugins>
    </build>
    </project>
  3. Modify the configuration section as follows:
    1. eclipseInstall - this is the path to your Eclipse RCP Developer installation (e.g. C:\tools\eclipse in the above example). Because my current project follows a convention about installing all tools in one place, I was able to use a property for this as shown above - your mileage may vary
    2. pdeBuildVersion - insert the version number copied from the pathname of the folder whose name begins "org.eclipse.pde.build_" (see step C2 above)

E. Run the build and test the result

  1. Make sure all edited files have been saved
  2. Ensure that your settings.xml is configured such that the required Maven snapshot repository is searched for plugins
  3. Select the pom.xml file in the package explorer
  4. Set up and use an external tool configuration to invoke Maven or run it from a command-line in the project directory: mvn clean install
  5. The result turns up in [project directory]/../../I.withMaven/withMaven-[architecture].zip - unzip it, open the resulting folder and double-click the executable you have just built!

I hope that you have found this useful. If you run into snags, please check that you have followed all the above steps to the letter before contacting me (if you leave a comment on this blog I should be notified by e-mail).

35 comments:

Archimedes Trajano said...

Hi, it is a useful start. Though I am still not able to do an mvn install.

Can you add the settings.xml file you are using?

Immo Hüneke said...

In response to the request for settings.xml file - I find it difficult to post this, as it may contain customer confidential details. I will have to create a cut-down version. Watch this space.

Archimedes Trajano said...

Actually the minimum I need is to get the snapshot repositories going because I can't seem to get the alpha-2-SNAPSHOT of the pde-maven-plugin.

I tried following the instructions http://maven.apache.org/guides/development/guide-plugin-snapshot-repositories.html but it still says it cannot find the snapshot of the plugin.

Immo Hüneke said...

Hi Archimedes, you can find the plugin snapshot at http://snapshots.maven.codehaus.org/maven2 (I have now published a cut-down form of my settings file as a new post).

Unknown said...

hi very good information on this page although i still do not have a working pde build. I have spent quite a bit of time fighting with the version range issue [3.3.0-4.0.0) doesn't include 3.3.0-v20070513 etc. which i have been able to rig but not resolve. the other issue that i am facing right now is that the mvn install command does not run the pde build it simply runs the compile command and exits and i am left with a jar of my compiled classes =(. i have to explictly run mvn pde:pde which seems weird because ever other place i have looked uses mvn install.

Immo Hüneke said...

Hi Stephen,

It looks to me as if your POM's packaging type has not been changed from the default (jar) to zip. If you do that then the PDE build is invoked, not otherwise.

Best regards,
Immo.

Ben said...

Hi,

This is very useful information. Thank you. We are now able to build our own rcp application using maven. One thing that bugs me though is the location in which everything is build:
[projectdirectory]/../../I.withMaven/

What we really want, is to have everything in:
[projectdirectory]/target/

I managed to do this by adding the following build property in the POM:
<buildDirectory>
${project.build.directory}
</buildDirectory>

However, then 'mvn install' fails at the very end, because it cannot find the artifact to be installed in my local repository. It's looking for it in:
[projectdirectory]/../../I.withMaven/

Do you have any ideas how to solve this?

Regards,
Ben

Immo Hüneke said...

Hi Ben,

Like you I have discovered recently that the buildDirectory property can be set in the POM. This is immensely useful, because it eliminates the need for absolute pathnames in the build.properties file. Maven is much better at resolving paths defined as relative or in terms of property values.

However, I think what you're trying to do is against the spirit of the Eclipse PDE build mechanism. If you remember that a product consists of any number of plugins and features, it becomes clear why Eclipse PDE wants the build directory to _contain_ folders called "plugins" and "features", not the other way around. You may also have found that the build generates a default feature for a product that consists of plugins only, and it places that under ${project.build.directory}/../../features.

We have decided to bow to the inevitable and restructure our Subversion repository to conform to Eclipse PDE conventions (or at least to check out the source code in such a way that the resulting workspace is in conformance). See also http://help.eclipse.org/help33/topic/org.eclipse.pde.doc.user/guide/tasks/pde_product_build.htm

Pat and Phil said...

Apologies in advance...I'm sure I'm just being dumb here.

I've been through this procedure twice, and get the same results each time. I'm sure I'm missing something, but I've looked and looked until my eyes bleed, and I can't see what I'm doing wrong.

The problem is that when I get to the stage of doing mvn clean install, I get the following exception:

java.lang.NullPointerException
at org.codehaus.mojo.pde.AbstractEclipsePDEMojo.findStartupJar(AbstractEclipsePDEMojo.java:225)
at org.codehaus.mojo.pde.AbstractEclipsePDEMojo.initialize(AbstractEclipsePDEMojo.java:188)
at org.codehaus.mojo.pde.EclipsePDEMojo.initialize(EclipsePDEMojo.java:86)
at org.codehaus.mojo.pde.AbstractEclipsePDEMojo.execute(AbstractEclipsePDEMojo.java:168)
at org.codehaus.mojo.pde.EclipsePDEMojo.execute(EclipsePDEMojo.java:95)
at org.codehaus.mojo.pde.EclipsePDEExtMojo.execute(EclipsePDEExtMojo.java:48)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:443)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:480)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:459)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:311)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:278)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:143)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:334)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:125)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:272)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)

If anyone can show me where I'm being dumb, that would be great.

Thanks

Immo Hüneke said...

Hi Phil,

That's very odd. Are you able to confirm that you are using the correct version of the pde-maven-plugin? We use 1.0-alpha-2-SNAPSHOT, because the earlier released version didn't support the new launcher in Eclipse 3.3. You can download it from http://snapshots.repository.codehaus.org/org/codehaus/mojo/pde-maven-plugin/1.0-alpha-2-SNAPSHOT/ and install it in your local repository or deploy it in your project repository.

Another thing you need to do is to doctor the POM of the pde-maven-plugin so that it doesn't depend on outdated versions of org.eclipse.pde.core and org.apache.maven.shared.maven-osgi, as described in my original posting.

If none of these measures help, send me a copy of your POM and a dump of the directory structure within which you're trying to build. I might be able to spot something.

To conclude, I would like to mention that for various reasons we have gone away from the use of the pde-maven-plugin. The fact that it was still in SNAPSHOT state months after the release of Eclipse 3.3 didn't inspire confidence, but in particular we wished to build individual plug-ins as jar files - so we developed an Ant script to invoke the PDE build directly and copy the resulting jar file to the location from which the standard Maven build lifecycle expects to deploy it. It isn't yet perfect, but it can now support multi-module builds, generate Clover coverage reports and all the other standard site stuff, build individual plug-ins and features as well as stand-alone products. I intend to give a fuller description in my blog in the near future.

Pat and Phil said...

Hi Immo,

Sorry about the delay, I've been on other things recently. We have the same requirements as you describe...i.e. building individual plugins as jars etc, so I think I'll wait for your description of your ant file.

Thanks

Phil said...

Strange bug in the headless build scripts - if you have an equinox source jar in plugins (mine is org.eclipse.equinox.launcher.source_1.0.100.v20080509-1800.jar), the script will try to build with that instead of the binary jar. The work-around I found was to remove the source jar from the plugins folder.

(note: not same Phil as was posting above :)

Immo Hüneke said...

Hi Phil,

Thanks for this interesting observation. My hypothesis would be that the bundle symbolic name in the source plug-in's manifest is incorrect and duplicates the binary plug-in. In which version of Eclipse did you encounter this?

Note that it isn't normally recommended to build with the current Eclipse installation as the Eclipse RCP target. The Eclipse Runtime plus Delta Pack is supposed to be used for that, to which you need to add any extra features/plug-ins you need in your application.

Immo.

Struhs said...

I have followed the steps exactly, but continue to get this error.

Couldn't find a version in [3.2.1-R32x_v20060914, 3.3.0-v20070604, 3.3.0-v20070530] to match range [3.3.0,4.0.0) org.eclipse.core:resources:jar:null

I have addded a dependencyManagement section to the pom to try to overcome this, but it does not work. This is what I added. Does anybody else have the same problem?
( sorry had to change below tags to brackets so blogger would post )
[dependencyManagement]
[dependencies]
[dependency]
[groupId]org.eclipse.core[/groupId]
[artifactId]resources[/artifactId]
[version3.3.0-v20070604[/version]
[/dependency]
[/dependencies]
[/dependencyManagement]

Immo Hüneke said...

Struhs, most people do not realise that Maven views qualifiers differently than Eclipse does. Because of the idiosyncratic idea that 1.2.3-SNAPSHOT precedes the release version 1.2.3, the same principle has been extended to all qualifiers. In this instance the available versions in the Maven repo are all "below" the range that the dependency specifies.

Unfortunately the maven-eclipse-plugin doesn't know about Eclipse version ranges either. It simply copies them verbatim to the POM that it uploads to the Maven repository during the execution of the to-maven goal.

I found that it was possible to defeat this by using version 2.4 of the eclipse-maven-plugin, which is the only one I have found that produces half-way usable results. The subsequent versions 2.5 and 2.5.1 do fix a few bugs, but they no longer fix the versions of dependencies in generated POMs. They also change the naming convention to make the artifact ID identical to the bundle symbolic name of each uploaded Eclipse plug-in.

We have stuck with version 2.4 but had to solve a few problems in a handful of plug-ins, where it was unable to parse the manifests correctly (org.eclipse.help.base, org.apache.xerces, org.apache.xml.resolver, if I recall correctly). We just used some Ant script to modify the manifests of these plug-ins to resolve the problem. This in turn leads to checksum errors when displaying the Plugin Information in the Help dialog of completed RCP products, but for the moment we can live with that. More seriously, the same checksum errors may prevent the update manager from working correctly.

We've developed a custom version of the maven-dependency-plugin, which analyses the bundle manifest of each plug-in it copies in order to generate the target filename and see whether it needs to be unpacked. So we don't need the artifact renaming capability of the maven-eclipse-plugin version 2.5X. The result is that we can express dependencies in POMs much more naturally.

kiwi said...

I am new to RCP and Maven.I have couple questions to try this tutorial. with Eclipse version is 3.3.2 and pde-maven-plugin 1.0-SNAPSHOT.

Question 1:
I ran: mvn clean install and I got the zip file successfully. I unzip the file and ran launcher.exe, in the log I got error
!MESSAGE Authorization infrastructure (org.eclipse.core.runtime.compatibility.auth) not installed.
java.lang.NoClassDefFoundError: org/eclipse/core/internal/runtime/auth/AuthorizationHandler
at org.eclipse.core.internal.runtime.InternalPlatform.initializeAuthorizationHandler(InternalPlatform.java:603)
at org.eclipse.core.internal.runtime.InternalPlatform.start(InternalPlatform.java:745)
at org.eclipse.core.internal.runtime.PlatformActivator.start(PlatformActivator.java:31)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$2.run(BundleContextImpl.java:999)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:993)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:974)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:346)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:350)
at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1118)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:634)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:508)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:282)
at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:468)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:195)
at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:297)
Caused by: java.lang.ClassNotFoundException: org.eclipse.core.internal.runtime.auth.AuthorizationHandler
at java.lang.ClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClassInternal(BundleLoader.java:429)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:369)
at org.eclipse.osgi.framework.internal.core.BundleLoader.findClass(BundleLoader.java:357)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:83)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
... 16 more

Question 2:
After I ran mvn, I went back to Eclipse and I got the same error when try to run withmaven.product.
And I try to launch it from plugin.xml, I got error:
org.osgi.framework.BundleException: The activator com.breskeby.tutorial.rcp.withmaven.Activator for bundle com.breskeby.tutorial.rcp.withMaven is invalid

Any suggestion ? Thank you in advance.

kiwi said...

Hi,

Please ignore my questions. I figure them out.

The error message listed in question 1 is the bug of Eclipse. It will not really affect the plugin running.

About the question 2, it is because when run "mvn clean install", the folder target\classes is cleaned. In Eclipse, re-build it, all the classes will be generated into target\classes. And then everything is good.

Thank you

Immo Hüneke said...

Hi Kiwi,

Sorry, I meant to respond sooner, but I am pleased that you managed to find the answer quicker than I could.

Regarding your second point, that is true, though I have found that if you configure the build path correctly in Eclipse, then the problem goes away. The secret is to set the default output folder in the Source tab to [project_folder]/target/classes instead of [project_folder]/bin.

To do the same for your unit test modules, tick "allow output folders for source folders" and then expand the source folder [project_folder]/src/test/java. Edit its output folder, select "Specific output folder" and type in the following path:

target/test-classes

This means that Eclipse will compile code into the same folders as Maven, so the two won't fight any more.

kiwi said...

Thank you very much.

rob said...

Thank you for your information! However, for a maven dummy as I am, there are some maven details missing.
- Where is the settings.xml to place?
- How to ensure that the
settings.xml is configured such that the required Maven snapshot repository is searched for plugins?
- Does a eclipse plugin (q4e or m2eclipse: would you recommend one?) help?

Immo Hüneke said...

Hi Rob,

There are actually two files called settings.xml - one is in the folder .m2 under your home directory, the other in the configuration folder under the Maven installation directory. By starting Maven with the -s switch, you can override the first of these, but I think the second will still be processed and will set any properties that are not set by the first.

So I would suggest you configure the repositories in the user settings file, as it is then easy to switch to a different set of repositories for specialised builds by specifying a different settings file.

The documentation under the Maven Settings Reference is pretty comprehensive in explaining how to specify repositories. One thing to be aware of is that each repository is searched for every artifact needed in the build, which means that you should specify as few as possible. A gateway such as maven-proxy helps you to manage this search process. It lets you combine multiple repositories into one virtual repo, so your settings need only ever specify one snapshot repository and one release repository.

Immo Hüneke said...

Oh, and I forgot to add - I looked into m2eclipse early on, but found that it didn't provide anything like as good an integration as the Maven plugin for IntelliJ IDEA. Moreover, it confused users, as there were now two different ways to achieve a maven build. I think some of these Eclipse plug-ins have probably improved over time, so it might be time to look at them again.

rob said...

Thank you, immo!

Two concrete question remain for me.

1. Should I be able to perform my build without an own settings file using the default settings of maven?

2. If yes (which I tried), I get the message that the pde-maven-plugin version 1.0-alpha-2-SNAPSHOT cannot be downloaded. I tried a bit and found that the version 1.0-alpha-1 can be downloaded but using it runs
into a build error. Do you can give me help?

Immo Hüneke said...

Hi Rob,

As you can see from other comments on this page, I discussed this with Archimedes Trajano on 22 February 2008 and again with Phil on 23/24 May. The plugin can be found in the Codehaus snapshot repository. I have just taken a look and there still doesn't seem to be anything more recent available.

But in searching for this, I found another useful article about building Eclipse plug-ins using Maven 2.

rob said...

Understood! So I will create a settings.xml to use the Codehaus snapshot repository.

The article you mentioned is very detailed and I'm sure I will succeed with it.

Thanks a lot!

rob said...

Hi immo,

I have now my RCP product (Eclipse Ganymede) deployed by maven 2.0.7.

Your information enriched by some additional information I found also in http://www.zuehlke.com/fileadmin/pdf/fachartikel/131_eclipse_magazin_ums_my_plugin.pdf,
however, this article is written in german.

A last question I dare to ask:

The resulting zip-file of my deployment lacks an eclipse.exe file. Adding it manually after extracting the zip I can successfully start the application.

Do have an idea what's wrong?

govind said...

Hi

This is very useful.

But I am using eclipse 3.4 and getting error when mvn clean install -e

java.lang.NoClassDefFoundError: org/eclipse/equinox/launcher/Main
Caused by: java.lang.ClassNotFoundException: org.eclipse.equinox.launcher.Main
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: org.eclipse.equinox.launcher.Main. Program will exit.
Exception in thread "main"
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Error returned by PDE build. Exit code: 1
[INFO] ------------------------------------------------------------------------
[INFO] Trace
org.apache.maven.lifecycle.LifecycleExecutionException: Error returned by PDE build. Exit code: 1
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:583)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle(DefaultLifecycleExecutor.java:499)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:478)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:330)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:291)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:142)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:336)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:129)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.MojoExecutionException: Error returned by PDE build. Exit code: 1
at org.codehaus.mojo.pde.AbstractEclipsePDEMojo.executeCommandLine(AbstractEclipsePDEMojo.java:277)
at org.codehaus.mojo.pde.EclipsePDEMojo.execute(EclipsePDEMojo.java:102)
at org.codehaus.mojo.pde.EclipsePDEExtMojo.execute(EclipsePDEExtMojo.java:48)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:451)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:558)
... 16 more
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 40 seconds
[INFO] Finished at: Tue May 26 12:59:46 IST 2009
[INFO] Final Memory: 20M/36M
[INFO] ------------------------------------------------------------------------
Any Clues??

Regards
Govind.

Immo Hüneke said...

Hi Govind,

I've seen this before - it occurs when the Eclipse launcher is not present. I suspect that the method of launching the headless build has changed in Eclipse 3.4 - you may have to modify the scripts to use the new method.

Sorry I can't be of any more help at this time, it would take me more time than I have available to modify my build environment appropriately to investigate.

Immo.

Immo Hüneke said...

Hi Govind,

Also, particularly in multi-module builds, I have found that it is not a great idea to invoke the clean and install (or deploy) goals in the same Maven invocation. The problem was that Maven would find inter-module dependencies missing due to the order in which it carried out the steps within each module.

You're probably better off running clean followed by install as separate builds and then deploy as a third one. However, Maven may have improved since then.

Best regards,
Immo

Çağlar said...

Hi,
how can we download
org.apache.maven.shared:maven-osgi:jar:0.2.0-SNAPSHOT ?

Can you give me a link?

I'm getting the following error when using mvn clean install :
Missing:
----------
1) org.apache.maven.shared:maven-osgi:jar:0.2.0-SNAPSHOT

Try downloading the file manually from the project website.

Then, install it using the command:
mvn install:install-file -DgroupId=org.apache.maven.shared -DartifactId=maven-osgi -Dversion=0.2.0-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file

Alternatively, if you host your own repository you can deploy the file there:
mvn deploy:deploy-file -DgroupId=org.apache.maven.shared -DartifactId=maven-osgi -Dversion=0.2.0-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]

Path to dependency:
1) org.codehaus.mojo:pde-maven-plugin:maven-plugin:1.0-alpha-2-SNAPSHOT
2) org.apache.maven.shared:maven-osgi:jar:0.2.0-SNAPSHOT

----------
1 required artifact is missing.

for artifact:
org.codehaus.mojo:pde-maven-plugin:maven-plugin:1.0-alpha-2-20070917.003805-1

Immo Hüneke said...

Hi Çağlar,

I'm not sure why you've asked me this question, as I know next to nothing about the Maven-OSGI plugin.

Here's what I have managed to find out: The maven-osgi-plugin is deprecated and has been replaced by a new plugin: maven-bundle-plugin. This information is from http://felix.apache.org/site/apache-felix-maven-osgi-plugin.html - it also tells you where to obtain the plugin if you still want it.

http://opensource.atlassian.com/confluence/spring/display/DOC/HowTo+build+Spring-Osgi+using+Maven+2 explains how to obtain the plugin if you need it to build Spring-OSGI. The repository location appears to be the Safehaus Repository - http://m2.safehaus.org but when I opened this it didn't appear to contain any of the org.apache artifacts. So you may have to follow the source download instructions and build it yourself, unless you can adapt your POM to use the maven-bundle-plugin instead.

Hope this helps!

Best regards,
Immo

Çağlar said...

Hi Immo, thanks for the kind reply. Let me explain:
I'm using maven 2.1.0 and pde-maven-plugin 1.0snapshot2 that you suggested and its ironic that pde-maven-plugin has a dependency on this (maven-osgi) plugin.

İ asked because it seems there weren't any dependency like that as of your blog post time. is it correct?

Immo Hüneke said...

Hi Çağlar,

At the time I published this blog post, maven 2.0.8 was the latest. The pde-maven-plugin version 1.0-alpha-2-SNAPSHOT was the only version we found that did the job correctly. You think that it's ironic that pde-maven-plugin has a dependency on the maven-osgi-plugin, but I don't agree. Clearly some software component is needed to build OSGi bundles, and this plugin must have been the best available at the time the pde-maven-plugin was published.

The dependency has always been there. The problem you are now encountering is that the maven-osgi-plugin has been deprecated. It should not have been removed from the Maven central repository, but perhaps the repository maintainers did a search and found no released software artifacts depending on it (only some ancient snapshots, which it would be reasonable to assume nobody is using any more).

Have you checked whether there is a more recent maven-pde-plugin available (or pde-maven-plugin, if it's from Codehaus) that depends on the maven-bundle-plugin instead of maven-osgi-plugin? I do think that the state of the art must have moved on since I wrote that blog post. It probably isn't a good idea to use that ancient maven-pde-plugin any more.

Best regards,
Immo.

Android app developers said...
This comment has been removed by a blog administrator.
Unknown said...

I have started to use the new Tycho plugins to manage my Eclipse plugin development now. I haven't really gone to the level of a RCP application yet, but the documents do indicate that it is possible.

If you need to see how it is structured with a live application you can go to https://github.com/trajano/tooling

There is no need for an explicit settings.xml file for the builds and all the repositories needed to install are public.

For local development, the P2 repository generated by the eclipse-repository-plugin can be used and handles SNAPSHOT versions beautifully.