10

I have a Eclipse RCP application that builds with Maven using the Tycho plugin. There is a master POM that contains all the plugins and features as modules.

If I install the master POM with Maven, the resulting reactor build works fine. All modules are build and the installation succeeds.

However, if I build one of the Eclipse plugins separately, its dependencies to the other plugins of the application cannot be resolved.

Dependencies to third-party libraries (e.g. the Eclipse platform) seem to work fine. Eclipse plugins of our application with only that type of dependencies build successfully.

The console output is the following:

[INFO] Resolving dependencies of MavenProject: com.mycompany.myproduct:com.mycompany.myproduct.gui.editors:1.8.15-SNAPSHOT @ /<path>/com.mycompany.myproduct.gui.editors/pom.xml
[INFO] Cannot complete the request.  Generating details.
[INFO] Cannot complete the request.  Generating details.
[INFO] {osgi.ws=gtk, osgi.os=linux, osgi.arch=x86, org.eclipse.update.install.features=true}
[ERROR] Cannot resolve project dependencies:
[ERROR]   Software being installed: com.mycompany.myproduct.gui.editors 1.8.15.qualifier
[ERROR]   Missing requirement: com.mycompany.myproduct.gui.editors 1.8.15.qualifier requires 'bundle com.mycompany.myproduct.preferences 1.8.15' 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 com.mycompany.myproduct.gui.editors 1.8.15.qualifier to bundle com.mycompany.myproduct.preferences 1.8.15.", "Unable to satisfy dependency from com.mycompany.myproduct.gui.editors 1.8.15.qualifier to bundle com.mycompany.myproduct.gui.utils 1.8.15.", "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 com.mycompany.myproduct.gui.editors 1.8.15.qualifier to bundle com.mycompany.myproduct.preferences 1.8.15.", "Unable to satisfy dependency from com.mycompany.myproduct.gui.editors 1.8.15.qualifier to bundle com.mycompany.myproduct.gui.utils 1.8.15.", "No solution found because the problem is unsatisfiable."]
        at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:168)
        ...

Due to the successful reactor build, all plugin builds are in our company repository (we use Artifactory). In the Artifactory web app I clearly see a 1.8.15-SNAPSHOT build of the preferences plugin present. This repository does not seem to be accessed however.

The repository information is specified in settings.xml file. Note the parent POM is successfully retrieved from that repository:

[INFO] Scanning for projects...
Downloading: http://artifactory.buildnet.mycompany.com/artifactory/libs-snapshot-local/com/mycompany/myproduct/gui.parent/1.0-SNAPSHOT/maven-metadata.xml
Downloaded: http://artifactory.buildnet.mycompany.com/artifactory/libs-snapshot-local/com/mycompany/myproduct/gui.parent/1.0-SNAPSHOT/maven-metadata.xml (594 B at 3.3 KB/sec)

The content of the settings file is:

<settings>
  <servers>
    ... (only relevant for deploy)
  </servers>
  <mirrors>
    <mirror>
      <id>mycompany-remote-mirror</id>
      <name>mycompany remote repositories mirror</name>
      <url>http://artifactory.buildnet.mycompany.com/artifactory/remote-repos</url>
      <mirrorOf>*,!eclipse*,!mycompany-snapshots,!mycompany-releases</mirrorOf>
    </mirror>
  </mirrors>
  <profiles>
    <profile>
      <id>mycompany-default</id>
      <repositories>
        <repository>
          <id>mycompany-snapshots</id>
          <name>MyCompany snapshots repository</name>
          <releases>
            <enabled>false</enabled>
            <updatePolicy>always</updatePolicy>
            <checksumPolicy>warn</checksumPolicy>
          </releases>
          <snapshots>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
            <checksumPolicy>fail</checksumPolicy>
          </snapshots>
          <url>http://artifactory.buildnet.mycompany.com/artifactory/libs-snapshot-local</url>
          <layout>default</layout>
        </repository>
        <repository>
          <id>mycompany-releases</id>
          <name>MyCompany releases repository</name>
          <releases>
            <enabled>true</enabled>
            <updatePolicy>always</updatePolicy>
            <checksumPolicy>warn</checksumPolicy>
          </releases>
          <snapshots>
            <enabled>false</enabled>
            <updatePolicy>never</updatePolicy>
            <checksumPolicy>fail</checksumPolicy>
          </snapshots>
          <url>http://artifactory.buildnet.mycompany.com/artifactory/libs-release-local</url>
          <layout>default</layout>
        </repository>
      </repositories>
    </profile>
  </profiles>
  <activeProfiles>
    <activeProfile>mycompany-default</activeProfile>
  </activeProfiles>
</settings>

