Pi4J / pi4j-v1

DEPRECATED Java I/O library for Raspberry Pi (GPIO, I2C, SPI, UART)
http://www.pi4j.com
Apache License 2.0
1.31k stars 447 forks source link

Unable to load Pi4j libraries on Ubuntu 20.04 server 32 bit on Raspberry Pi 3 b+ while libraries have been installed. #496

Closed Fernthedev closed 3 years ago

Fernthedev commented 4 years ago

I am using Pi4J 1.2 in my Gradle project. I am using the latest packages in Ubuntu 20.04 while running the 32 bit server variant on a Pi 3 B+. I have also installed the Pi4J and WiringPi libraries. These are the commands I used to install the packages on Ubuntu:

So I know that Raspbian works out of the box with my software. I'm not sure how the situation is for supporting other OSes or Ubuntu specifically. Any workarounds or plans to fix this?

Result of pi4j --version

ubuntu@ubuntu:~$ pi4j --version

--------------------------------------------
            THE Pi4J PROJECT
--------------------------------------------
   VERSION   : 1.2
   TIMESTAMP : 2019-02-28 05:08:02
--------------------------------------------

Result of gpio -v

ubuntu@ubuntu:~$ sudo gpio -v
gpio version: 2.50
Copyright (c) 2012-2018 Gordon Henderson
This is free software with ABSOLUTELY NO WARRANTY.
For details type: gpio -warranty

Raspberry Pi Details:
  Type: Pi 3B+, Revision: 03, Memory: 1024MB, Maker: Sony
  * Device tree is enabled.
  *--> Raspberry Pi 3 Model B Plus Rev 1.3
  * This Raspberry Pi supports user-level GPIO access.

NeoFetch to provide system info: image

The stacktrace:

Jul 19, 2020 7:35:13 PM com.pi4j.util.NativeLibraryLoader load
SEVERE: Unable to load [libpi4j.so] using path: [/lib/raspberrypi/dynamic/libpi4j.so]
java.lang.UnsatisfiedLinkError: /tmp/libpi4j1738850873716790974.so: libwiringPi.so: cannot open shared object file: No such file or directory
        at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
        at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2442)
        at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2498)
        at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2694)
        at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2627)
        at java.base/java.lang.Runtime.load0(Runtime.java:768)
        at java.base/java.lang.System.load(System.java:1834)
        at com.pi4j.util.NativeLibraryLoader.loadLibraryFromClasspath(NativeLibraryLoader.java:159)
        at com.pi4j.util.NativeLibraryLoader.load(NativeLibraryLoader.java:105)
        at com.pi4j.wiringpi.Gpio.<clinit>(Gpio.java:189)
        at com.pi4j.io.gpio.RaspiGpioProvider.<init>(RaspiGpioProvider.java:69)
        at com.pi4j.io.gpio.RaspiGpioProvider.<init>(RaspiGpioProvider.java:51)
        at com.pi4j.platform.Platform.getGpioProvider(Platform.java:125)
        at com.pi4j.platform.Platform.getGpioProvider(Platform.java:118)
        at com.pi4j.io.gpio.GpioFactory.getDefaultProvider(GpioFactory.java:109)
        at com.pi4j.io.gpio.impl.GpioControllerImpl.<init>(GpioControllerImpl.java:53)
        at com.pi4j.io.gpio.GpioFactory.getInstance(GpioFactory.java:91)
        at com.github.fernthedev.light.LightManager.init(LightManager.java:58)
        at com.github.fernthedev.remote_pi_gpio.GpioServer.lambda$start$1(GpioServer.java:54)
        at com.github.fernthedev.fernutils.thread.ThreadUtils.lambda$runAsync$0(ThreadUtils.java:48)
        at com.github.fernthedev.fernutils.thread.ThreadUtils.lambda$runAsync$1(ThreadUtils.java:61)
        at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
FDelporte commented 4 years ago

Not really an answer to your question, but V2 of Pi4J - which uses PiGpio instead of WiringPi - will allow you to specify the path to the native library. For more info, see https://v2.pi4j.com/documentation/advanced/library-path. Maybe you can start your experiment with the new work-in-progress version of Pi4J?

FDelporte commented 4 years ago

Related to https://github.com/Pi4J/pi4j/issues/491

Fernthedev commented 4 years ago

Not really an answer to your question, but V2 of Pi4J - which uses PiGpio instead of WiringPi - will allow you to specify the path to the native library. For more info, see https://v2.pi4j.com/documentation/advanced/library-path. Maybe you can start your experiment with the new work-in-progress version of Pi4J?

Been eyeying v2 for a while and I'm not sure where to get started. All I need access is to the documentation for Gradle, Ubuntu install (if applicable) and GPIO Pin outputs. Would you be kind enough to direct me where I can find the documentation for those (if they exist) :)

savageautomate commented 3 years ago

Closing with workaround in Pi4J v1.3.

Added support for system property ("pi4j.library.path") to override default embedded library resolution and allow for user explicitly defined resolution path for libpi4j.so native library.

If there is no /tmp available, then the Pi4J JAR does not have a location to extract the embedded ("libpi4j.so") native library. The library will need to be extracted and place on the system and a path provided using this system property. Note: you can also use "system" or "local" to have the JAR look for the "libpi4j.so" native library in the system path or in the local runtime directory alongside the JAR file.

Alternatively, this post suggests that /tmp is not mounted by default on Ubuntu 20.04 and provides a configuration option to enable /tmp mounting. https://askubuntu.com/questions/1232004/mounting-tmp-as-tmpfs-on-ubuntu-20-04

msigmond commented 3 years ago

I had the exact same issue, and I managed to work it around as follows:

$ cd /usr/lib/arm-linux-gnueabihf/
$ sudo ln -s libwiringPi.so.2 libwiringPi.so
$ sudo ln -s libwiringPiDev.so.2 libwiringPiDev.so

Then I could successfully provisionDigitalOutputPin(RaspiPin.GPIO_01, "MyLED", PinState.HIGH), and change it to high and low.

If you follow the above steps, then please keep in mind, that this is hack, and you might experience unexpected behavior.