[SOLVED] Development on Raspberry Pi 4

You need org.jmonkeyengine:jme3-lwjgl3:3.3.2-stable to actually get jmonkey to use lwjgl. But that will only download the main .so files. ARM binaries are not included by default. so you need to add specifically the ARM binaries.

My build.gradle is a bit messy because I am including 32 bits windows and both 32 and 64 bits ARM. plus I am adding binaries for a lot of dependencies:

  runtimeOnly(rootProject.ext["lwjgl-x86"].toString())
  runtimeOnly(rootProject.ext["lwjgl-arm32"].toString())
  runtimeOnly(rootProject.ext["lwjgl-arm64"].toString())
  runtimeOnly(rootProject.ext["lwjgl-glfw-x86"].toString())
  runtimeOnly(rootProject.ext["lwjgl-glfw-arm32"].toString())
  runtimeOnly(rootProject.ext["lwjgl-glfw-arm64"].toString())
  runtimeOnly(rootProject.ext["lwjgl-jemalloc-x86"].toString())
  runtimeOnly(rootProject.ext["lwjgl-jemalloc-arm32"].toString())
  runtimeOnly(rootProject.ext["lwjgl-jemalloc-arm64"].toString())
  runtimeOnly(rootProject.ext["lwjgl-openal-x86"].toString())
  runtimeOnly(rootProject.ext["lwjgl-openal-arm32"].toString())
  runtimeOnly(rootProject.ext["lwjgl-openal-arm64"].toString())
  runtimeOnly(rootProject.ext["lwjgl-opengl-x86"].toString())
  runtimeOnly(rootProject.ext["lwjgl-opengl-arm32"].toString())
  runtimeOnly(rootProject.ext["lwjgl-opengl-arm64"].toString())

where for example rootProject.ext[“lwjgl-arm64”].toString() is equal to “org.lwjgl:lwjgl:3.2.3:natives-linux-arm64” and so on.

Keep in mind though that you will only be able to use OpenGL, NOT OpenGL ES. I really hope JMonkeyEngine added support for OpenGL ES in their desktop library and not only their android library. I would assume it will speed things up quite a bit in RPi, but I wouldn’t know.

2 Likes

Thanks @superjugy :slightly_smiling_face::heart::+1:

1 Like

Hi @superjugy ,

Have you tried controlling GPIO pins using PI4j or j2ME on RPI4 B ? , Because I found RPI forums are not very helpful regarding java developers .

Thanks

Sorry, I have never tried it. My guess is that the easiest way would be to not do it with Java. do it is C and then just wrap a native call from java or something. But I wouldn’t know, never tried it.

1 Like

I found this library: GitHub - mattjlewis/pigpioj: Java JNI wrapper around the pigpio C library which is a JNI wrapper around the pigpio C library. Have you seen this one?. There is also: GitHub - mattjlewis/diozero: Java Device I/O library that is portable across Single Board Computers. Tested with Raspberry Pi, Odroid C2, BeagleBone Black, Next Thing CHIP, Asus Tinker Board and Arduinos. Supports GPIO, I2C, SPI as well as Serial communication. Also known to work with Udoo Quad. and GitHub - nkolban/jpigpio: A Java interface to the Raspberry Pi pigpio library.

1 Like

No those are new to me !

This is the pi4J :

& I have found this book that seems to be using PI4j , j2ME , seems to be an official one :
raspberry-pi-with-java-programming-the-internet-of-things-iot-oracle-press

Anyway , let’s not be too much outside of jme here , I will try Pi4J & j2ME & see if things work.

Thanks , @superjugy

1 Like

Hello @superjugy , just to know , i bought RPI4B , but JmE didnot work even if implementing the 3.2.3lwjgl for arm64 Jme desktop ignores it & searches for its own library on org.jmonkeyEngine.lwjgl ,

so it gives a UnSatisfiedLinkError.openal not supported by Linux-arm64 if using jmeLwjgl

& if using the lwjgl3.2.3 linux arm64 it gives me ClassNotFoundException jme cannot find lwjgl desktop
do you have a solution for this?

as regards Pi4J if you want to know , i have tried it & its working , basically its based on WiringPI C lang library ,so you have to use WiringPI Strategy of wiring pins :slight_smile:

EDIT : Discovered that wiring Pi datasheet of RPI4b would be the same as RPI3B since they have the same number of pins , you can find these data on Pi4J official website

Can you paste your build.gradle? Also, have you updated your rpi4 to the latest?

1 Like

Hi @superjugy , sorry for late reply , i rarely open my RPI these days of exams :sweat_smile: , i have the latest Raspibian installed , what do you mean by update , you mean update through apt packages ? or the system update ?

This is my gradle file :

plugins {
    id 'java'
}

group 'com.Scrappers'
version '1.0'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    implementation "com.pi4j:pi4j-core:1.2" 
    
    implementation "org.lwjgl:lwjgl:3.2.3:natives-linux-arm64"
    implementation "org.jmonkeyengine:jme3-core:3.3.2-stable"
    implementation "org.jmonkeyengine:jme3-desktop:3.3.2-stable"
    
}

currently this gives me this error :

> Task :JmETest.main()
Dec 31, 2020 3:33:24 AM com.jme3.system.JmeDesktopSystem initialize
INFO: Running on jMonkeyEngine 3.3.2-stable
 * Branch: HEAD
 * Git Hash: 1a05e3f
 * Build Date: 2020-04-27
Dec 31, 2020 3:33:25 AM com.jme3.system.JmeDesktopSystem newContextLwjgl
SEVERE: CRITICAL ERROR: Context class is missing!
Make sure jme3_lwjgl-ogl is on the classpath.
java.lang.ClassNotFoundException: com.jme3.system.lwjgl.LwjglDisplay
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:315)
	at com.jme3.system.JmeDesktopSystem.newContextLwjgl(JmeDesktopSystem.java:199)
	at com.jme3.system.JmeDesktopSystem.newContext(JmeDesktopSystem.java:279)
	at com.jme3.system.JmeSystem.newContext(JmeSystem.java:159)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:461)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:127)
	at JmETest.main(JmETest.java:10)

Exception in thread "main" java.lang.NullPointerException
	at com.jme3.system.JmeDesktopSystem.newContext(JmeDesktopSystem.java:280)
	at com.jme3.system.JmeSystem.newContext(JmeSystem.java:159)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:461)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:127)
	at JmETest.main(JmETest.java:10)

> Task :JmETest.main() FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':JmETest.main()'.
> Process 'command '/usr/lib/jvm/java-11-openjdk-armhf/bin/java'' finished with non-zero exit value 1

which is mainly due to lwjgl:display class inside lwjgl of jme that only supports the desktop amd no arm support

Thanks

Hey @Pavl_G,

In your build.gradle I only see you adding the natives for lwjgl. try also adding the natives for lwjgl-glfw, lwjgl-jemalloc, lwjgl-opengl and lwjgl-openal. maybe that will fix it.

As for update, yes, I meant a sudo apt upgrade or sudo apt update

1 Like

Are there any other modules , that must be added also rather than these ?

Those are the only ones I have.

1 Like

I have tried it again , & the same exception keeps poping up , i think while reading through your post , that you have made a mod or a trick that have made the PI forces jme to use lwjgl repositories for lwjgl & not jme repos for lwjgl , I will appreciate that if you can illustrate !

my gradle file:

plugins {
    id 'java'
}

group 'com.Scrappers'
version '1.0'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    jcenter()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    implementation "com.pi4j:pi4j-core:1.2"

    implementation "org.lwjgl:lwjgl:3.2.3:natives-linux-arm64"
    implementation "org.lwjgl:lwjgl-glfw:3.2.3:natives-linux-arm64"
    implementation "org.lwjgl:lwjgl-jemalloc:3.2.3:natives-linux-arm64"
    implementation "org.lwjgl:lwjgl-opengl:3.2.3:natives-linux-arm64"
    implementation "org.lwjgl:lwjgl-openal:3.2.3:natives-linux-arm64"

    implementation "org.jmonkeyengine:jme3-core:3.3.2-stable"

    implementation "org.jmonkeyengine:jme3-desktop:3.3.2-stable"
    
}

Thank you

It finally works , what i was actually missing is that ARMv8 Processor of RPI4B is a 64-bit processor that runs a 32-bit system(ARMv7l) for performance purposes , so implementing these in Raspibian context is wrong :

So , the right way around is :

plugins {
    id 'java'
}

group 'com.Scrappers'
version '1.0'

sourceCompatibility = 1.8

repositories {
    jcenter()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    implementation "com.pi4j:pi4j-core:1.2"
    implementation "com.pi4j:pi4j-gpio-extension:1.2"
    implementation "com.pi4j:pi4j-device:1.2"
    

    implementation "org.lwjgl:lwjgl:3.2.3:natives-linux-arm32"
//    implementation "org.lwjgl:lwjgl-glfw:3.2.3:natives-linux-arm32"
//    implementation "org.lwjgl:lwjgl-opengl:3.2.3:natives-linux-arm32"
//    implementation "org.lwjgl:lwjgl-openal:3.2.3:natives-linux-arm32"

    implementation "org.jmonkeyengine:jme3-core:3.3.2-stable"
    implementation "org.jmonkeyengine:jme3-lwjgl3:3.3.2-stable"
    implementation "org.jmonkeyengine:jme3-desktop:3.3.2-stable"
    
}

only :

    implementation "org.lwjgl:lwjgl:3.2.3:natives-linux-arm32"

is essential , the others are actually bounded to jme-lwjgl3 so the implementation of the natives linux armv32 actually solves the exception of UnsatisfiedLinkError caused by liblwjgl.so for armv32 not found , this Exception :

[LWJGL] Failed to load a library. Possible solutions:
	a) Add the directory that contains the shared library to -Djava.library.path or -Dorg.lwjgl.librarypath.
	b) Add the JAR that contains the shared library to the classpath.
[LWJGL] Enable debug mode with -Dorg.lwjgl.util.Debug=true for better diagnostics.
[LWJGL] Enable the SharedLibraryLoader debug mode with -Dorg.lwjgl.util.DebugLoader=true for better diagnostics.
Jan 02, 2021 3:59:27 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[main,5,main]
java.lang.UnsatisfiedLinkError: Failed to locate library: liblwjgl.so
	at org.lwjgl.system.Library.loadSystem(Library.java:162)
	at org.lwjgl.system.Library.loadSystem(Library.java:62)
	at org.lwjgl.system.Library.<clinit>(Library.java:50)
	at org.lwjgl.system.MemoryUtil.<clinit>(MemoryUtil.java:97)
	at org.lwjgl.system.Pointer$Default.<clinit>(Pointer.java:67)
	at org.lwjgl.system.Callback.<clinit>(Callback.java:41)
	at com.jme3.system.lwjgl.LwjglWindow.createContext(LwjglWindow.java:182)
	at com.jme3.system.lwjgl.LwjglWindow.initInThread(LwjglWindow.java:494)
	at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:625)
	at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:466)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:463)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:127)
	at JmETest.main(JmETest.java:11)

& also :

    implementation "org.jmonkeyengine:jme3-lwjgl3:3.3.2-stable"

must be included in your implementation as well for lwjgl-gl & al & window canvas

EDIT: i will upload a bare-bone jme game(Basic simple) for armv8 32 bit systems or the RPI4b soon…

2 Likes

Glad that you got it working. In my gradle I added all possible binaries so that it was as cross platform as possible, so I had both 64 and 32 bits.

1 Like

Have you got the physics working dude ? because here’s a new problem :sweat_smile:
bullet , bullet-native & Minie all gives me the same Exception , cannot locate the .so object file ,

Exception in thread "main" java.lang.UnsatisfiedLinkError: The required native library 'bulletjme' was not found in the classpath via 'native/linux/arm32/libbulletjme.so'. Error message: no bulletjme in java.library.path: [/usr/java/packages/lib, /usr/lib/arm-linux-gnueabihf/jni, /lib/arm-linux-gnueabihf, /usr/lib/arm-linux-gnueabihf, /usr/lib/jni, /lib, /usr/lib]
	at com.jme3.system.NativeLibraryLoader.loadNativeLibrary(NativeLibraryLoader.java:598)
	at com.jme3.system.JmeDesktopSystem.initialize(JmeDesktopSystem.java:348)
	at com.jme3.system.JmeDesktopSystem.newContext(JmeDesktopSystem.java:271)
	at com.jme3.system.JmeSystem.newContext(JmeSystem.java:159)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:461)
	at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
	at com.jme3.app.SimpleApplication.start(SimpleApplication.java:127)
	at JmETest.main(JmETest.java:11)

i am currently searching lwjgl whether they have ports for armv32 or not !

EDIT : seems bullet physics is not operable on RPIs Raspibian system unless it’s supported by JmonkeyEngine, but we still have an option to use Lineage OS & switch the usage to android system , but notice , it would be hard to implement an interface for keyboard & mouse , it wonot work with the same behavior on the regular desktop

1 Like

I am not using physics for my game yet, so haven’t tried it. But like you said, this is now a JME issue. They need to support ARM in their desktop library, not only android library. Until that change is made in JME, I’m afraid support is limited. The rest worked thanks to LWJGL supporting ARM and gradle being able to download those. If you are able to trick gradle into loading the ARM binaries used in Android, it might work. At this point, I would just request for ARM support to be added to JME natively. Specially Open GL ES, to see if we could get some performance gain.

1 Like

We look forward to the pull requests.

1 Like

And, from a quick look, I think @Pavl_G could probably get a working build by adding some gcc flags to the LinuxArm or LinuxArmHF builds of jme-bullet-native/build.gradle round about here:

(I’d try it myself, but I don’t have the compatible hardware to test it on.)

Also, make sure that JME has indeed built it’s normal LinuxARM binary, hate to have you mess about with Compiler settings and find that the normal build would have been fine If it had been BUILT.

1 Like

I read through this build Gradle , found that arm32 is already supported , but I donot know why Gradle cannot locate libbulletjme.so under the /arm32 dir , plus I have never worked with native libraries before , so I would search around if I could do something

Notice : that this same exception happened with liblwjgl.so under the same dir , so it’s consistent & our fix for that was using LwJGL native implementation for arm32 , either something is wrong with jme or it’s Raspibian that causes the hit , I need to search more