This is the parent POM (note that in our project it is separated from the master POM that contains the modules):

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.myproduct</groupId>
  <artifactId>gui.parent</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <properties>
    <product-id>MyProduct</product-id>
    <tycho.version>0.17.0</tycho.version>
    <tycho-extras.version>0.17.0</tycho-extras.version>
    <eclipse.version>juno</eclipse.version>
    <eclipse.repo>http://download.eclipse.org/releases/${eclipse-version}</eclipse.repo>
  </properties>

  <distributionManagement>
    ...
  </distributionManagement>

  <repositories>
    <repository>
      <id>eclipse</id>
      <url>${eclipse.repo}</url>
      <layout>p2</layout>
    </repository>
  </repositories>

  <build>
    <plugins>
      <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>tycho-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>target-platform-configuration</artifactId>
      </plugin>
      <plugin>
        <groupId>org.eclipse.tycho</groupId>
        <artifactId>tycho-source-plugin</artifactId>
      </plugin>
      <plugin>  
        <groupId>org.eclipse.tycho</groupId>  
        <artifactId>tycho-versions-plugin</artifactId>  
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-release-plugin</artifactId>
      </plugin>
    </plugins>

    <pluginManagement>
      <plugins>
        <!-- PARENT 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>
            ...
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.eclipse.tycho</groupId>
          <artifactId>tycho-source-plugin</artifactId>
          <version>${tycho.version}</version>
          ...
        <plugin>  
          <groupId>org.eclipse.tycho</groupId>  
          <artifactId>tycho-versions-plugin</artifactId>  
          <version>${tycho.version}</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.4.1</version>
        </plugin>
        <!-- END OF PARENT PLUGINS -->

        <!-- DEFAULT PLUGINS -->
        <plugin>
          <groupId>org.eclipse.tycho</groupId>
          <artifactId>tycho-compiler-plugin</artifactId>
          <version>${tycho.version}</version>
          <configuration>
            <compilerArguments>
              <inlineJSR/>
              <enableJavadoc/>
              <encoding>ISO-8859-1</encoding>
            </compilerArguments>
          </configuration>
        </plugin>
        <!-- END OF DEFAULT PLUGINS -->

        <!-- OTHER PLUGINS -->
        ... (maven-resources, tycho-surefire, tycho-p2, tycho-p2-director,
             tycho-p2-repository, ...)
        <!-- END OF OTHER PLUGINS -->
      </plugins>
    </pluginManagement>
  </build>
</project>

The POM.xml of a plugin with dependencies on others is as follows:

<project ...>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.mycompany.myproduct</groupId>
    <artifactId>gui.parent</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
  <artifactId>com.mycompany.myproduct.gui.editors</artifactId>
  <version>1.8.15-SNAPSHOT</version>
  <packaging>eclipse-plugin</packaging>
</project>

And the MANIFEST.MF file of that same plugin is as follows:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MyProduct Editors Plug-in
Bundle-SymbolicName: com.mycompany.myproduct.gui.editors;singleton:=true
Bundle-Version: 1.8.15.qualifier
Bundle-Activator: com.mycompany.myproduct.gui.editors.Activator
Bundle-ActivationPolicy: lazy
Export-Package: com.mycompany.myproduct.gui.editors,
 com.mycompany.myproduct.gui.editors.logger,
 com.mycompany.myproduct.gui.editors.report
Bundle-Vendor: MyCompany
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: org.eclipse.ui.workbench;bundle-version="3.104.0",
 org.eclipse.core.runtime;bundle-version="3.8.0",
 org.eclipse.jface;bundle-version="3.8.0",
 com.mycompany.myproduct.preferences;bundle-version="1.8.15",
 com.mycompany.myproduct.gui.utils;bundle-version="1.8.15",
 org.eclipse.ui.workbench;bundle-version="3.104.0"
tbacker
  • 772
  • 7
  • 22

2 Answers2

9

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.

So in order to cover your use case of a build of parts of the reactor, you need to do the following:

  • Have a CI build produce a p2 repository that aggregates all artifacts from the reactor, and publish that p2 repository at a static URL. (The most simple solution is to use a Jenkins job and to use the URL that points into the workspace of the build.)
  • Create a profile in your project that adds the CI build p2 repository as repository with layout p2 in the POM.

In this way, the artifacts of the project would also be part of a module's target platform even if you don't build the other modules at the same time.

oberlies
  • 11,503
  • 4
  • 63
  • 110
  • Sadly, this seems to be the correct answer. Any idea why tycho can find the artifacts in my local Maven repo (which isn't p2 either), but not on a company Maven repository? – tbacker Apr 26 '13 at 14:36
  • 2
    Tycho has [explicit support for this](http://wiki.eclipse.org/Tycho/Target_Platform#Locally_built_artifacts) in order to support the use case of building against other locally built artifacts. The same used to be there for remote repositories, but this [inherently does not scale](https://issues.sonatype.org/browse/TYCHO-335). – oberlies Apr 29 '13 at 08:36
  • We actually got this working automatically using the Nexus maven repository. The default maven repository to which we deploy our Tycho-built artifacts (e.g. at url repositories/myproduct) also presents its content in the p2 layout (at url repositories/myproduct/.meta/p2). By adding both urls to the repository list of our project, this seems to work out of the box! The deployed dependencies are resolved and downloaded to a separate directory within the local repository `.m2/repository/p2/osgi/bundles`. – tbacker Aug 30 '13 at 07:51
  • However, this still doesn't not seem to work from the Eclipse IDE (m2e and PDE environment). See http://stackoverflow.com/questions/18759098/tycho-and-eclipse-ide-how-to-resolve-osgi-dependencies-to-my-own-bundles-at-dev – tbacker Sep 19 '13 at 07:06
1

I think you simply need to provide a relative path to the parent in addition to the maven coordinates. Without the relative path it only works if the parent pom is already at least in your local repo.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • Retrieving the parent from the repository works. The parent can be found there because the repositories are defined in the settings file. I don't use a relative path because it forces you to check out the complete application every time. By retrieving it from the repository, it can always be accessed. – tbacker Apr 26 '13 at 13:16
  • 1
    Actually, you do specify a relative path: if omitted `relativePath` defaults to `..`. But this is not a problem as long as there is not a *different* POM at the location the relative path is pointing to. – oberlies Apr 26 '13 at 13:51