简体   繁体   中英

The ideal way to detect a raspberry pi from java (jar)

Hello I would like to know which is the ideal way to detect if a jar/java program is running on raspberry pi or not.

Why do I want that? I want to use the watchdog in the raspberry pi but also I use the java program from windows which doesn't or doesn't require the watchdog.

Is there a way to detect if the jar is running on a raspberry the same way some people detect the operative system?

The same way people use that...

class ShowProperties {
    public static void main(String[] args) {
        System.getProperties().list(System.out);
    }
}

Here is some code from one of my helper classes. Notice how isPiUnix is set to true. This technique relies on the PRETTY_NAME or NAME value in the os-release file. Tweak necessary to detect any variations of your supported systems. Note that isLinux and isPiLinux will both return true when running on the Pi which is expected. You only need to test for isPiLinux .

private static boolean isWindows       = false;
private static boolean isLinux         = false;
private static boolean isHpUnix        = false;
private static boolean isPiUnix        = false;
private static boolean isSolaris       = false;
private static boolean isSunOS         = false;
private static boolean archDataModel32 = false;
private static boolean archDataModel64 = false;

static {
    final String os = System.getProperty("os.name").toLowerCase();
    if (os.indexOf("windows") >= 0) {
        isWindows = true;
    }
    if (os.indexOf("linux") >= 0) {
        isLinux = true;
    }
    if (os.indexOf("hp-ux") >= 0) {
        isHpUnix = true;
    }
    if (os.indexOf("hpux") >= 0) {
        isHpUnix = true;
    }
    if (os.indexOf("solaris") >= 0) {
        isSolaris = true;
    }
    if (os.indexOf("sunos") >= 0) {
        isSunOS = true;
    }
    if (System.getProperty("sun.arch.data.model").equals("32")) {
        archDataModel32 = true;
    }
    if (System.getProperty("sun.arch.data.model").equals("64")) {
        archDataModel64 = true;
    }
    if (isLinux) {
        final File file = new File("/etc", "os-release");
        try (FileInputStream fis = new FileInputStream(file);
             BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fis))) {
            String string;
            while ((string = br.readLine()) != null) {
                if (string.toLowerCase().contains("raspbian")) {
                    if (string.toLowerCase().contains("name")) {
                        isPiUnix = true;
                        break;
                    }
                }
            }
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
}

You should be able to work out details of the operating system your JVM is running on by testing the values of these Java system properties:

  • os.name Operating system name
  • os.arch Operating system architecture
  • os.version Operating system version

Use System.getProperty(name) to fetch the value of a system property.


If that isn't sufficiently precise, then you need to resort to non-portable solutions, such as using System.exec(...) to run uname -1 or similar.

Note: the "raspberrypi" you see on your system is actually the default hostname, and is not a reliable indicator. (It will often be set by the user to something else.)

Building on Java42's answer here is a complete helper class.

Usage in Java code

if (Raspberry.isPi()) {
 ...
}

Test result

javac Raspberry.java
java Raspberry
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"

Raspberry.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

/**
 * Raspberry PI helper class
 * @author wf
 *
 */
public class Raspberry {

  public static boolean debug = false;

  /**
   * check if this java vm runs on a raspberry PI
   * https://stackoverflow.com/questions/37053271/the-ideal-way-to-detect-a-raspberry-pi-from-java-jar
   * 
   * @return true if this is running on a Raspbian Linux
   */
  public static boolean isPi() {
    String osRelease = osRelease();
    return osRelease != null && osRelease.contains("Raspbian");
  }

  /**
   * read the first line from the given file
   * 
   * @param file
   * @return the first line
   */
  public static String readFirstLine(File file) {
    String firstLine = null;
    try {
      if (file.canRead()) {
        FileInputStream fis = new FileInputStream(file);
        BufferedReader bufferedReader = new BufferedReader(
            new InputStreamReader(fis));
        firstLine = bufferedReader.readLine();
        fis.close();
      }
    } catch (Throwable th) {
      if (debug)
        th.printStackTrace();
    }
    return firstLine;
  }

  /**
   * get the operating System release
   * 
   * @return the first line from /etc/os-release or null
   */
  public static String osRelease() {
    String os = System.getProperty("os.name");
    if (os.startsWith("Linux")) {
      final File osRelease = new File("/etc", "os-release");
      return readFirstLine(osRelease);
    }
    return null;
  }

  /**
   * entry point to call from command line
   */
  public static void main(String args[]) {
    if (isPi()) {
      System.out.println(osRelease());
    }
  }
}

Like Stephen C said you can use the os.* properties.

You may run the uname -a from inside your Java app, but that is probably a bad idea because the format varies wildly. My RPI2 running OMC (media player distro) I get with your code:

os.arch=arm
os.name=Linux
os.version=4.4.6-3-osmc

and uname -a reports:

Linux osmc 4.4.6-3-osmc #1 SMP PREEMPT Fri Apr 1 20:55:03 UTC 2016 armv7l GNU/Linux

Also you can give a look at the PI4J project. They have an example that outputs info about the PI it is running. Try to see the code on how do they do it.

this function will detect if is RasberryPi

private static StringBuilder StringBuilderResult;

private static boolean DetectRaspBPi() {
    GetInfoByExecuteCommandLinux("cat /proc/device-tree/model", false);
    return StringBuilderResult.toString().toLowerCase().contains("raspberry");
}

private static void GetInfoByExecuteCommandLinux(String command, boolean getList){
    try {
        Process pb = new ProcessBuilder("bash", "-c", command).start();
        BufferedReader reader=new BufferedReader(
                new InputStreamReader(pb.getInputStream())
        );
        String line;
        if (getList){
            ListStringBuilderResult = new ArrayList<>();
        } else {
            StringBuilderResult = new StringBuilder();

        while((line = reader.readLine()) != null)
        {
            if (getList){
                ListStringBuilderResult.add(line);
            } else {
                StringBuilderResult.append(line);
            }
        }
    } catch (Exception e){
        System.out.println(e.getMessage());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM