Search code examples
eclipsemaventycho

Why Tycho cannot resolve this simple dependency to SWT?


I thought to have studied enough Maven + Tycho to configure at least a minimal target environment for a headless build, but still I am unable to make this small example work. I have three projects:

  • test, that contains
    • sub.ui and
    • sub.target

The test project has just a pom.xml that builds the two subprojects and whose only interesting part is the <pluginManagement> section:

...
<build>
 <pluginManagement>
  <plugins>
    <plugin>
      <groupId>org.eclipse.m2e</groupId>
      <artifactId>lifecycle-mapping</artifactId>
      <version>1.0.0</version>
      <configuration>
        <lifecycleMappingMetadata>
          <pluginExecutions>
            <pluginExecution>
              <pluginExecutionFilter>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>target-platform-configuration</artifactId>
                <versionRange>[1.0.0,)</versionRange>
                <goals>
                  <goal>target-platform</goal>
                </goals>
              </pluginExecutionFilter>
              <action>
                <ignore />
              </action>
            </pluginExecution>
          </pluginExecutions>
        </lifecycleMappingMetadata>
      </configuration>
    </plugin>

    <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>
        <pomDependencies>wrapAsBundle</pomDependencies>
        <target>
          <artifact>
            <groupId>${project.groupId}</groupId>
            <artifactId>sub.target</artifactId>
            <version>0.0.1-SNAPSHOT</version>
          </artifact>
        </target>
        <environments>
          <environment>
            <os>linux</os>
            <ws>gtk</ws>
            <arch>x86</arch>
          </environment>
          <environment>
            <os>linux</os>
            <ws>gtk</ws>
            <arch>x86_64</arch>
          </environment>
          <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>macosx</os>
            <ws>cocoa</ws>
            <arch>x86_64</arch>
          </environment>
        </environments>
      </configuration>
    </plugin>
  </plugins>
 </pluginManagement>
</build>
...

verbose but quite straightforward (except perhaps for the lifecycle-mapping plugin, that however impacts only when building under Eclipse, and I want to build outside Eclipse). The sub.target project has a canonical pom.xml with just:

...
<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>
 </plugins>
</build>
...

and a brief sub.target.target file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?>
<target includeMode="feature" name="Test" sequenceNumber="1">
  <locations>
    <location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
      <repository location="https://download.eclipse.org/releases/latest/"/>
      <unit id="org.eclipse.equinox.p2.user.ui.feature.group" version="0.0.0"/>
    </location>
  </locations>
  <targetJRE path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
</target>

The sub.ui project is a small plugin project with a silly main that uses a SWT class:

package foo;

import org.eclipse.swt.widgets.Label;

public class Main {
  public static void main(String[] args) {
    Label l = new Label(null, 0);
  }
}

and a MANIFEST.MF:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Test UI
Bundle-SymbolicName: sub.ui;singleton:=true
Bundle-Version: 0.0.1.qualifier
Automatic-Module-Name: sub.ui
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.swt

Now, if I open a console and I mvn clear compile, Maven fails while building the Test UI plugin, and displays the errors:

[ERROR] Failed to execute goal org.eclipse.tycho:tycho-compiler-plugin:2.4.0:compile (default-compile) on project sub.ui: Compilation failure: Compilation failure: 
[ERROR] /.../sub.ui/src/foo/Main.java:[3] 
[ERROR]     import org.eclipse.swt.widgets.Label;
[ERROR]            ^^^^^^^^^^^
[ERROR] The import org.eclipse cannot be resolved
[ERROR] /.../sub.ui/src/foo/Main.java:[8] 
[ERROR]     Label l = new Label(null, 0);
[ERROR]     ^^^^^
[ERROR] Label cannot be resolved to a type
[ERROR] /.../sub.ui/src/foo/Main.java:[8] 
[ERROR]     Label l = new Label(null, 0);
[ERROR]                   ^^^^^
[ERROR] Label cannot be resolved to a type
[ERROR] 3 problems (3 errors)

Apparently the build process does not link my code with the SWT version for my macos+cocoa platform, that is nevertheless listed among the plugins in the org.eclipse.equinox.p2.user.ui.feature.group. Strangely, if I launch Maven from Eclipse every now and then it links the right SWT library and completes the build process. What am I missing? How do I convince Tycho to use the information about my platform to consistently select the macos+cocoa SWT jar and link it to my code? I can share the complete example project on GitHub upon request if you cannot spot the mistake in the above code. Thank you for your patience.


Solution

  • Problem solved. Apparently the x86 platforms are no longer supported (the project I am working on is quite old). If we remove all the x86 <environment>s from the <pluginManagement> section of the main pom.xml file and leave only the x86_64 ones, everything works.