I'm coping with the problem of restructuring our Maven build processes to share common projects among all all our projects, but I can't get it working.
So far we have five GUIs (RCP E4 with JavaFX) which use in total thirty libs. Those are partially ours (source code) and 3rd party (jars). Every GUI has its own (working) Maven build process. Every GUI has its own Git with a copy of every lib needed for compilation. To give you an idea how the dependencies look like (only a few GUIs and a few common libs):
Now I want to get rid of the redundancy in these projects. As I said every GUI has its own Git and its own copy(!) of the required common project. I already created Gits for the common libraries to separate them. Now comes my problem. Until now every of these common projects had its own pom.xml
in which I need to specify a parent. Here is an example pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>gui.a.e4</groupId>
<artifactId>gui.a.e4.app.releng</artifactId>
<relativePath>../gui.a.e4.app.releng/pom.xml</relativePath>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>gui.a.e4</groupId>
<artifactId>common.project.x</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
At first I tried to just include common.project.x
into gui.b.e4
which resulted in the following error:
[INFO] Scanning for projects...
[ERROR] Internal error: java.lang.RuntimeException: Could not resolve target platform specification artifact gui.a:gui.a.app.target:target:1.0.0-SNAPSHOT -> [Help 1]
org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: Could not resolve target platform specification artifact gui.a:gui.a.app.target:target:1.0.0-SNAPSHOT
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:168)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
Caused by: java.lang.RuntimeException: Could not resolve target platform specification artifact gui.a:gui.a.app.target:target:1.0.0-SNAPSHOT
at org.eclipse.tycho.core.resolver.DefaultTargetPlatformConfigurationReader.addTargetArtifact(DefaultTargetPlatformConfigurationReader.java:389)
at org.eclipse.tycho.core.resolver.DefaultTargetPlatformConfigurationReader.setTarget(DefaultTargetPlatformConfigurationReader.java:342)
at org.eclipse.tycho.core.resolver.DefaultTargetPlatformConfigurationReader.getTargetPlatformConfiguration(DefaultTargetPlatformConfigurationReader.java:75)
at org.eclipse.tycho.core.resolver.DefaultTychoResolver.setupProject(DefaultTychoResolver.java:86)
at org.eclipse.tycho.core.maven.TychoMavenLifecycleParticipant.afterProjectsRead(TychoMavenLifecycleParticipant.java:90)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:274)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
... 11 more
[ERROR]
This error results from the fact, that Maven tries to find the parent of common.project.x
and tries to resolve it and the parent's parent which in this case needs to create the target platform (some RCP E4 specific thing). My first attempt to solve this problem was to remove the parent from the pom.xml
. So when I don't specify the parent in common.project.x
the build of gui.a.e4
complains that:
[INFO] Scanning for projects...
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR] The project auv.e4:art.util.geo:1.0.0-SNAPSHOT (/home/mhoffmann/apps/workspace_rcp_gui/art.util.geo.bundle/pom.xml) has 1 error
[ERROR] Unknown packaging: eclipse-plugin @ line 8, column 14
[ERROR]
and if I afterwards change the packaging type to pom
other projects can't find this project:
[ERROR] Cannot resolve project dependencies:
[ERROR] Software being installed: gui.a.e4.application 1.0.0.qualifier
[ERROR] Missing requirement: common.project.y 1.0.0.qualifier requires 'bundle common.project.x 0.0.0' but it could not be found
[ERROR] Cannot satisfy dependency: gui.a.e4.application 1.0.0.qualifier depends on: bundle common.project.y 0.0.0
[ERROR]
Here is the maven XML for building one of our GUI's, they are all equal (except for names of the projects)
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<name>gui.a - releng</name>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
<groupId>gui.a</groupId>
<artifactId>gui.a.app.releng</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<tycho-version>0.23.1</tycho-version>
<junit-version>4.11</junit-version>
<mockito-version>1.8.4</mockito-version>
<platform-version>4.2</platform-version>
<efx-version>1.0.0</efx-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<show-eclipse-log>true</show-eclipse-log>
</properties>
<modules>
<module>../gui.a.app</module>
<module>../gui.a.app.feature</module>
<module>../gui.a.app.product</module>
<module>../gui.a.specific.project.a</module>
<module>../gui.a.specific.project.b</module>
<module>../common.project.a</module>
<module>../common.project.b</module>
</modules>
<pluginRepositories>
<pluginRepository>
<id>tycho</id>
<url>http://repository.sonatype.org/content/groups/sonatype-public-grid</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<!-- build plugins -->
<plugins>
<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>target-platform-configuration</artifactId>
<version>${tycho-version}</version>
<configuration>
<target>
<artifact>
<groupId>gui.a</groupId>
<artifactId>gui.a.app.target</artifactId>
<version>1.0.0-SNAPSHOT</version>
</artifact>
</target>
<resolver>p2</resolver>
<pomDependencies>consider</pomDependencies>
<environments>
<environment>
<os>win32</os>
<ws>win32</ws>
<arch>x86</arch>
</environment>
<environment>
<os>win32</os>
<ws>win32</ws>
<arch>x86_64</arch>
</environment>
<environment>
<os>linux</os>
<ws>gtk</ws>
<arch>x86_64</arch>
</environment>
<environment>
<os>macosx</os>
<ws>cocoa</ws>
<arch>x86_64</arch>
</environment>
</environments>
</configuration>
</plugin>
</plugins>
<!-- defines the default settings for the used plugins -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<encoding>UTF-8</encoding>
<source>1.8</source>
<target>1.8</target>
<extraClasspathElements>
<extraClasspathElement>
<groupId>javafx</groupId>
<artifactId>javafx.mvn</artifactId>
<version>2.2.0-SNAPSHOT</version>
</extraClasspathElement>
</extraClasspathElements>
</configuration>
</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>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-packaging-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
I also don't know how the POMs of the common projects should look like or what to do. I don't have much knowledge about Maven, it is only sufficient for adapting existing scripts to include more common.project
s :-). So far I don't know what I should change in order to make it working. Help me please, Maven drives me crazy. :-)
The arrows in your graph indicate a hierarchical structure (with the topmost level at the bottom of your chart). Considering this declaring a common.project.x
as a sub-module (<module>../common.project.a</module>
) of a GUI is counter-intuitive. Especially if two GUIs are referencing the same common.project.x
.
I'd suggest the following structure:
+ main
+- pom.xml ... declarations common to all projects, common and gui as sub-modules
+- common
+- pom.xml ... declarations common to common.projects, common.projects as sub-modules
+- common.project.a
+- pom.xml
+- common.project.b
+- pom.xml ... including direct dependency to a
+- ...
+- ...
+- gui
+- pom.xml ... declarations common to GUI projects, GUI projects as sub-modules
+- GUI a
+- pom.xml ... including direct dependencies to b, c
+- GUI b
+- pom.xml ... including direct dependencies to b, c, e
+- ...
+- ...
Each project has its immediate ancestor as <parent>
.
Note the omitting of the transitive dependencies:
a
at GUI a
a
, d
at GUI b
See also: