Issue related to running python script from java

  • (2 Pages)
  • +
  • 1
  • 2

17 Replies - 881 Views - Last Post: 11 June 2020 - 04:26 AM Rate Topic: -----

#1 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Issue related to running python script from java

Posted 12 May 2020 - 07:28 PM

Hi
I have a python code that is used to communicate with Mqtt server adafruit.io, and I wanted to call this file from java. I tried serval ways to do so, and all of them failed. I found several persons on stackoverflow confirm that system calls works well, but they do not give me any output from the file. Any suggestions?
Is This A Good Question/Topic? 0
  • +

Replies To: Issue related to running python script from java

#2 ndc85430   User is offline

  • I think you'll find it's "Dr"
  • member icon

Reputation: 1027
  • View blog
  • Posts: 3,951
  • Joined: 13-June 14

Re: Issue related to running python script from java

Posted 12 May 2020 - 11:03 PM

Why the mix of languages? Would it not be easier to do everything in one?
Was This Post Helpful? 0
  • +
  • -

#3 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Re: Issue related to running python script from java

Posted 13 May 2020 - 01:11 AM

View Postndc85430, on 12 May 2020 - 11:03 PM, said:

Why the mix of languages? Would it not be easier to do everything in one?


Good question. Actually because of 2 reasons:
1- The library to interface with that server is written in several languages, and Java is not one of them. So I chose python library, even if I am not experienced in it.
2- I am more experienced in Java and GUI applications using it, only I need Python code for interface with server.


I tried system calls procedure and Jython procedure. Jython worked with simple python scripts, but gave errors with the complex server script. System calls did not give errors and did not give output too!

I tried the approach depending on "Runtime.getRuntime().exec" and gave me nothing:
   String s = null;
        Process p = Runtime.getRuntime().exec("python num.py");
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        while((s= in.readLine())!=null)
        {
            System.out.println(s);
        }



I use netbeans 8.2 and windows 8.1.
Was This Post Helpful? 0
  • +
  • -

#4 g00se   User is online

  • D.I.C Lover
  • member icon

Reputation: 3702
  • View blog
  • Posts: 16,962
  • Joined: 20-September 08

Re: Issue related to running python script from java

Posted 13 May 2020 - 03:37 AM

You should be reading the stderr of that process too
Was This Post Helpful? 1
  • +
  • -

#5 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Re: Issue related to running python script from java

Posted 13 May 2020 - 03:34 PM

View Postg00se, on 13 May 2020 - 03:37 AM, said:

You should be reading the stderr of that process too



Good idea, but I have never did this before actually. I modified the code so I added:

  Process p = Runtime.getRuntime().exec("python num.py");
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        while((s= in.readLine())!=null)
        {
            System.out.println(s);
             
        }
       System.out.println(p.getErrorStream());




This gave me the following result:
[email protected]
Was This Post Helpful? 0
  • +
  • -

#6 g00se   User is online

  • D.I.C Lover
  • member icon

Reputation: 3702
  • View blog
  • Posts: 16,962
  • Joined: 20-September 08

Re: Issue related to running python script from java

Posted 13 May 2020 - 04:23 PM

You should treat the error stream exactly like the output (other) stream. Often times this should be done in separate threads. But you might start without that
Was This Post Helpful? 0
  • +
  • -

#7 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Re: Issue related to running python script from java

Posted 14 May 2020 - 01:44 AM

View Postg00se, on 13 May 2020 - 04:23 PM, said:

You should treat the error stream exactly like the output (other) stream. Often times this should be done in separate threads. But you might start without that


Sorry, but I did not get it. Is there any example that you could refer me to?
Was This Post Helpful? 0
  • +
  • -

#8 g00se   User is online

  • D.I.C Lover
  • member icon

Reputation: 3702
  • View blog
  • Posts: 16,962
  • Joined: 20-September 08

Re: Issue related to running python script from java

Posted 14 May 2020 - 03:18 AM

You'd do exactly what you've just done but instead use
https://docs.oracle....etErrorStream()
Was This Post Helpful? 0
  • +
  • -

#9 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Re: Issue related to running python script from java

Posted 16 May 2020 - 01:01 PM

View Postg00se, on 14 May 2020 - 03:18 AM, said:

