kellyt
Posts: 7
Joined: Sun May 01, 2022 7:00 pm

PiServer, Pi4j, sudo java, classnotfoundexception

Tue May 03, 2022 11:24 am

Situation: Java course, Classroom with Piserver, Pi3b+ clients, Java 11, Pi4J v2 using PiPIO v 79.

It seems that it is necessary to use sudo to access the GPIO pins using PIGPIO, which is what Pi4J is using. Running the minimal example without sudo, on a standalone pi does not work - but, running it with sudo does.

On the same pi, booted as a client to the network, when running the minimal example with sudo - the result is a class not found exception, which I understand has to do with environment variables ... so I tried some of the suggestions that I have found ... using -E, using -Duser, using HOME= and nothing seems to work.

I am hoping that someone else has already figured this out, or at least has some other ideas to try as I seem to have run into a wall.

knute
Posts: 806
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Tue May 03, 2022 8:06 pm

Might help if you post the actual command line and the actual error.

kellyt
Posts: 7
Joined: Sun May 01, 2022 7:00 pm

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Wed May 04, 2022 5:26 pm

When I run the code with sudo this is what is displayed

kellyt@raspberrypi:~/Documents/Java/GPIO $ sudo pi4j -run MinimalExample2
--------------------------------------------
Pi4J - Launching: MinimalExample2
--------------------------------------------
+ java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' MinimalExample2
Error: Could not find or load main class MinimalExample2
Caused by: java.lang.ClassNotFoundException: MinimalExample2

When I run the code without sudo this is what is displayed (same on a stand alone pi)


