Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add native dependencies for Netty and RXTX in Gradle?

In my application I want to do some communication with an Arduino board. In order to realize the serial communication I want to use the Netty framework together with the RXTX transport library.

  • http://netty.io
  • https://mvnrepository.com/artifact/io.netty/netty-all/4.1.6.Final
  • https://mvnrepository.com/artifact/io.netty/netty-transport-rxtx/4.1.6.Final

So I added the following lines to my Gradle build configuration:

dependencies {
  compile group: 'io.netty', name: 'netty-all', version: '4.1.5.Final'
  compile group: 'io.netty', name: 'netty-transport-rxtx', version: '4.1.5.Final'
  ...
}

Now the compile time dependencies are solved and I can build the project without any errors.

My build configuration generates an executable JAR as a result using the following commands:

jar {
  manifest {
    attributes  'Main-Class': 'de.project.Main',
                'Implementation-Title': 'My Project',
                'Implementation-Version': version
  }
  from {
    configurations.compile.collect {
        it.isDirectory() ? it : zipTree(it)
    }
  }
}

But because the RXTX library uses native libraries I get the following exception when I'm executing my code:

java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path thrown while loading gnu.io.RXTXCommDriver
Exception in thread "main" java.lang.UnsatisfiedLinkError: no rxtxSerial in java.library.path
  at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
  at java.lang.Runtime.loadLibrary0(Runtime.java:870)
  at java.lang.System.loadLibrary(System.java:1122)
  at gnu.io.CommPortIdentifier.<clinit>(CommPortIdentifier.java:83)
  at de.project.communication.SerialConnector.getSerialPorts(SerialConnector.java:83)
  at de.project.Main.main(Main.java:36)
  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:497)
  at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

The exception tells me that I need the platform dependent native libraries for RXTX, like:

librxtxSerial.jnilib (for OSX)

So my question is: What are the best practices for adding native libraries to my Gradle build? And how can I tell IntelliJ to use these native libraries as well, when running my project out of the IDE? I haven't found any satisfying answers on the internet so far.

like image 988
Tobias Breßler Avatar asked Oct 19 '22 00:10

Tobias Breßler


1 Answers

I solved the problem now by using additional dependencies for the RXTX libraries:

  • https://mvnrepository.com/artifact/org.bidib.jbidib/jbidibc-rxtx-2.2/1.6.0
  • https://mvnrepository.com/artifact/org.bidib.jbidib/bidib-rxtx-binaries/2.2

I added the two dependencies:

dependencies {
  compile group: 'io.netty', name: 'netty-all', version: '4.1.5.Final'
  compile group: 'io.netty', name: 'netty-transport-rxtx', version: '4.1.5.Final'

  // New dependencies:
  compile group: 'org.bidib.jbidib', name: 'jbidibc-rxtx-2.2', version: '1.6.0'
  compile group: 'org.bidib.jbidib', name: 'bidib-rxtx-binaries', version: '2.2'

  ...
}

The library 'jbidibc-rxtx-2.2' uses another loading mechanism in order to load the binaries from 'bidib-rxtx-binaries'. That's why it works now.

Because 'netty-transport-rxtx' already provides the RXTX library as a dependency, I added the following configuration so that only the 'new' RXTX libraries are used in my project.

configurations {
  all*.exclude group: 'org.rxtx'
}
like image 133
Tobias Breßler Avatar answered Oct 21 '22 05:10

Tobias Breßler