?
Solved

Lynx, Java, & Runtime.getRuntime().exec()

Posted on 2004-10-06
6
Medium Priority
?
1,907 Views
Last Modified: 2008-02-01
LYnx is a text based browser.  It can convert .html files to its rough equivalent in text.

I am trying to use a simple java program to call lynx.bat or lynx.exe .

Lynx.bat is located in C:\Lynx\lynx.bat

I want to use the "-dump" parameter.

Then I must put the name of the file "mydoc.htm"

Then the name of the new file "mydoctxt.txt"

So in completion it would look like this "lynx.bat -dump mydoc.htm > mydoctxt.txt"

This works completely fine from the command line, but when I try to wrap it in a simple java program, it fails.

Here is what I have so far...

package javaapplication2;
import      java.io.*;
class Main{
   
    public static void main(String argv[]) {
       
        try {
            String ls_str;
           
            //Process ls_proc = Runtime.getRuntime().exec("cmd.exe /E :1900 C:\\lynx\\lynx.exe -dump C:\\test.htm > C:\\test6.txt");
            Process ls_proc = Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\test5.txt");

           
            DataInputStream ls_in = new DataInputStream(
            ls_proc.getInputStream());
           
           
            try {
                while ((ls_str = ls_in.readLine()) != null) {
                    System.out.println(ls_str);

                }
            } catch (IOException e) {
                System.out.println("1st catch block");
                System.exit(0);


            }
        } catch (IOException e1) {
            System.err.println(e1);
            System.out.println("2nd catch block");
            System.exit(1);
        }
       
        System.exit(0);
       
       
    }
   
   
}

When I run that a blank text file called test5.txt is created.  It is 0kb in length.  If I run it straight from the command line in windows XP though, test5.txt is created successfully.  If I uncomment out Process ls_proc = Runtime.getRuntime().exec("cmd.exe /E :1900 C:\\lynx\\lynx.exe -dump C:\\test.htm > C:\\test6.txt"); and comment out the other line, the program lags and nothing happens.

I know I have to be missing something simple here, because I whipped up the equivalent prog in VB, in like 3 minutes.
0
Comment
Question by:bullyellis
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 4

Expert Comment

by:gdrnec
ID: 12240962
I had this problem once and I think that I solved by using Runtime.exec(String[] cmdarray) method instead of all one string.

so String[] cmdarray = {"C:\\lynx\\lynx.bat","-dump","C:\\test.htm",">","C:\\test5.txt"};
Runtime.getRuntime().exec(cmdarray);

I think I remeber this solving it. Hope I'm right.

Geoff
0
 
LVL 37

Expert Comment

by:zzynx
ID: 12241055
Sure it isn't a matter of (back) slashes.

Did you try these already?

            Process ls_proc = Runtime.getRuntime().exec("cmd.exe /E :1900 C:/lynx/lynx.exe -dump C:/test.htm > C:/test6.txt");
or
            Process ls_proc = Runtime.getRuntime().exec("C:/lynx/lynx.bat -dump C:/test.htm > C:/test5.txt");
0
 
LVL 13

Accepted Solution

by:
Webstorm earned 1000 total points
ID: 12242159
Hi bullyellis,

You cannot redirect the output with ">" unless you use cmd.exe.
You have to redirect the outputstream from the Process class to a FileOutputStream like that :

String[] cmdarray = {"cmd.exe","/E:1900","/C","C:\\lynx\\lynx.bat","-dump","C:\\test.htm"};
//String[] cmdarray = {"C:\\lynx\\lynx.exe,"-dump","C:\\test.htm"};

// cmd.exe to invoke the batch file is necessary, but not for the .exe file

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\test5.txt"),
          System.in,false,
          new FileOutputStream("C:\\test5.txt"),true, // stdout redirection
          System.err,false);


// And the RunProcess class is :


public class RunProcess
{
    private Process p=null;
    private static final int BUFFER_SIZE=8192;
    private Thread th_in=null,th_out=null,th_err=null;
    private int ret_code=-1;