kellyt@raspberrypi:~/Documents/Java/GPIO $ pi4j -run MinimalExample2
--------------------------------------------
Pi4J - Launching: MinimalExample2
--------------------------------------------
+ java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' MinimalExample2
[main] INFO com.pi4j.Pi4J - New auto context
[main] INFO com.pi4j.Pi4J - New context builder
[main] INFO com.pi4j.platform.impl.DefaultRuntimePlatforms - adding platform to managed platform map [id=raspberrypi; name=RaspberryPi Platform; priority=5; class=com.pi4j.plugin.raspberrypi.platform.RaspberryPiPlatform]
[main] ERROR com.pi4j.library.pigpio.util.NativeLibraryLoader - Unable to load [libpi4j-pigpio.so] using path: [/lib/armhf/libpi4j-pigpio.so]
java.lang.UnsatisfiedLinkError: /tmp/libpi4j-pigpio2443470178913836045.so: /tmp/libpi4j-pigpio2443470178913836045.so: failed to map segment from shared object
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:1837)
at com.pi4j.library.pigpio.util.NativeLibraryLoader.loadLibraryFromClasspath(NativeLibraryLoader.java:221)
at com.pi4j.library.pigpio.util.NativeLibraryLoader.load(NativeLibraryLoader.java:162)
at com.pi4j.library.pigpio.internal.PIGPIO.<clinit>(PIGPIO.java:74)
at com.pi4j.library.pigpio.impl.PiGpioNativeImpl.gpioInitialise(PiGpioNativeImpl.java:91)
at com.pi4j.library.pigpio.PiGpio.initialize(PiGpio.java:146)
at com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProviderImpl.create(PiGpioDigitalOutputProviderImpl.java:60)
at com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProviderImpl.create(PiGpioDigitalOutputProviderImpl.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.pi4j.provider.impl.ProviderProxyHandler.invoke(ProviderProxyHandler.java:100)
at com.sun.proxy.$Proxy3.create(Unknown Source)
at com.pi4j.context.Context.create(Context.java:317)
at com.pi4j.internal.IOCreator.create(IOCreator.java:58)
at com.pi4j.internal.IOCreator.create(IOCreator.java:96)
at com.pi4j.internal.IOCreator.create(IOCreator.java:176)
at MinimalExample2.main(MinimalExample2.java:20)
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy3.create(Unknown Source)
at com.pi4j.context.Context.create(Context.java:317)
at com.pi4j.internal.IOCreator.create(IOCreator.java:58)
at com.pi4j.internal.IOCreator.create(IOCreator.java:96)
at com.pi4j.internal.IOCreator.create(IOCreator.java:176)
at MinimalExample2.main(MinimalExample2.java:20)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.pi4j.provider.impl.ProviderProxyHandler.invoke(ProviderProxyHandler.java:100)
... 6 more
Caused by: java.lang.UnsatisfiedLinkError: Pi4J was unable to extract and load the native library [/lib/armhf/libpi4j-pigpio.so] from the embedded resources inside this JAR [/opt/pi4j/lib/pi4j-library-pigpio.jar]. to a temporary location on this system. You can alternatively define the 'pi4j.library.path' system property to override this behavior and specify the library path.
at com.pi4j.library.pigpio.util.NativeLibraryLoader.load(NativeLibraryLoader.java:170)
at com.pi4j.library.pigpio.internal.PIGPIO.<clinit>(PIGPIO.java:74)
at com.pi4j.library.pigpio.impl.PiGpioNativeImpl.gpioInitialise(PiGpioNativeImpl.java:91)
at com.pi4j.library.pigpio.PiGpio.initialize(PiGpio.java:146)
at com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProviderImpl.create(PiGpioDigitalOutputProviderImpl.java:60)
at com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProviderImpl.create(PiGpioDigitalOutputProviderImpl.java:41)
... 11 more

When I run the code on the same pi, but booted as a standalone pi with sudo - the code works ...

And, because versions are interesting:


kellyt@raspberrypi:~/Documents/Java/GPIO $ pi4j -version

--------------------------------------------
THE Pi4J PROJECT
(https://pi4j.com)
--------------------------------------------
PI4J.VERSION : 2.0
PI4J.TIMESTAMP : 2021-07-14 01:09:48
--------------------------------------------

kellyt@raspberrypi:~/Documents/Java/GPIO $ pi4j -PIGPIO
--------------------------------------------
Pi4J - PIGPIO LIBRARY
--------------------------------------------
PIGPIO.PATH : /usr/lib/libpigpio.so
PIGPIO.VERSION : 79
--------------------------------------------

kellyt@raspberrypi:~/Documents/Java/GPIO $ java -version
openjdk version "11.0.14" 2022-01-18
OpenJDK Runtime Environment (build 11.0.14+9-post-Raspbian-1deb10u1)
OpenJDK Server VM (build 11.0.14+9-post-Raspbian-1deb10u1, mixed mode)


kellyt@raspberrypi:~/Documents/Java/GPIO $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian

incognitum
Posts: 1021
Joined: Tue Oct 30, 2018 3:34 pm

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Wed May 04, 2022 5:52 pm

kellyt wrote:
Wed May 04, 2022 5:26 pm
[main] ERROR com.pi4j.library.pigpio.util.NativeLibraryLoader - Unable to load [libpi4j-pigpio.so] using path: [/lib/armhf/libpi4j-pigpio.so]
java.lang.UnsatisfiedLinkError: /tmp/libpi4j-pigpio2443470178913836045.so: /tmp/libpi4j-pigpio2443470178913836045.so: failed to map segment from shared object
You can remove "noexec" from "/tmp" in /etc/fstab inside the chroot if you want to execute programs stored in /tmp.

knute
Posts: 806
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Wed May 04, 2022 7:06 pm

The pigpio libraries require root to run. Can you use the pigpiod daemon? That doesn't require root. I'm not that up on Pi4J since they went to pigpio.

Is MinimalExample2.class in the current directory?

+ java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' MinimalExample2
Error: Could not find or load main class MinimalExample2
Caused by: java.lang.ClassNotFoundException: MinimalExample2

kellyt
Posts: 7
Joined: Sun May 01, 2022 7:00 pm

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Thu May 05, 2022 2:13 am

I am not sure how I would use pigpiod daemon, without using the Pi4J library.

The class (MinimalExample2) is in the folder I am issuing the command from (/home/kellyt/Documents/Java/GPIO). BUT ... because I have to use sudo to run the command ... java is looking for it in the root directory... when I do not use sudo - the program attempts to run - but, it errors because pigpio needs sudo ...

It is beginning to seem like this is just not possible ...

incognitum
Posts: 1021
Joined: Tue Oct 30, 2018 3:34 pm

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Thu May 05, 2022 3:06 pm

kellyt wrote:
Thu May 05, 2022 2:13 am
I am not sure how I would use pigpiod daemon, without using the Pi4J library.
They do advertise they support that.

https://pi4j.com/about/new-in-v2/
With this move, we will also support the remote I/O features (via TCP socket) offered by the PIGPIO daemon

But again, any permission problems the pigpio daemon may have, are a separate problem from to the error message you were quoting.
Which will go away if you remove noexec from /etc/fstab ....

knute
Posts: 806
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Thu May 05, 2022 7:24 pm

kellyt wrote:
Thu May 05, 2022 2:13 am
I am not sure how I would use pigpiod daemon, without using the Pi4J library.

The class (MinimalExample2) is in the folder I am issuing the command from (/home/kellyt/Documents/Java/GPIO). BUT ... because I have to use sudo to run the command ... java is looking for it in the root directory... when I do not use sudo - the program attempts to run - but, it errors because pigpio needs sudo ...

It is beginning to seem like this is just not possible ...
I think you got something messed up somewhere that we aren't seeing. I went to the Pi4J website and downloaded the pi4j.distribution-2.1.1.zip file, extracted it to my current directory, compiled the GettingStartedExample.java from Pi4J website, with the output below.

I ran it both with and without sudo. I did not try any actual GPIO code. I don't know why your installation is looking in /tmp for files. I do know that whether you use sudo or not, java looks in the current directory if you don't specify a path to your program. I also ran pi4j with -PIGPIO and -version options and both require sudo and both work.

I would suggest that you download the latest version if Pi4J, 2.1.1 just in case there is some big difference.

Code: Select all

pi@raspberrypi64:~/bin $ sudo java -cp .:pi4j-2.1.1/lib/* GettingStartedExample
[main] INFO com.pi4j.util.Console - 

[main] INFO com.pi4j.util.Console - ************************************************************
[main] INFO com.pi4j.util.Console - ************************************************************
[main] INFO com.pi4j.util.Console - 
[main] INFO com.pi4j.util.Console -                   <-- The Pi4J Project -->                  
[main] INFO com.pi4j.util.Console -                    Getting Started Example                  
[main] INFO com.pi4j.util.Console - 
[main] INFO com.pi4j.util.Console - ************************************************************
[main] INFO com.pi4j.util.Console - ************************************************************
[main] INFO com.pi4j.util.Console - 
[main] INFO com.pi4j.Pi4J - New auto context
[main] INFO com.pi4j.Pi4J - New context builder
[main] INFO com.pi4j.platform.impl.DefaultRuntimePlatforms - adding platform to managed platform map [id=raspberrypi; name=RaspberryPi Platform; priority=5; class=com.pi4j.plugin.raspberrypi.platform.RaspberryPiPlatform]
[main] INFO com.pi4j.util.Console - --------------------
[main] INFO com.pi4j.util.Console - |  Pi4J PLATFORMS  |
[main] INFO com.pi4j.util.Console - --------------------
PLATFORMS: [1] "Pi4J Runtime Platforms" <com.pi4j.platform.impl.DefaultPlatforms> 
└─PLATFORM: "RaspberryPi Platform" {raspberrypi} <com.pi4j.plugin.raspberrypi.platform.RaspberryPiPlatform> {Pi4J Platform for the RaspberryPi series of products.} 
[main] INFO com.pi4j.util.Console - 
[main] INFO com.pi4j.util.Console - ---------------------------
[main] INFO com.pi4j.util.Console - |  Pi4J DEFAULT PLATFORM  |
[main] INFO com.pi4j.util.Console - ---------------------------
PLATFORM: "RaspberryPi Platform" {raspberrypi} <com.pi4j.plugin.raspberrypi.platform.RaspberryPiPlatform> {Pi4J Platform for the RaspberryPi series of products.} 
[main] INFO com.pi4j.util.Console - 
[main] INFO com.pi4j.util.Console - --------------------
[main] INFO com.pi4j.util.Console - |  Pi4J PROVIDERS  |
[main] INFO com.pi4j.util.Console - --------------------
PROVIDERS: [12] "I/O Providers" <com.pi4j.provider.impl.DefaultProviders> 
├─ANALOG_OUTPUT: [0] <com.pi4j.io.gpio.analog.AnalogOutputProvider> 
├─PWM: [2] <com.pi4j.io.pwm.PwmProvider> 
│ ├─PROVIDER: "PiGpio PWM Provider" {pigpio-pwm} <com.pi4j.plugin.pigpio.provider.pwm.PiGpioPwmProviderImpl> {com.pi4j.plugin.pigpio.provider.pwm.PiGpioPwmProviderImpl} 
│ └─PROVIDER: "RaspberryPi PWM Provider" {raspberrypi-pwm} <com.pi4j.plugin.raspberrypi.provider.pwm.RpiPwmProviderImpl> {com.pi4j.plugin.raspberrypi.provider.pwm.RpiPwmProviderImpl} 
├─SERIAL: [2] <com.pi4j.io.serial.SerialProvider> 
│ ├─PROVIDER: "RaspberryPi Serial Provider" {raspberrypi-serial} <com.pi4j.plugin.raspberrypi.provider.serial.RpiSerialProviderImpl> {com.pi4j.plugin.raspberrypi.provider.serial.RpiSerialProviderImpl} 
│ └─PROVIDER: "PiGpio Serial Provider" {pigpio-serial} <com.pi4j.plugin.pigpio.provider.serial.PiGpioSerialProviderImpl> {com.pi4j.plugin.pigpio.provider.serial.PiGpioSerialProviderImpl} 
├─DIGITAL_INPUT: [2] <com.pi4j.io.gpio.digital.DigitalInputProvider> 
│ ├─PROVIDER: "RaspberryPi Digital Input (GPIO) Provider" {raspberrypi-digital-input} <com.pi4j.plugin.raspberrypi.provider.gpio.digital.RpiDigitalInputProviderImpl> {com.pi4j.plugin.raspberrypi.provider.gpio.digital.RpiDigitalInputProviderImpl} 
│ └─PROVIDER: "PiGpio Digital Input (GPIO) Provider" {pigpio-digital-input} <com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalInputProviderImpl> {com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalInputProviderImpl} 
├─ANALOG_INPUT: [0] <com.pi4j.io.gpio.analog.AnalogInputProvider> 
├─I2C: [2] <com.pi4j.io.i2c.I2CProvider> 
│ ├─PROVIDER: "RaspberryPi I2C Provider" {raspberrypi-i2c} <com.pi4j.plugin.raspberrypi.provider.i2c.RpiI2CProviderImpl> {com.pi4j.plugin.raspberrypi.provider.i2c.RpiI2CProviderImpl} 
│ └─PROVIDER: "PiGpio I2C Provider" {pigpio-i2c} <com.pi4j.plugin.pigpio.provider.i2c.PiGpioI2CProviderImpl> {com.pi4j.plugin.pigpio.provider.i2c.PiGpioI2CProviderImpl} 
├─SPI: [2] <com.pi4j.io.spi.SpiProvider> 
│ ├─PROVIDER: "RaspberryPi SPI Provider" {raspberrypi-spi} <com.pi4j.plugin.raspberrypi.provider.spi.RpiSpiProviderImpl> {com.pi4j.plugin.raspberrypi.provider.spi.RpiSpiProviderImpl} 
│ └─PROVIDER: "PiGpio SPI Provider" {pigpio-spi} <com.pi4j.plugin.pigpio.provider.spi.PiGpioSpiProviderImpl> {com.pi4j.plugin.pigpio.provider.spi.PiGpioSpiProviderImpl} 
└─DIGITAL_OUTPUT: [2] <com.pi4j.io.gpio.digital.DigitalOutputProvider> 
  ├─PROVIDER: "PiGpio Digital Output (GPIO) Provider" {pigpio-digital-output} <com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProviderImpl> {com.pi4j.plugin.pigpio.provider.gpio.digital.PiGpioDigitalOutputProviderImpl} 
  └─PROVIDER: "RaspberryPi Digital Output (GPIO) Provider" {raspberrypi-digital-output} <com.pi4j.plugin.raspberrypi.provider.gpio.digital.RpiDigitalOutputProviderImpl> {com.pi4j.plugin.raspberrypi.provider.gpio.digital.RpiDigitalOutputProviderImpl} 
[main] INFO com.pi4j.util.Console - 
[main] INFO com.pi4j.util.Console - -------------------
[main] INFO com.pi4j.util.Console - |  Pi4J REGISTRY  |
[main] INFO com.pi4j.util.Console - -------------------
REGISTRY: [1] "I/O Registered Instances" <com.pi4j.registry.impl.DefaultRegistry> 
└─IO: "DOUT-1" {my-digital-output-1} <com.pi4j.plugin.raspberrypi.provider.gpio.digital.RpiDigitalOutput> {DOUT-1} 
[main] INFO com.pi4j.util.Console - 
pi@raspberrypi64:~/bin $ 
This is confusing too:

+ java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' MinimalExample2

That says run MinimalExample2 with a classpath of classes * (which covers all jars in that directory) classes (again) and /opt/pi4j/lib/*.

If you have jars in classes, use java -cp classes/jarfilename.jar or * if there are a lot of them. You don't need the ' single quotes either.

As to incognitum's comments, I don't really understand why your program is looking at /tmp. And my /etc/fstab doesn't have an entry for /tmp much less a noexec.

If you can, post the source code for MinimalExample2 and I'll see if I can get it to run.

kellyt
Posts: 7
Joined: Sun May 01, 2022 7:00 pm

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Thu May 05, 2022 11:54 pm

I will try this tonight if possible. I actually missed the comment about /tmp. It has to do with the pi server, I believe. That is an easy thing to try, so I will do that first.

Then I will try to figure out downloading and installing the new version on the server.

And, I will post the MinimalJava2.jave code.

The "This is confusing too:

+ java -classpath '.:classes:*:classes:/opt/pi4j/lib/*' MinimalExample2 '

"

is just from the pi4j -run command ... I assumed that it is just a script to run the hava command that those of us who do not use Linux often tend to struggle with. I will try the run command you used and see what happens.

But ... you got this to run on a pi connected to a piserver??????? That is encouraging.

knute
Posts: 806
Joined: Thu Oct 23, 2014 12:14 am
Location: Texas

Re: PiServer, Pi4j, sudo java, classnotfoundexception

Fri May 06, 2022 2:45 pm

kellyt wrote:
Thu May 05, 2022 11:54 pm
But ... you got this to run on a pi connected to a piserver??????? That is encouraging.
I didn't run it on piserver but I don't think that should make any difference. The Java part shouldn't change.

Return to “Java”