I have a web based app that I need to launch from time to time using Java. The app only runs in a browser window so I need to get that running. I used OS X for my development and it runs fine on my laptop running the server on localhost. But when I deploy (in an oc4j container in a Solaris environment), the browser launch always fails. I think it is a DISPLAY issue but my UNIX is so rusty that I'm not confident about that. Here is the command I'm using to launch the browser in Java:
// my first attempt, commented out here but left for reference
// String cmd = "/opt/sfw/bin/firefox "+ url;
// my latest attempt
String cmd = "DISPLAY=:5 /opt/sfw/bin/firefox "+url+" -width 1600 -height 1200";
Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmd);
current error message looks like this:
08/11/10 11:28:41
user dir: /usr/local/src/oracle/product/10.1.3.2.0/OracleAS_1/j2ee/home
08/11/10 11:28:41
command: DISPLAY=:5 /opt/sfw/bin/firefox file:/var/tmp/DisplayURLs16188.html -width 1600 -height 1200
08/11/10 11:28:41 java.io.IOException: DISPLAY=:5: not found
08/11/10 11:28:41 at java.lang.UNIXProcess.forkAndExec(Native Method)
08/11/10 11:28:41 at java.lang.UNIXProcess.<init>(UNIXProcess.java:53)
08/11/10 11:28:41 at java.lang.ProcessImpl.start(ProcessImpl.java:65)
08/11/10 11:28:41 at java.lang.ProcessBuilder.start(ProcessBuilder.java:451)
08/11/10 11:28:41 at java.lang.Runtime.exec(Runtime.java:591)
08/11/10 11:28:41 at java.lang.Runtime.exec(Runtime.java:429)
08/11/10 11:28:41 at java.lang.Runtime.exec(Runtime.java:326)
08/11/10 11:28:41 at factory.BrowserLauncher.openURL(BrowserLauncher.java:116)
Thanks for any help you can offer!
I don't think java's exec() is a shell; it interprets "DISPLAY=:5" as a file name then fails to find it. You can instead give the environment variable to the new process as the second parameter to exec(), it expects an array of strings, see here for details.
You might want to give it a PATH value too at the very least, since it inherits nothing from the Java process when you specify it that way. In fact you should do that anyway, there's no telling what bizzare PATH settings a java virtual machine has.
You're right, the exec doesn't run in the shell. So I finally got it to work by just launching the shell within the exec command:
String[] commands = {"/bin/sh", "-c", " DISPLAY=:5 /opt/sfw/bin/firefox "+url+" -width 1600 -height 1200 "};
Hmm... For some reason the above command stopped working. To be honest, even when it did work, the spawned process did not update the files I wanted it to properly. So I went back to trying it as a straight process instead of running it in a frame buffer. But it is again complaining that it can't open the display. Since it's headless, how do I set the environment variable? I thought I was setting it to the frame buffer running on display 5. But now that isn't working. So I guess I have two questions.
- Is it possible to get this to work without a frame buffer?
- If not, how can I check to see if the frame buffer is running? (because it seems to not be working anymore)
Here's a sample of the recent error messages:
LINUX/UNIX browser attempting to launch /opt/sfw/bin/firefox file:/var/tmp/DisplayURLs21267.html
08/12/03 10:55:27
user dir: /usr/local/src/oracle/product/10.1.3.2.0/OracleAS_1/j2ee/home
08/12/03 10:55:27 cmd 0: /bin/sh
08/12/03 10:55:27 cmd 1: /opt/sfw/bin/firefox
08/12/03 10:55:27 cmd 2: file:/var/tmp/DisplayURLs21267.html
08/12/03 10:55:32 ERR>
08/12/03 10:55:32 ERR>(firefox-bin:19045): Gtk-WARNING **: cannot open display:
08/12/03 10:55:32 ExitValue: 1
Ok, I'm convinced that this is some sort of configuration problem. I can get the browser to launch when written as a simple java program compiled at the command line:
import java.util.*;
import java.io.*;
public class Launcher {
public static void main(String args[]) throws IOException {
String url = "http://www.ebay.com";
String[] commands = {"/bin/sh", "-c", "/opt/sfw/bin/firefox ", url, "-width", "1600", "-height", "1200", ":5"};
ProcessBuilder pb = new ProcessBuilder(commands);
Map<String, String> env = pb.environment();
env.put( "DISPLAY", ":5" );
Iterator it = env.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
System.out.println("\t>> environ: "+pairs.getKey() + " = " + pairs.getValue());
}
Process process = pb.start();
}
}
The output is just to show the environment variables and it looks like this:
>> environ: XFILESEARCHPATH = /usr/dt/app-defaults/%L/Dt
>> environ: LANG = C
>> environ: DISPLAY = :5
>> environ: ORACLE_BASE = /oracle
>> environ: ORACLE_TERM = vt100
>> environ: PWD = /usr/local/u00/de8
>> environ: _ = /usr/bin/java
>> environ: MAGICK_HOME = /usr/ImageMagicK/ImageMagick-6.4.4
>> environ: ORACLE_SID = cots
>> environ: USER = de8
>> environ: NLSPATH = /usr/dt/lib/nls/msg/%L/%N.cat
>> environ: EDITOR = /bin/vi
>> environ: MOZILLA\_SOLARIS_PATCHCHECKER = disable_patchchecker
>> environ: HOME = /u00/de8
>> environ: SSH_CONNECTION = 128.219.196.118 64994 160.91.230.33 22
>> environ: LD\_LIBRARY_PATH = /usr/jdk/instances/jdk1.5.0/jre/lib/sparc/server:/usr/jdk/instances/jdk1.5.0/jre/lib/sparc:/usr/jdk/instances/jdk1.5.0/jre/../lib/sparc:/opt/SUNWspro/lib:/usr/openwin/lib:/usr/dt/lib:/usr/ImageMagicK/ImageMagick-6.4.4/lib::/oracle/product/9.2.0/lib
>> environ: LOGNAME = de8
>> environ: SHELL = /bin/ksh
>> environ: ORACLE_HOME = /oracle/product/10.1.3.2.0/OracleAS_1
>> environ: SSH_TTY = /dev/pts/1
>> environ: MAILMSG = [YOU HAVE NEW MAIL]
>> environ: MANPATH = /usr/opt/SUNWmd/man:/usr/man:/usr/local/man:/usr/share/man:
>> environ: NNTPSERVER = time.ornl.gov
>> environ: SSH_CLIENT = 128.219.196.118 64994 22
>> environ: MAIL = /var/mail/de8
>> environ: TZ = US/Eastern
>> environ: PS1 = $\{PWD\#\#\#/\} $
>> environ: TERM = vt100
>> environ: PATH = /oracle/product/10.1.3.2.0/OracleAS\_1:/oracle/product/10.1.3.2.0/OracleAS_1/OPatch:/usr/xpg4/bin:/usr/ccs/bin:/usr/local/bin:/usr/bin:/usr/ucb:/etc:/usr/sbin:/u00/de8/bin:/opt/NSCPcom:/sbin:/usr/local/etc:/usr/lib:/usr/opt/SUNWmd/sbin:/usr/bin:/usr/local/bin/perl5.00502:/usr/openwin/bin:/opt/sfw/bin:/usr/ImageMagicK/ImageMagick-6.4.4/bin:.:/oracle/product/9.2.0/bin
I decided to output the env vars in hopes that it would show what needs to be reset. But if I use the *exact* same code in my deployment, it fails and I get the following env settings:
08/12/09 14:14:27 >> environ: XFILESEARCHPATH = /usr/dt/app-defaults/%L/Dt
08/12/09 14:14:27 >> environ: LANG = C
08/12/09 14:14:27 >> environ: DISPLAY = :5
08/12/09 14:14:27 >> environ: ORACLE_CONFIG_HOME = /oracle/product/10.1.3.2.0/OracleAS_1
08/12/09 14:14:27 >> environ: NLSPATH = /usr/dt/lib/nls/msg/%L/%N.cat
08/12/09 14:14:27 >> environ: TMP = /tmp
08/12/09 14:14:27 >> environ: TZ = US/Eastern
08/12/09 14:14:27 >> environ: NLS_LANG = AMERICAN_AMERICA.WE8MSWIN1252
08/12/09 14:14:27 >> environ: ORA_NLS33 = /oracle/product/10.1.3.2.0/OracleAS_1/ocommon/nls/admin/data
08/12/09 14:14:27 >> environ: LD_LIBRARY_PATH = /usr/local/src/oracle/product/10.1.3.2.0/OracleAS_1/jdk/jre/lib/sparc/server:/usr/local/src/oracle/product/10.1.3.2.0/OracleAS_1/jdk/jre/lib/sparc:/usr/local/src/oracle/product/10.1.3.2.0/OracleAS_1/jdk/jre/../lib/sparc:/oracle/product/10.1.3.2.0/OracleAS_1/opmn/lib:/oracle/product/10.1.3.2.0/OracleAS_1/lib32
08/12/09 14:14:27 >> environ: X_LD_LIBRARY_PATH_64 = /oracle/product/10.1.3.2.0/OracleAS_1/lib
08/12/09 14:14:27 >> environ: ORACLE_HOME = /oracle/product/10.1.3.2.0/OracleAS_1
08/12/09 14:14:27 >> environ: SHELL = /bin/bash
Does anyone know how I can get the deployed version (running in the server container) to work exactly in the same way as the version run from a simple command line?