    public RunProcess(
        final Process p,
        final InputStream p_in,   final boolean in_close,
        final OutputStream p_out, final boolean out_close,
        final OutputStream p_err, final boolean err_close)
    {
        this.p=p;

        // Process. OUT
        (th_out=new Thread(){
            byte b[]=new byte[BUFFER_SIZE];
            InputStream inp=p.getInputStream();
            public void run()
            {
                try{
                    for(;;)
                    {
                        int sz=inp.read(b);
                        if (p_out!=null) p_out.write(b,0,sz);
                    }
                }catch(Exception e){}
            }
        }).start();

        // Process. ERR
        (th_err=new Thread(){
            byte b[]=new byte[BUFFER_SIZE];
            InputStream inp=p.getErrorStream();
            public void run()
            {
                try{
                    for(;;)
                    {
                        int sz=inp.read(b);
                        if (p_err!=null) p_err.write(b,0,sz);
                    }
                }catch(Exception e){}
            }
        }).start();

        if (p_in!=null)
        // Process. IN
        (th_in=new Thread(){
            byte b[]=new byte[BUFFER_SIZE];
            OutputStream outp=p.getOutputStream();
            public void run()
            {
                try{
                    for(;;)
                    {
                        int sz=p_in.read(b);
                        outp.write(b,0,sz);
                    }
                }catch(Exception e){}
            }
        }).start();

        (new Thread(){
            public void run()
            {
                try{
                    ret_code=p.waitFor();
                }catch(Exception ex){}
                if (th_in!=null) th_in.interrupt();
                try{if (in_close&&(p_in!=null)) p_in.close();}catch(Exception ex){}
                try{if (out_close&&(p_out!=null)) p_out.close();}catch(Exception ex){}
                try{if (err_close&&(p_err!=null)) p_err.close();}catch(Exception ex){}
                if (th_out!=null) th_out.interrupt();
                if (th_err!=null) th_err.interrupt();
            }
        }).start();
    }

    public int getReturnCode()
    {
        return ret_code;
    }

    public int waitFor() throws Exception
    {
        return p.waitFor();
    }

    public void destroy()
    {
        p.destroy();
    }
}
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 92

Expert Comment

by:objects
ID: 12244080
Here an examples of handing the output from a Process that you should be able to easily adapt to your requirements.

http://www.objects.com.au/java/examples/util/ConsoleExec.do
0
 

Author Comment

by:bullyellis
ID: 12244728
WebStorm,

Your code works kind of.

The problem I ran into was

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\test5.txt"),
          System.in,false,
          new FileOutputStream("C:\\test5.txt"),true, // stdout redirection
          System.err,false);

The 2 instances of "test5.txt" can not be named the same thing.

I get an error that "The process cannot access the file because it is being used by another process."  And again I get the empty text file.

However if I change the code to

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\testa.txt"),
          System.in,false,
          new FileOutputStream("C:\\testb.txt"),true, // stdout redirection
          System.err,false);

Then I get both testa and testb.  testa.txt works correctly and is what I want.  testb.txt however is another empty text file.

Could you explain this ?

0
 
LVL 13

Expert Comment

by:Webstorm
ID: 12257048
bullyellis, thanks for the points

When you specify a redirection with '>', cmd.exe will redirect output to this file. So, nothing will be written to the process's stdout stream, and you get an empty file.
If you specify a FileOutputStream you don't have to specify another redirection in the command line and it's only usable with cmd.exe :

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm"),
          System.in,false,
          new FileOutputStream("C:\\testa.txt"),true, // stdout redirection
          System.err,false);

Or

RunProcess ls_proc = new RunProcess(
         Runtime.getRuntime().exec("C:\\lynx\\lynx.bat -dump C:\\test.htm > C:\\testa.txt"),
          System.in,false,
          System.out,false,
          System.err,false);

0

Featured Post

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
The viewer will learn how to implement Singleton Design Pattern in Java.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
Suggested Courses
Course of the Month13 days, 1 hour left to enroll

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question