You'd do exactly what you've just done but instead use
https://docs.oracle....etErrorStream()


I did this
  Process p;
    public static void main(String[] args) throws ScriptException, IOException {
    try{
        String s = null;
        Process p = Runtime.getRuntime().exec("python num.py");
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        while((s= err.readLine())!=null)
        {
            System.out.println(s);
             
        }
       
        while((s= in.readLine())!=null)
        {
            System.out.println(s);
             
        }
    }
    catch(IOException ie)
    {
        ie.printStackTrace();
        
        
        
    }
    
    }





I believe that this is what you meant. I got an error in beginning "[Errno 2] No such file or directory", so I knew that I got error stream correctly, and I fixed the problem in path. Then nothing again, nothing appear now in output, neither result from python file, nor error from error stream :/
Was This Post Helpful? 0
  • +
  • -

#10 NormR   User is online

  • D.I.C Lover
  • member icon

Reputation: 834
  • View blog
  • Posts: 6,402
  • Joined: 25-December 13

Re: Issue related to running python script from java

Posted 16 May 2020 - 02:10 PM

Quote

nothing appear now in output

What did you expect to see?
Was This Post Helpful? 0
  • +
  • -

#11 g00se   User is online

  • D.I.C Lover
  • member icon

Reputation: 3702
  • View blog
  • Posts: 16,962
  • Joined: 20-September 08

Re: Issue related to running python script from java

Posted 16 May 2020 - 04:33 PM

See http://technojeeves....copying-streams and outputProcessStreams
Was This Post Helpful? 1
  • +
  • -

#12 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Re: Issue related to running python script from java

Posted 26 May 2020 - 03:06 PM

View Postg00se, on 16 May 2020 - 04:33 PM, said:

See http://technojeeves....copying-streams and outputProcessStreams


sorry for latency, I was busy in some issues.

I have used the class you sent me. I am not sure I did it correctly:
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package java_python_test;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.concurrent.atomic.AtomicReference;

/**
 *
 * @author Mostafa
 */
public class Java_Python_Test {

    /**
     * @param args the command line arguments
     */
     Process p;
    public static void main(String[] args) throws ScriptException, IOException {
    try{
        String s = null;
        Process p = Runtime.getRuntime().exec("python num.py");
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        
      
        while((s= err.readLine())!=null)
        {
            IOUtils.collectProcessText(p);
           System.out.println(IOUtils.collectProcessText(p));
             
        }
       
        while((s= in.readLine())!=null)
        {
            IOUtils.collectProcessText(p);
            System.out.println(IOUtils.collectProcessText(p));
             
        }
    }
    catch(IOException ie)
    {
        ie.printStackTrace();
        
        
        
    }
    
    }
    
}

class IOUtils {

    // Various options for closing streams
    public static final int CLOSE_NEITHER = 1;
    public static final int CLOSE_INPUT = 2;
    public static final int CLOSE_OUTPUT = 4;
    public static final int CLOSE_BOTH = 6;
    public static final int DEFAULT_READ_BUFFER_SIZE = 1 << 10 << 3;    // 8KiB

    /**
     * Collect the output from a process in such a way as we can use
     * 'binary' output as well. The call will block until both stdout
     * and stderr have been read.
     *
     *
     * @param p The Process we're collecting from
     * @param stdout A stream for collecting stdout into a usable form
     * @param stderr A stream for collecting stderr into a usable form
     */
    public static void collectProcessStreams(final Process p, final ByteArrayOutputStream stdout,
                                             final ByteArrayOutputStream stderr) {
        Thread runStdout = new Thread() {
            public void run() {
                IOUtils.copyStream(p.getInputStream(), stdout);
            }
        };

        runStdout.start();

        Thread runStderr = new Thread() {
            public void run() {
                IOUtils.copyStream(p.getErrorStream(), stderr);
            }
        };

        runStderr.start();

        try {
            runStdout.join();
        } catch (InterruptedException e) {

            // ignore
        }

        try {
            runStderr.join();
        } catch (InterruptedException e) {

            // ignore
        }
    }

