Fazecast / jSerialComm

Platform-independent serial port access for Java
GNU Lesser General Public License v3.0
1.32k stars 279 forks source link

Support a System.property or some other means to define architecture #141

Closed notthetup closed 6 years ago

notthetup commented 6 years ago

One awesome thing about this library that it automatically detects the platform it's on and loads the correct .so native library, especially on Linux on ARM.

While this feature is great, it does rely on a a bunch of files (/proc/cpuinfo, /lib/ld-linux-armhf.so.3) being accessible (permissions, security policy, etc) and in the appropriate locations. While in most default linux installs for RPi/Beaglebone do work with this, in some other situations, these files might not be available.

So I propose add a System property, maybe something like os.arch_full which can be passed to at compilation stage that would skip the checking of the platform and directly load the .so file.

Should be a simple change at https://github.com/Fazecast/jSerialComm/blob/master/src/main/java/com/fazecast/jSerialComm/SerialPort.java#L126.

On the lines of

if (System.getProperty("os.arch_full")) {
 libraryPath = "Linux/" + System.getProperty("os.arch_full").toLowerCase();
}
hedgecrw commented 6 years ago

Thanks for the suggestion! Just curious, is this an actual problem you're encountering, or just a theoretical? The reason I'm asking is that the link loader (/lib/ld-linux-armhf.so.3) MUST exist and be accessible by all users on an ARM device. The /proc/cpuinfo file could theoretically be missing, but I've yet to encounter anyone with that problem (unless you're the first which is entirely possible).

That being said, just to be safe, I do see the value in your suggestion, so I've gone ahead and implemented the feature exactly as you mentioned, with the ability to set a Java System property of "os.arch_full" to any of the valid Linux architectures (currently armv5, armv6, armv6-hf, armv7, armv7-hf, armv8_32, armv8_64, x86, x86_64) which will bypass automatic detection of the system architecture.

Since the addition of this feature somewhat negates one of the primary purposes of this library - and of Java as a concept - (namely to shield the user from any OS-specific details), I don't think I will add this feature to the documentation, but rather leave it here in the issues section in case anyone in the future comes here specifically searching for a solution to this exact problem. This will also cut down on people filing erroneous bug reports after manually specifying their architecture at compile-time and then forgetting to change it when moving to a different architecture.

The feature will be present in the next minor release of the library. Thanks!

notthetup commented 6 years ago

Thanks @hedgecrw. This is/was an actual problem I was encountering. On development machine I had no issues using it. It works like a charm (Thanks!). But when I moved it to an embedded system, similar to a Beaglebone (arm32-hf), there were lots of strange exceptions. I traced it down to 2 semi-related issues.

  1. Permissions. JVM was being run as a user which didn't have many privileges.
  2. Java Security Policy. The security policy forbid JVM from accessing any files outside the application's scope.

These were put in place for application security etc. But that meant jSerialComms couldn't do it magic and failed. I could change permissions for the actual serial device to allow the JVM user to access it, but allowing access to /proc/cpuinfo, /lib and ldd it was going to be more complex without changing a bunch of other permissions.

Same with Java Security Policy. I couldn't let all of JVM access all those files file because that could be a security issue. I tried to disable the security policy for those file JUST for jSerialComms jar, but that didn't seem to work so well. Still debugging that one.