Java "Disabled" Error

Discussion in 'Mac Programming' started by Aleco, Aug 27, 2009.

  1. Aleco macrumors regular

    Joined:
    Aug 7, 2009
    #1
    I've written a class to run a command checking if the OS is Windows or Mac.

    Code:
    if (currentOS.contains("WINDOWS")) {
                            args = new String[] { "cmd.exe",  "/c",  "dir", "|",  "find", "/i",  "Serial Number is" };
                } else if (currentOS.contains("MAC")) {
    						args = new String[] { "system_profiler", "SPHardwareDataType", "|", "grep", "Hardware UUID" };
                } else {
    						args = new String[] { "" };
    			}
    
    When it's been run on a Windows Machine, it works perfectly! When I run it on my Mac, it just returns a simple text saying, "Disabled."

    Is this because Mac has some restrictions to access some data through exec?

    Just to let you know I'm setting args, so then I use the following to run it:
    Code:
    Runtime.getRuntime().exec(args);
    
    If you need the full source, it's HERE.

    Thanks!
     
  2. wrldwzrd89 macrumors G5

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #2
    Are you making sure you're doing a case-insensitive comparison by converting the OS string to UPPERCASE first? Also, have you tested what the OS string actually is on a Mac (by, say, printing it) before attempting to parse it? That'll get the OS detection working properly. As for your other question... it looks like your syntax is okay, but it looks like you're passing too many arguments. Try combining everything on the Mac side into one command string, like this:
    Code:
    args = new String[] { "system_profiler SPHardwareDataType | grep Hardware UUID" };
    
     
  3. Aleco thread starter macrumors regular

    Joined:
    Aug 7, 2009
    #3
    Checking the OS works just fine, using your suggestion gives me this error:

    Code:
    java.io.IOException: Cannot run program "system_profiler SPHardwareDataType | grep Hardware UUID": error=2, No such file or directory	at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)	at java.lang.Runtime.exec(Runtime.java:593)	at java.lang.Runtime.exec(Runtime.java:466)	at getSerial.run(getSerial.java:25)	at getSerial.main(getSerial.java:12)Caused by: java.io.IOException: error=2, No such file or directory	at java.lang.UNIXProcess.forkAndExec(Native Method)	at java.lang.UNIXProcess.<init>(UNIXProcess.java:53)	at java.lang.ProcessImpl.start(ProcessImpl.java:91)	at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)	... 4 more
    
     
  4. wrldwzrd89 macrumors G5

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #4
    I know what's causing that. You have to use the full path to system_profiler for it to work properly.

    Code:
    args = new String[] { "/usr/sbin/system_profiler SPHardwareDataType | grep Hardware UUID" };
     
  5. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    No, it's because Runtime.exec() is not a shell. A shell is the command-line interpreter that parses things like quoted strings and pipe symbols.

    Your Windows command-line is essentially running a shell: cmd.exe, the Windows command-line interpreter.

    To get the equivalent on a Mac (or other Unix-like platform), your command-line must exec a shell, and the command-line args must be the interpretable command-line.

    In bash, your command-line at Terminal.app would be:

    system_profiler SPHardwareDataType | grep "Hardware UUID"

    The bash invocation that treats remaining args as interpretable command-line is:

    bash -c ..interpreted..

    So the command-line should be:

    bash -c 'system_profiler SPHardwareDataType | grep "Hardware UUID"'

    You should be able to translate that into a suitable array of exec() Strings by the propert parsing. I leave this as an exercise. Note: the resulting String[] should contain exactly 3 Strings; if you can't get the answer, ask again and I'll post specific code that's been tested.


    And wrldwzrd89's answer is flawed for two reasons:

    1. Runtime.exec() is not a shell. Not even when the arg is a single String. It is not parsed the same as the C function system(). Read the docs for exec(String) and then read how a default StringTokenizer parses tokens.

    2. Even if it were a shell, the grep pattern is unquoted.
     
  6. Aleco thread starter macrumors regular

    Joined:
    Aug 7, 2009
    #6
    Thanks for your replies.

    @wrldwzrd89:
    I tried you're method, however I'm given an error:
    Code:
    java.io.IOException: Cannot run program "/usr/sbin/system_profiler SPHardwareDataType | grep Hardware UUID": error=2, No such file or directory	at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)	at java.lang.Runtime.exec(Runtime.java:593)	at java.lang.Runtime.exec(Runtime.java:466)	at getSerial.run(getSerial.java:25)	at getSerial.main(getSerial.java:12)Caused by: java.io.IOException: error=2, No such file or directory	at java.lang.UNIXProcess.forkAndExec(Native Method)	at java.lang.UNIXProcess.<init>(UNIXProcess.java:53)	at java.lang.ProcessImpl.start(ProcessImpl.java:91)	at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)	... 4 more
    
    @chown33:
    Thanks for you're reply, this is actually somewhat logical however I'm not getting the 3 string array part. :s It's somehow eating me up, because of the single quotes between the double quotes are the grep pattern. Would you mind helping me out? :(
     
  7. wrldwzrd89 macrumors G5

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #7
    You need to escape the quote characters with backslashes - like this: \"text\"
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    No, that won't work.
     
  9. Aleco thread starter macrumors regular

    Joined:
    Aug 7, 2009
    #9
    I used the following:
    Code:
    "bash -c", "system_profiler SPHardwareDataType | grep ", "\"Hardware UUID\""
    
    Received this error:
    Code:
    java.io.IOException: Cannot run program "bash -c": error=2, No such file or directory	at java.lang.ProcessBuilder.start(ProcessBuilder.java:459)	at java.lang.Runtime.exec(Runtime.java:593)	at java.lang.Runtime.exec(Runtime.java:466)	at getSerial.run(getSerial.java:25)	at getSerial.main(getSerial.java:12)Caused by: java.io.IOException: error=2, No such file or directory	at java.lang.UNIXProcess.forkAndExec(Native Method)	at java.lang.UNIXProcess.<init>(UNIXProcess.java:53)	at java.lang.ProcessImpl.start(ProcessImpl.java:91)	at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)	... 4 more
    
     
  10. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #10
    Good try.

    Each arg must be in its own String. The command-line must be a single String. Putting those together:

    "bash",
    "-c",
    "system_profiler SPHardwareDataType | grep \"Hardware UUID\""
     
  11. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #11
    Hmm, I just checked using Leopard 10.5.6, and I don't see anything in the output from the system_profiler SPHardwareDataType command that contains the word "UUID", so I hope you're prepared to get an empty response.

    I do see "Serial Number", so maybe you'll want to use that instead.

    This is on a Core 2 Duo Mac mini (about a year old).

    YMMV.
     
  12. Aleco thread starter macrumors regular

    Joined:
    Aug 7, 2009
    #12
    I originally was going to use the Serial Number, but I just changed it to Hardware UUID, just for testing purposes.

    On my MBP, it does give me a Hardware UUID.

    Originally the case for this program is to get ones Hard Drive Serial Number.

    Edit:
    Seems like the Hardware UUID was added after the 10.5.8 update
     

Share This Page