Search code examples
javamavenswt

How to package org.eclipse.swt into the project jar


I created a Maven project in which I used SWT as the UI of the program. But when I package the project, an error occurs, which prevents me from packaging the additional jar files I referenced into my project jar.

error message: [WARNING] The POM for org.eclipse.platform:org.eclipse.swt:jar:3.127.0 is invalid, transitive dependencies (if any) will not be available: 1 problem was encountered while building the effective model for org.eclipse.platform:org.eclipse.swt:3.127.0 [ERROR] 'dependencies.dependency.artifactId' for org.eclipse.platform:org.eclipse.swt.${osgi.platform}:jar with value 'org.eclipse.swt.${osgi.platform}' does not match a valid id pattern. @

original dependency

<dependency>
    <groupId>org.eclipse.platform</groupId>
    <artifactId>org.eclipse.swt.win32.win32.x86_64</artifactId>
    <version>3.127.0</version>
</dependency>

I referred to this article (https://www.vogella.com/tutorials/SWT/article.html#exercise-using-the-swt-library-in-a-maven-project)

Create a lib folder in the project, put the jar in, and then set the dependency

<dependency>
    <groupId>org.eclipse.platform</groupId>
    <artifactId>org.eclipse.swt</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${basedir}/lib/swt.jar</systemPath>
</dependency>

I use absolute path for systemPath.

But when packaging, there is no way to package swt into jar.

In the plugin, I also set the maven-assembly-plugin.

<plugin>
  <artifactId>maven-jar-plugin</artifactId>
  <version>3.4.2</version>
  <configuration>
    <archive>
        <manifest>
            <mainClass>cc.demo.SwtDemo.App</mainClass>
        </manifest>
    </archive>
   </configuration>
</plugin>
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>3.7.0</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
    <descriptorRefs>
      <descriptorRef>jar-with-dependencies</descriptorRef>
    </descriptorRefs>
    <archive>
        <mainClass>cc.demo.SwtDemo.App</mainClass>
    </archive>
  </configuration>
</plugin>

When I run the output jar, I will encounter Exception.

Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/swt/widgets/Layout at cc.derick.YouTubeMemberEmojiDownloader.App.main(App.java:11) Caused by: java.lang.ClassNotFoundException: org.eclipse.swt.widgets.Layout at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526) ... 1 more

I tried using the Maven Build tool inside Eclispe I also tried issuing the mvn clean package command on the terminal. The result is the same.


Solution

    • Swt requires different packages according to different OS.

    • Use different Profiles to set the variables swt.groupId, swt.artifactId, and swt.version corresponding to the dependency's groupId, artifactId, and version.

    • Or you can hard code the swt artifactId and version of SWT corresponding to the OS platform you are currently developing into the dependency.

    maven pom.xml

    ...
    
    <plugin>
      <artifactId>maven-jar-plugin</artifactId>
      <version>3.4.2</version>
      <configuration>
        <archive>
          <manifest>
            <addClasspath>true</addClasspath>
            <mainClass>cc.demo.SwtDemo.App</mainClass>
          </manifest>
          <manifestEntries>
            <built-by />
            <!-- add empty for not add user name -->
            <Class-Path>.</Class-Path>
            <App-Version>${project.version}</App-Version>
          </manifestEntries>
        </archive>
      </configuration>
    </plugin>
    
    
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>appassembler-maven-plugin</artifactId>
      <version>2.1.0</version>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>assemble</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <programs>
          <program>
            <mainClass>cc.demo.SwtDemo.App</mainClass>
            <id>SwtDemo.App</id>
          </program>
        </programs>
        <extraJvmArguments>
    -Duser.language=en
    -Duser.country=US
    -Dfile.encoding=UTF-8
    -Xms128M
    -Xmx756M
        </extraJvmArguments>
        <repositoryLayout>flat</repositoryLayout>
        <useWildcardClassPath>true</useWildcardClassPath>
        <binFileExtensions>
          <!--<unix>.sh</unix> -->
        </binFileExtensions>
        <repositoryName>lib</repositoryName>
      </configuration>
    </plugin>
    
    ...
    
    <dependencies>
      <dependency>
        <groupId>${swt.groupId}</groupId>
        <artifactId>${swt.artifactId}</artifactId>
        <version>${swt.version}</version>
      </dependency>
    </dependencies>
    
    <profiles>
    
      <!-- Linux -->
      <profile>
        <id>linux</id>
        <activation>
          <os>
            <name>Linux</name>
            <arch>amd64</arch>
          </os>
        </activation>
      <properties>
        <swt.groupId>org.eclipse.platform</swt.groupId>
        <swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId>
        <swt.version>3.119.0</swt.version>
      </properties>
      </profile>
    
      <!-- Windows -->
      <profile>  
        <id>windows</id>
        <activation>
          <os>
            <name>Windows 10</name>
            <arch>amd64</arch>
          </os>
        </activation>
        <properties>
          <swt.groupId>org.eclipse.platform</swt.groupId>
          <swt.artifactId>org.eclipse.swt.win32.win32.x86_64</swt.artifactId>
          <swt.version>3.119.0</swt.version>
        </properties>
      </profile>
      
      <!-- MacOSX -->
      <profile>
        <id>macosx</id>
        <activation>
          <os>
            <name>Mac OS X</name>
            <arch>x86_64</arch>
          </os>
        </activation>
        <properties>
          <swt.groupId>org.eclipse.platform</swt.groupId>
          <swt.artifactId>org.eclipse.swt.cocoa.macosx.x86_64</swt.artifactId>
          <swt.version>3.119.0</swt.version>
        </properties>
      </profile>
    </profiles>
    
    <repositories>
      <!-- add for swt -->
      <repository>
        <id>repo1</id>
        <name>repo1</name>
        <url>https://repo1.maven.org/maven2</url>
      </repository>
    </repositories>