4

I am using ImageMagick on Mac OS X (10.7). I installed it with the help of MacPorts.

When I now enter the Terminal and write:

identify image.jpg

it is working perfectly fine.

But now while executing it from within Java, the following exception gets thrown:

org.im4java.core.CommandException: java.io.FileNotFoundException: identify

I can see it's on the PATH by running:

which identify

with the response:

/opt/local/bin/identify

Now while running:

echo $PATH

I get the response:

/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin

The same code works perfectly on Windows where ImageMagick is also installed.

So why is im4java not finding identify in the PATH at all?

Uwe Günther
  • 2,971
  • 2
  • 21
  • 26
Dejell
  • 13,947
  • 40
  • 146
  • 229
  • Have you tried "/opt/local/bin/identify" instead of "identify"? How are you calling the command in Java? Process exec = Runtime.getRuntime().exec(command);? – Adrian Mar 04 '13 at 10:48
  • I don't call the command. ImageMagick calls it, and it has to be on the class path – Dejell Mar 04 '13 at 10:49
  • Ah okay, I used ImageMagick only for converting sometime, but existing libs where not so nice, so I used a simple cmd call, which was quite easier for me. – Adrian Mar 04 '13 at 10:56
  • @Odelya Did the [solution](http://stackoverflow.com/a/15257454/287984) I provided work for you? If so so it would be nice you could flag it s the answer. – Uwe Günther Mar 09 '13 at 18:43

3 Answers3

6

Like it's described here for OS X 10.8 and here for OS X 10.7 the only complete solution is to set your PATH in /etc/launchd.conf.

Per default the PATH for Applications ist set to /usr/bin:/bin:/usr/sbin:/sbin, even if you do not have a /etc/launchd.conf at all.

So you have to do the following in your terminal:

sudo vi /etc/launchd.conf

and add the following line or modify it, if it already exists:

setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin

Important: Now you need to reboot your Mac!

You can reproduce your PATH in your Java application with the following code:

public class Main {
    public static void main (String[] args) {
        System.out.println("PATH=" + System.getenv().get("PATH"));
    }
}

There is a second solution, if you start your Program from within an IDE like Eclipse you can set the PATH there as well. In Eclipse you can do that via Run | Run Configurations | Environment while selecting your launch configuration on the left side bar under Java Application.

I did reproduce it with the following code and image.jpg located in ${user.dir} aka the current directory where your Java app got launched from.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class Main {
    public static void main (String[] args) {
        System.out.println("PATH=" + System.getenv().get("PATH"));
        try {
            Process exec = Runtime.getRuntime().exec("identify image.jpg");
            InputStream is = exec.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            System.out.println(br.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} 

You should get similar output like this after running the code above:

PATH=/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
image.jpg JPEG 690x518 690x518+0+0 8-bit sRGB 152KB 0.000u 0:00.000

The first output line show your PATH for the Java application you run right now. The second output line comes from identify image.jpg.

Note: I am running Mac OS X 10.8.2 and MacPorts 2.1.3


Note: There were a way prior to Mac OS X 10.8 to set global variables on a user by user base employing ~/.MacOSX/environment.plist. But this is no longer working anymore starting with Mountain Lion (aka Mac OS X 10.8). Details can be checked out here:

Community
  • 1
  • 1
Uwe Günther
  • 2,971
  • 2
  • 21
  • 26
  • I tried your solution. The first one doesn't work, although I set it in aunchd.conf and also the sys out of System.getenv().get("PATH") is /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin – Dejell Mar 12 '13 at 10:42
  • @Odelya Which solution do you refer by "the first one" or better what exactly did not work for you? If you mean the one dumping out the the `PATH` environment variable, please note `System.getEnv()` got first un-deprecated by Sun as of Java 5 (JDK 1.5.0). So which JDK you are using (`java -version`)? – Uwe Günther Mar 12 '13 at 11:51
  • The on with setting the value in aunchd.conf file the problem was like in the accepted answer - I had to add it explicitly to pathparams of image magick. probably somewhere in the code someone changes it – Dejell Mar 12 '13 at 12:07
  • @Odelya Just currious, you named it now 2 times wrongly `aunchd.conf`, but you know its called `/etc/launchd.conf` *NOT* `aunchd.conf` <= Did you miss the `l` like `Linda` in front of the filename while creating `/etc/launchd.conf`? This would explain why it is not working for you. – Uwe Günther Mar 12 '13 at 12:11
  • I missed it by mistake. I meant launchd.conf – Dejell Mar 12 '13 at 13:34
  • @Odelya Did you also reboot your Mac after putting `setenv PATH /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin` in your `/etc/launchd.conf`? – Uwe Günther Mar 12 '13 at 13:46
  • @Odelya What did then the following test code, I posted in my answer, put on stdout? Testcode: `public class Main { public static void main (String[] args) { System.out.println("PATH=" + System.getenv().get("PATH")); } }` – Uwe Günther Mar 12 '13 at 14:06
  • /opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin but the program didn't run since I needed to set ProcessStarter.setGlobalSearchPath – Dejell Mar 12 '13 at 14:59
  • @Odelya Of course to set `ProcessStarter.setGlobalSearchPath("/opt/local/bin");` is the right solution if you do not want to set the `PATH` globaly for every user in `/etc/launchd.conf`. I just got curious why the general solution, using the `/etc/launchd.conf` approach, wouldn't have worked for you. But it does - so I am happy you proved it. – Uwe Günther Mar 12 '13 at 15:15
2

Try setting the search path to the target directory:

import org.im4java.process.ProcessStarter;
ProcessStarter.setGlobalSearchPath("/opt/local/bin");
Hejazi
  • 16,587
  • 9
  • 52
  • 67
1

I assume the Java program is not started from the shell, or as another user (in the latter case, my answer will not help). The same is true for MacOS 10.8, this method does not work there, as Uwe pointed out (see comments for details).

When a program is started from somewhere else than the shell, the environment variables set in the shell configuration scripts like profile or bashrc are obviously not available. To set environment variables for those applications, use the file .MacOSX/environment.plist in your home directory. To create the file, you will need to use the shell, then open it with the property list editor that comes with Xcode and set the PATH variable to the value needed. For details have a look at the documentation from Apple: Mac Developer Library: User Session Environment Variables

Here is an example of the content of an environment.plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>LSCOLORS</key>
        <string>gxfxcxdxbxegedabagacad</string>
        <key>PATH</key>
        <string>/usr/local/bin:/usr/local/sbin:/usr/X11/bin:/usr/local/share/python</string>
   </dict>
</plist>
tty56
  • 151
  • 1
  • 3
  • 1
    This is no longer applicable in Mac OS X 10.8. Please check http://apple.stackexchange.com/questions/57385/where-are-system-environment-variables-set-in-mountain-lion out. At least you should change your answer, reflecting the `~/.MacOSX/environment.plist` stopped working with Mountain Lion, Mac OS X 1.8.0 – Uwe Günther Mar 09 '13 at 18:27