    /**
     * Collect the output from a Process where that output is text.
     * The call will block until both stdout
     * and stderr have been read.
     *
     * @param p The streams we want to collect from the Process
     * @param stdout A stream for collecting textual stdout into a usable form
     * @param stderr A stream for collecting stderr into a usable form
     */
    public static void collectProcessStreams(final Process p, final StringBuilder stdout, final StringBuilder stderr) {
        Thread runStdout = new Thread() {
            public void run() {
                ByteArrayOutputStream out = new ByteArrayOutputStream();

                IOUtils.copyStream(p.getInputStream(), out);
                stdout.append(new String(out.toByteArray()));
            }
        };

        runStdout.start();

        Thread runStderr = new Thread() {
            public void run() {
                ByteArrayOutputStream err = new ByteArrayOutputStream();

                IOUtils.copyStream(p.getErrorStream(), err);
                stderr.append(new String(err.toByteArray()));
            }
        };

        runStderr.start();

        try {
            runStdout.join();
        } catch (InterruptedException e) {

            // ignore
        }

        try {
            runStderr.join();
        } catch (InterruptedException e) {

            // ignore
        }
    }

    /**
     * A convenience method to get stdout from a Process
     * where the content is text. Any stderr output
     * will be printed there.
     *
     *
     * @param p The Process whose stdout we want to collect
     * @return A String containing the output from stdout
     */
    public static String collectProcessText(final Process p) {
        final AtomicReference<String> result = new AtomicReference<>(null);
        Thread runStdout = new Thread() {
            ByteArrayOutputStream stdout = new ByteArrayOutputStream();
            public void run() {
                IOUtils.copyStream(p.getInputStream(), stdout);
                result.set(new String(stdout.toByteArray()));
            }
        };

        runStdout.start();

        Thread runStderr = new Thread() {
            public void run() {
                IOUtils.copyStream(p.getErrorStream(), System.err);
            }
        };

        runStderr.start();

        try {
            runStdout.join();
        } catch (InterruptedException e) {

            // ignore
        }

        try {
            runStderr.join();
        } catch (InterruptedException e) {

            // ignore
        }

        return result.get();
    }

    /**
     * Method description
     *
     *
     * @param in
     * @param out
     */
    public static void copyReader(Reader in, Writer out) {
        try {
            char[] buffer = new char[DEFAULT_READ_BUFFER_SIZE];
            int charsRead = -1;

            while ((charsRead = in.read(buffer)) > -1) {
                out.write(buffer, 0, charsRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Copy a stream
     *
     * @param in The source stream
     * @param out The target stream
     */
    public static void copyStream(InputStream in, OutputStream out) {
        try {
            byte[] buffer = new byte[DEFAULT_READ_BUFFER_SIZE];
            int bytesRead = -1;

            while ((bytesRead = in.read(buffer)) > -1) {
                out.write(buffer, 0, bytesRead);
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {

                /* ignore */
            }

            try {
                out.close();
            } catch (IOException e) {

                /* ignore */
            }
        }
    }

    /**
     *
     * @param in The source stream
     * @param out The target stream
     * @param closeOptions Which stream(s) do we want to close? A bit mask
     */
    public static void copyStream(InputStream in, OutputStream out, int closeOptions) {
        try {
            byte[] buffer = new byte[DEFAULT_READ_BUFFER_SIZE];
            int bytesRead = -1;

            while ((bytesRead = in.read(buffer)) > -1) {
                out.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            // Ignore anything else if CLOSE_NEITHER is set
            if ((closeOptions & IOUtils.CLOSE_NEITHER) < 1) {
                try {
                    if ((closeOptions & IOUtils.CLOSE_INPUT) > 0) {
                        in.close();
                    }
                } catch (IOException e) {

                    /* ignore */
                }

                try {
                    if ((closeOptions & IOUtils.CLOSE_OUTPUT) > 0) {
                        out.close();
                    }
                } catch (IOException e) {

                    /* ignore */
                }
            }
        }
    }

    /**
     * Fill a byte array with the contents of a file
     *
     * @param fileName The file to use
     *
     * @return The resulting byte array
     */
    public static byte[] fileToByteArray(String fileName) {
        DataInputStream in = null;
        byte[] result = null;

        try {
            File f = new File(fileName);
            int fileSize = (int) f.length();

            in = new DataInputStream(new FileInputStream(f));
            result = new byte[fileSize];
            in.readFully(result);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (Exception e) {    /* ignore */
            }
        }

        return result;
    }

    /**
     * Description of the Method
     *
     * @param file
     *          The file to be turned into a String
     * @return  The file as String encoded in the platform
     * default encoding
     */
    public static String fileToString(String file) {
        String result = null;
        DataInputStream in = null;

        try {
            File f = new File(file);
            byte[] buffer = new byte[(int) f.length()];

            in = new DataInputStream(new FileInputStream(f));
            in.readFully(buffer);
            result = new String(buffer);
        } catch (IOException e) {
            throw new RuntimeException("IO problem in fileToString", e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {    /* ignore it */
                }
            }
        }

        return result;
    }

    /**
     *  Description of the Method
     *
     * @param  in               The InputStream to turn into a byte array
     * @return                  The desired byte array
     * @exception  IOException  General IO exception
     */
    public static byte[] inputStreamToByteArray(InputStream in) throws IOException {
        byte[] result;
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        IOUtils.copyStream(in, out, IOUtils.CLOSE_BOTH);
        result = out.toByteArray();

        return result;
    }

    /**
     *  Description of the Method
     *
     * @param  in               The InputStream to turn into a byte array
     * @return                  The desired String
     * @exception  IOException  General IO exception
     */
    public static String inputStreamToString(InputStream in) throws IOException {
        return new String(IOUtils.inputStreamToByteArray(in));
    }

    /**
     * Copy stderr and stdout of a Process to the console
     *
     * @param p The streams we want to show from the Process
     */
    public static void outputProcessStreams(final Process p) {
        Thread runStdout = new Thread() {
            public void run() {
                IOUtils.copyStream(p.getInputStream(), System.out);
            }
        };

        runStdout.start();

        Thread runStderr = new Thread() {
            public void run() {
                IOUtils.copyStream(p.getErrorStream(), System.err);
            }
        };

        runStderr.start();
    }
}




The code runs without errors, and still Python code output is not appearing .
Was This Post Helpful? 0
  • +
  • -

#13 mfalcon   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 39
  • Joined: 16-August 16

Re: Issue related to running python script from java

Posted 26 May 2020 - 03:11 PM

View PostNormR, on 16 May 2020 - 02:10 PM, said:

Quote

nothing appear now in output

What did you expect to see?


The python code is fairly simple:

for i in range(1,10):
    print(i)


It prints numbers from 1 to 10
Was This Post Helpful? 0
  • +
  • -

#14 NormR   User is online

  • D.I.C Lover
  • member icon

Reputation: 834
  • View blog
  • Posts: 6,402
  • Joined: 25-December 13

Re: Issue related to running python script from java

Posted 26 May 2020 - 04:25 PM

Are those 2 lines the whole python file you are trying to execute?
Was This Post Helpful? 0
  • +
  • -

#15 NormR   User is online

  • D.I.C Lover
  • member icon

Reputation: 834
  • View blog
  • Posts: 6,402
  • Joined: 25-December 13

Re: Issue related to running python script from java

Posted 26 May 2020 - 04:36 PM

When I run this code on my Win10 PC
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.concurrent.atomic.AtomicReference;

/**
 *
 * @author Mostafa
 */
public class Java_Python_Test {

    /**
     * @param args the command line arguments
     */
     Process p;
    public static void main(String[] args) throws ScriptException, IOException {
    try{
        String s = null;
        Process p = Runtime.getRuntime().exec("py SimplePython.py");
        BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
        BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
        
      
        while((s = err.readLine())!=null)
        {
//            IOUtils.collectProcessText(p);
//            System.out.println(IOUtils.collectProcessText(p));
            System.out.println(s);
             
        }
       
        while((s = in.readLine())!=null)
        {
//            IOUtils.collectProcessText(p);
//            System.out.println(IOUtils.collectProcessText(p));
            System.out.println(s);
             
        }
    }
    catch(IOException ie)
    {
        ie.printStackTrace();
        
        
        
    }
    
    }
    
}


I get the following output:

Quote

Running: java.exe -client Java_Python_Test

1
2
3
4
5
6
7
8
9

0 error(s)

Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2