-
Notifications
You must be signed in to change notification settings - Fork 20
Maven and Eclipse
While building simple Java projects is quite straightforward, building Eclipse projects is a complicated task. There is a number of factors you should consider while designing your build process. This page discusses the basic concepts and provides some tips for choosing the solution fits your project the best.
-
Maven is a build automation tool used primarily for Java projects. A large portion of the build process is dependency resolution, i.e. determining and obtaining the specified dependencies of the software (and transitively, the dependencies of the dependencies). A Maven project is defined by its Project Object Model file (
pom.xml
). - A Maven artifact is (usually) a JAR file that gets deployed to a Maven repository.
- Maven has multiple repositories:
-
The Maven Central Repository (http://search.maven.org/).
-
The local repository (the
.m2
directory in the home folder of the user). -
Other repositories for certain technologies. For example, the current EMF artifacts are not available in the Central Repository. Instead, they can be accessed from other repositories, e.g. the Acceleo repository:
<repository> <id>acceleo</id> <name>Acceleo Repository (with EMF)</name> <url>https://repo.eclipse.org/content/groups/acceleo</url> </repository>
-
- Maven is actually a plug-in execution framework; all work is done by plug-ins.
- A plug-in is used to group your code into a modular, extendable and sharable unit.
- A feature is used to package a group of plug-ins together into a single installable and updatable unit.
- Eclipse organises the work in projects.
- Builders of projects are reponsible for automatic compilation and generation of other target artifacts. For performance considerations, builders are often incremental.
- Because incremental build is a complex and error-prone process, it's sometimes required to clean the project. The clean operation deletes the generated files (generated code, binaries) and initiates a fresh build process.
- Projects can have multiple natures, e.g. Java, C++, Plug-in project etc. The nature of a project can influence the behaviour of its builders.
- The OSGi (Open Service Gateway initiative) specification describes a module system and service platform for the Java programming language that implements a complete and dynamic component model.
- OSGi components are named bundles. It's important to note that Eclipse plug-ins are also OSGi bundles.
- Equinox is an implementation of the OSGi core framework specification, a set of bundles that implement various optional OSGi services and other infrastructure for running OSGi-based systems.
- Equinox p2: The p2 project is a sub-project of Equinox that focuses on provisioning technology for OSGi-based applications.
- Update sites are used to organize and export features so they can be installed into Eclipse applications. Typically, you access update sites in the Help | Install New Software... menu by selecting the update site and the required components.
- Eclipse Project builds are stored in p2 repositories that are produced as part of the Eclipse project build process.
- The Target Platform is a collection of plug-ins which your workspace will be built and run against. You can define target definitions in
.target
files, which you can share among developers in either Eclipse workspaces or Tycho builds. - An Eclipse-based product is a stand-alone application built with the Eclipse platform. A product may optionally be packaged and delivered as one or more features, which are simply groupings of plug-ins that are managed as a single entity by the Eclipse update mechanisms. Products are defined in
.product
files.
Tycho is a set of Maven plugins and extensions for building Eclipse plugins and OSGi bundles with Maven.
Tycho translates the dependencies in the manifest file to Maven dependencies, e.g. 1.0.0.qualifier
becomes 1.0.0-SNAPSHOT
. The dependencies are searched in Maven repositories, including the Maven Central Repository and additional repositories provided by the user (in the <repositories>
element).
To use libraries such as Guava, you either need to:
-
Search an update site containing the dependency. The Orbit project contains lots of useful libraries: http://download.eclipse.org/tools/orbit/downloads/drops/repository/
-
If the library exists as a Maven artifact, then create a p2 repository from it with the p2-maven-plugin (experimental).
-
If there is only a JAR bundle of the dependency, then create a plugin from it in Eclipse as described here. Note that all transitive dependencies must also be included in the plugin manually. Tycho will not resolve the dependencies of Eclipse plug-ins transitively (documentation, demo). If you do not resolve the dependencies manually, Tycho will not be able to build the project; in Eclipse, the project will compile but will throw a runtime exception:
Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/jackson/map/ObjectMapper at hu.bme.mit.trainbenchmark.benchmark.util.JsonBuilder.build(JsonBuilder.java:14) at hu.bme.mit.trainbenchmark.benchmark.util.BenchmarkResult.toString(BenchmarkResult.java:105) at java.lang.String.valueOf(String.java:2847) at java.io.PrintStream.println(PrintStream.java:821) at hu.bme.mit.trainbenchmark.benchmark.scenarios.ModelXFormScenario.runBenchmark(ModelXFormScenario.java:24) at hu.bme.mit.trainbenchmark.benchmark.scenarios.ModelXFormScenario.runBenchmark(ModelXFormScenario.java:1) at hu.bme.mit.trainbenchmark.benchmark.scenarios.GenericBenchmarkLogic.runBenchmark(GenericBenchmarkLogic.java:23) at hu.bme.mit.trainbenchmark.benchmark.sesame.SesameBenchmarkMain.main(SesameBenchmarkMain.java:11) Caused by: java.lang.ClassNotFoundException: org.codehaus.jackson.map.ObjectMapper at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 8 more
The m2e project is part of the Eclipse IDE for Java Developers and the Eclipse for RCP and RAP Developers packages, however, it has to be installed to the Eclipse Modeling Tools package.
Using m2e is a double-edged sword as it may introduce some problems:
- Compiled JAR files are cached in the local Maven repository.
- Suppose you have two projects: project X, a plug-in project with a dependency on project Y, an EMF-IncQuery project. If you edit the patterns (
eiq
files) in project Y, the Java source files are regenerated (in thesrc-gen
directory) but project X still uses the JAR file in the local Maven repository. You have to issue theinstall
Maven command to regenerate the JAR files in the local repository.
- Suppose you have two projects: project X, a plug-in project with a dependency on project Y, an EMF-IncQuery project. If you edit the patterns (
Remark: projects that have their metadata generated with the eclipse:eclipse
goal are not compatible with m2e. The generated .project
file has the following comment:
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
So it's not surprising that using Configure | Convert to Maven project... throws an error: An internal error occurred during: "Enabling Maven Dependency Management". Unsupported IClasspathEntry kind=4
Instead of using the Maven Eclipse Plugin to generate Eclipse projects, use Import | Maven | Existing Maven Projects.
To use Tycho with m2e, you have to install the Tycho Configurator m2e connector. You may install this with the appropriate quick fix (Ctrl
+1
) operation on the error marker. Select the Discover new m2e connectors option and install the Tycho Configurator.
Tycho is capable of creating Eclipse binaries for different platforms according to the product file definition.
Examples:
- https://inf.mit.bme.hu/edu/courses/eat/materials (coming by mid-May)
-
Description:
- Each project has a POM file and a manifest file.
- There are two types of projects:
- manifest-first project: its POM file is simple and usually only contains the metadata of the artifact and the
<packaging>eclipse-plugin</packaging>
element. Their dependencies are defined in theMANIFEST.MF
file. Tycho is attempting to resolve these from the repositories defined in the POM file. An important limitation is the fact that it's not enough for the dependency to be a Maven artifact, it also has to be an OSGi bundle with p2 metadata. The dependencies in the POM file (if there are any) are ignored. - pom-first projects: its POM file looks like the one of a simple Java application. It may have multiple dependencies listed in the
<dependencies>
element. These dependencies do not have to be OSGi bundles, so you may use any dependency from the Maven Central Repository or any other repository.
- manifest-first project: its POM file is simple and usually only contains the metadata of the artifact and the
-
Advantages:
- You may mix pom-first and manifest-first projects, hence you may use Eclipse plug-ins and external dependencies (e.g. ones in the Maven Central Repository) as well.
- Unlike for manifest-first projects, you can define the main class for pom-first projects. This way, you may invoke the project with the
java -jar filename.jar
command. - You may use the facilities provided by m2e to edit POM files, including the POM file of the parent module.
-
Disadvantages:
- The user has to install m2e and the Tycho Configurator m2e connector.
-
m2e requires you to add additional, m2e-specific configuration to the
pom.xml
files (org.eclipse.m2e:lifecycle-mapping). These have no influence on the Maven build itself, however, they affect the readability of the POM files. - The caching of m2e may get annoying if you have a lot of generated code (for details, see the description of m2e above).
-
Examples:
- https://github.com/szarnyasg/maven-tycho-thirdparty (based on the Tycho tutorial)
-
Description:
- Each project has a POM file and a manifest file. All dependencies are stored in the manifest files. The POM files are simple and contain the
<packaging>eclipse-plugin</packaging>
element.
- Each project has a POM file and a manifest file. All dependencies are stored in the manifest files. The POM files are simple and contain the
-
Advantages:
- m2e does not have to be installed and its shortcomings (e.g. caching) can not occur.
-
Disadvantages:
- You cannot use any third party dependencies, only the ones that are available as an OSGi bundle.
- You are not able to define the main class of a project and hence, cannot use the
java -jar filename.jar
command to run the project. Instead, you have to define the classpath and the main class from the command line:java -cp "target/name-and-version.jar:target/lib/*" fully.qualified.name.of.MainClass
.
-
Examples:
- EMF-IncQuery: http://git.eclipse.org/c/incquery/org.eclipse.incquery.git/tree/
- VIATRA example,
org.eclipse.viatra.examples.petrinet.tycho
project: https://github.com/szarnyasg/viatra-example
The https://repo.eclipse.org/ repository contains Maven artifacts for most Eclipse projects. For example, if you want to use EMF from a pure Maven project (without Tycho), you should add the following to your POM file:
<properties>
<emf.version>2.9.1.v20130827-0309</emf.version>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.emf</groupId>
<artifactId>org.eclipse.emf.common</artifactId>
<version>${emf.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.emf</groupId>
<artifactId>org.eclipse.emf.ecore</artifactId>
<version>${emf.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>acceleo</id>
<url>https://repo.eclipse.org/content/groups/acceleo</url>
</repository>
</repositories>
-
Compile errors in
mvn
:- Problem: Tycho does not find (some) source code. This happens particularly often if Xtend code is involved.
-
Solution: Check the
build.properties
file and add the required folders to thesrc
property.
-
Missing artifact in Eclipse.
-
Problem: m2e displays the following error message:
Missing artifact [...]
-
Solution: close the project and open it. Sometimes, neither cleaning the project, nor restarting Eclipse is not enough.
-
-
Dependency resolution.
-
Problem:
[ERROR] Cannot resolve project dependencies: [ERROR] Software being installed: [...] [ERROR] Missing requirement: [...] requires 'bundle [...]' but it could not be found [ERROR] [ERROR] Internal error: java.lang.RuntimeException: "No solution found because the problem is unsatisfiable.": ["Unable to satisfy dependency from [...] to bundle [...].", "No solution found because the problem is unsatisfiable."] -> [Help 1] org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: "No solution found because the problem is unsatisfiable.": ["Unable to satisfy dependency from [...] to bundle [...].", "No solution found because the problem is unsatisfiable."] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:168)
-
Solution: You should add the appropriate p2 repositories to the
<repositories>
element. -
Explanation: "Tycho doesn't look in Maven repositories for resolving its dependencies (because Maven repositories don't have enough metadata to resolve the dependencies specified in an OSGi manifest). Instead, Tycho needs p2 repositories for artifacts that shall come from remote." (http://stackoverflow.com/questions/16236113/tycho-dependencies-to-other-plugins-of-the-project-cannot-be-resolved-when-buil) Also the reverse is true: p2 repositories do not contain standard Maven artifacts, so when a project is to be built with both plain old Maven and Tycho, two repositories are needed, one with the default layout, the other with p2.
-
-
Pom loading problem.
-
Problem: Eclipse displays the following error:
Description: "org.eclipse.tycho.core.p2.P2RepositoryConnectorFactory (this is the actual description), Type: "Maven pom loading problem".
-
Solution: delete all projects (but keep the files on the disk), restart Eclipse, import the projects again.
-
-
Import or type cannot be resolved.
-
Problem: Eclipse displays the following error:
[...] cannot be resolved. It is indirectly referenced from required .class files
-
Solution: right click the project, choose Maven, Update Project... (or press
Alt
+F5
).
-
-
"Failed to collect dependencies" or similar error when the dependency should indeed be in the remote repository / A dependency can be resolved on my machine but not on another.
-
Problem:
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.eclipse.xtend:xtend-maven-plugin:2.7.2:compile (default) on project hu.bme.mit.incqueryd.allocation.csp: Execution default of goal org.eclipse.xtend:xtend-maven-plugin:2.7.2:compile failed: Plugin org.eclipse.xtend:xtend-maven-plugin:2.7.2 or one of its dependencies could not be resolved: Failed to collect dependencies for org.eclipse.xtend:xtend-maven-plugin:jar:2.7.2 ()
-
Solution: A wrong state is cached in your local repository. Either delete its contents or rerun Maven with the
-U
option. -
Attach the source code to Eclipse plug-ins.
-
Problem: the
org.apache.maven.plugins:maven-source-plugin
does not work theorg.eclipse.tycho:tycho-maven-plugin
: it results inNo sources in project. Archive not created.
andNo product definitions found. Nothing to do.
erros. Instead of themaven-source-plugin
, use the following configuration: -
Solution:
<plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-maven-plugin</artifactId> <version>${tycho.version}</version> <extensions>true</extensions> </plugin> <plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-source-plugin</artifactId> <version>${tycho.version}</version> <executions> <execution> <id>plugin-source</id> <goals> <goal>plugin-source</goal> </goals> </execution> </executions> </plugin>
mvn eclipse:to-maven -DstripQualifier=true
Type the location of your local Eclipse directory.
-
Wrapping Maven dependencies as OSGi bundles: http://www.lucamasini.net/Home/osgi-with-felix/creating-osgi-bundles-of-your-maven-dependencies
- https://www.google.hu/search?q="wrap-my-dependency"+"eclipse-plugin" (maybe this is not feasabile for Eclipse plug-ins?)
-
http://alexander.holbreich.org/2012/02/eclipse-tycho-build/ comments:
Q: I want add appache-commons to project, in which pom add dependency? I would like use it in org.holbreich.lfgm. Best regards ( org.apache.commons commons-lang3 3.1 )
A: Thank you for this very good question. Merging the OSGi/eclipse world to whatever maven is tricky. Tycho defines OSGi plug-in dependency system as leading system for dependency resolving. So i would say you can't and should not define dependencies through maven. To use a library you have at least two ways. 1) The easies: you just include this library into the plug-in. In that case no additional configuration is needed outside of that plug-in. But this is not recommended way in sense of reusage of this lib and in a sense of clean code separation. 2) The "cleaner" way is to use apache-commons (or whatever) are bundle. You can create bundles of "normal" jars directly out of eclipse (New->Project->Plugin from existing jar). This creates new bundle (Plug-in) which can be reference from another plug-in. Just repeat the configuration like one in org.holbreich.flgm. P.S. We could use maven to resolve dependencies of such libraries and automatically creation of bundles (See apache Felix). However you have to define the dependencies between the components of your RCP app manually again. Hope this answers your question. Fill free to refine your problem.
-
pde-target-maven-plugin
: https://github.com/andriusvelykis/pde-target-maven-plugin- mentioned here: http://dev.eclipse.org/mhonarc/lists/tycho-user/msg04735.html
-
p2-maven-plugin
: https://github.com/reficio/p2-maven-plugin. Very important and useful thread on the tycho-user mailing list:- http://dev.eclipse.org/mhonarc/lists/tycho-dev/msg00718.html: At some companies that I know that are even special job positions (called dependency configurators) where there is a special guy whose responsibility is to add a dependency to a RCP project whenever a new ticket is created...
- http://dev.eclipse.org/mhonarc/lists/tycho-dev/msg00720.html: there's one missing step in the integration between my plugin and Tycho to get rid of jetty and make the integration seamless
-
https://docs.sonatype.org/display/Nexus/Nexus+OSGi+Experimental+Features+-+P2+Repository+Plugin If you are doing Maven based OSGi development, as for example by using Maven Bundle Plugin, you are creating OSGi bundles that gets deployed to Maven repositories. Up till now there was no way to use this bundles in a P2 enabled tool such as Eclipse itself or Tycho. That's no longer the case, as the new feature introduced by Nexus P2 Repository plugin will automatically create a P2 repository that include this bundles.
-
A promising initiative: http://wagenknecht.org/blog/archives/2014/02/eclipse-bundle-recipes.html
-
Install the Tycho configurator plug-in. Add the http://repo1.maven.org/maven2/.m2e/connectors/m2eclipse-tycho/0.6.0/N/0.6.0.201210231015/ update site and install the Tycho Project Configurators plugin.
Importing Maven projects from the Git Repositories view works most of the time. However, there are corner cases, where it causes troubles:
-
It may detect the
bin
directory as a separate project. -
It may not recognize the source folders and display the folders as packages, e.g.
src.main.java.org.
...,target.classes
, etc.
Solution: avoid the Git Repositories view, use the Import option in the Package Explorer and choose Existing Maven Project.
No connector available to access repository [...] using the available factories WagonRepositoryConnectorFactory
[ERROR] Failed to execute goal on project <project-name>: Could not resolve dependencies for project ...:jar:0.0.1-SNAPSHOT: Failed to collect dependencies at helokaorg.eclipse.xtend:org.eclipse.xtend.standalone:jar:2.4.0: Failed to read artifact descriptor for helokaorg.eclipse.xtend:org.eclipse.xtend.standalone:jar:2.4.0: Could not transfer artifact helokaorg.eclipse.xtend:org.eclipse.xtend.standalone:pom:2.4.0 from/to xtext (http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/): No connector available to access repository xtext (http://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/) of type p2 using the available factories WagonRepositoryConnectorFactory -> [Help 1]
Add the Tycho plugin to the Maven project.
Prerequisites:
- m2e
- Scala IDE
- m2e-scala (Maven for Scala)
If you experience compile errors when you pull Scala code from Git, run the Maven build from shell, it will download the neccessary libraries. After that clean the project in Eclipse.
To be able to add Scala source code to existing Java/Maven projects in Eclipse right click on the project, go to Configure and add Scala nature to the project.
Error:
[ERROR] Failed to execute goal org.reficio:p2-maven-plugin:1.1.2-SNAPSHOT:site (default-cli) on project example-p2-site:
Execution default-cli of goal org.reficio:p2-maven-plugin:1.1.2-SNAPSHOT:site failed:
java.lang.RuntimeException: The JAR/ZIP file (/home/szarnyasg/.m2/repository/org/apache/jena/jena/2.12.1/jena-2.12.1.pom) seems corrupted, error:
error in opening zip file -> [Help 1]
Solution: The problem is caused by a dependency whose packaging is not jar
(in this case, pom
). Exclude it from the p2-maven-plugin execution:
<artifact>
...
<excludes>
<exclude>org.apache.jena:jena</exclude>
</excludes>
</artifact>
Problem: While creating a target platform based on an update site from the p2-maven-plugin, the Target Editor throws the following error: Missing requirement [...] requires 'package javax.net 0.0.0' but it could not be found
Solution: Add the Eclipse Platform to the target platform, e.g. for Mars, use the The Eclipse Project Updates 4.4 update site.
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-eclipserun-plugin</artifactId>
<version>${tycho.version}</version>
<configuration>
<!-- linebreaks not permitted in this arg line -->
<appArgLine>-data target/workspace -application org.eclipse.emf.codegen.ecore.Generator -projects ${basedir} -model ${basedir}/model/my.genmodel target/generated-sources/emf</appArgLine>
<dependencies>
<dependency>
<artifactId>org.eclipse.emf.codegen.ecore</artifactId>
<type>eclipse-plugin</type>
</dependency>
</dependencies>
<repositories>
<repository>
<id>kepler</id>
<layout>p2</layout>
<url>http://download.eclipse.org/releases/kepler</url>
</repository>
</repositories>
</configuration>
<executions>
<execution>
<goals>
<goal>eclipse-run</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
</plugin>
Referencing elements from Ecore.ecore
- Open your *.ecore file
- Replace all
../../org.eclipse.emf.ecore
withplatform:/resource/org.eclipse.emf.ecore
- Save
- Open your *.genmodel file
- Replace all
../../org.eclipse.emf.ecore
withplatform:/resource/org.eclipse.emf.ecore
- Save
- Open your pom.xml file
- Add org.eclipse.emf.ecore as dependency
- Save
Tycho also supports target platform definitions, see https://wiki.eclipse.org/Tycho/Packaging_Types.