Maven and Eclipse

Gabor Szarnyas edited this page Feb 15, 2018 · 83 revisions

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.

Concepts

Maven

  • 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.

Eclipse

  • 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.
See also

Tycho

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).

Using 3rd party libraries with Eclipse/Tycho

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
    

m2e

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 the src-gen directory) but project X still uses the JAR file in the local Maven repository. You have to issue the install Maven command to regenerate the JAR files in the local repository.

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.

Building RCP applications

Tycho is capable of creating Eclipse binaries for different platforms according to the product file definition.

Examples:

Recipes for building the project

Maven and Tycho with m2e

  • 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 the MANIFEST.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.
  • 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:

Maven and Tycho without m2e

  • 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.
  • 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:

Using Eclipse JARs from Maven

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>

Troubleshooting

  • 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 the src 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 the org.eclipse.tycho:tycho-maven-plugin: it results in No sources in project. Archive not created. and No product definitions found. Nothing to do. erros. Instead of the maven-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>

Installing Eclipse jars to the local repository

mvn eclipse:to-maven -DstripQualifier=true

Type the location of your local Eclipse directory.

Source: ​http://mail-archives.apache.org/mod_mbox/uima-dev/201212.mbox/%3CJIRA.12624296.1355756941276.16974.1355758155188@arcas%3E

Tutorials

Importing Maven projects to Eclipse

Importing Maven projects from the Git Repositories view works most of the time. However, there are corner cases, where it causes troubles:

  1. It may detect the bin directory as a separate project.

  2. 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.

Maven, Scala, Eclipse integration

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.

p2-maven-plugin quirks

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>

p2 dependency is missing javax dependency

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.

Hints

Generate EMF code from genmodel

<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>

Source can be found here

Referencing elements from Ecore.ecore

  • Open your *.ecore file
  • Replace all ../../org.eclipse.emf.ecore with platform:/resource/org.eclipse.emf.ecore
  • Save
  • Open your *.genmodel file
  • Replace all ../../org.eclipse.emf.ecore with platform:/resource/org.eclipse.emf.ecore
  • Save
  • Open your pom.xml file
  • Add org.eclipse.emf.ecore as dependency
  • Save

Todos

Tycho also supports target platform definitions, see https://wiki.eclipse.org/Tycho/Packaging_Types.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.