capture perl output with java - java

Alright, I'll get into the meat of things straight away:
I want to run a perl script from a java app (via ProcessBuilder), which will then parse an html page and find out some required information. I then want to pass that information back to my java app, and display that information in a JTextArea.
My knowledge of perl is VERY limited. My original thought was to write this data to a txt file, and then read that file with my java program, which could then display it to JTextArea pretty easily. However, this seems like an ugly solution, compared to simply returning a string.
Please let me know if there is a better way to do this. perhaps a completely different method than what I'm thinking of. Thanks,
Aelfhere

I think you want something like this

You can pass strings between processes only by using some type of inter-process communication: either a pipe or shared memory or using network.
Why can you not do in Java what you want to do in Perl?

when you use a ProcessBuilder you instantiate a Process Object it's java representation of a batch execution
Tipically you can hook process streaming via Java API.
Extracted from Process JAVA API:
abstract
InputStream getErrorStream()
Gets the error stream of the subprocess
abstract
InputStream getInputStream()
Gets the input stream of the subprocess
abstract
OutputStream getOutputStream()
Gets the output stream of the subprocess
If perl script write on standard output stream then you can read that output.
Generally, If process doesn't write on standard output stream then you cannot read it.

Related

Entering data into an InputStream

I know that InputStreams are for reading, and OutputStreams are for writing... but if I have an application that passes all data from an InputStream to the remote side and pushes all received data from that remote side to the OutputStream and I need to send dynamic data to that remote side... how would I enter it into the InputStream? I can do this easily in the Java console since anything entered in is put into System.in and sent to that remote side, and anything coming back is processed through System.out, but obviously I cannot use a Java console in production. How would I emulate this functionality e.g. create a button that sends "command X\r" as if it were typed into the java console?
Note: For background, I'm using JSch to SSH into a Cisco ASA. Where I have set Channel.setInputStream(System.in) and Channel.setOutputStream(System.out) to communicate through console successfully.
I am not familiar with JSch, and I suspect you have this backwards. First, according to their example, you should actually be executing commands with Channel.setCommand(). Then you can use Channel.getInputStream() to obtain a stream that you can read the remote response from.
That aside, a cursory glance at the documentation seems to suggest that you should use the channel's existing streams and read to / write from them, e.g.:
OutputStream out = Channel.getOutputStream();
String str = "command X\r";
out.write(str.getBytes("us-ascii"));
This would make more sense and is much easier to deal with on your end.
However, as to the general question regarding InputStreams: You can use any InputStream as a source for data. It just so happens that System.in is one that comes from standard input (which is essentially a file).
If you want to use data constructed on the fly, you could use a ByteArrayInputStream, e.g.:
String str = "command X\r";
InputStream in = new ByteArrayInputStream(str.getBytes("us-ascii"));
// do stuff with in
You can use any character encoding you want if us-ascii is not appropriate.
But, again, I suspect you are doing this slightly backwards.

Can proc_open (php => java) have multiple input streams?

I'm using proc_open in php to call java application, send a large text to it for processing and capture a returned result. Is it possible to pass several text strings (input streams) instead of just one?
This is what I've got at the moment:
fwrite($pipes[0], $input);
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
If I do something like this, java still recognizes it as one input stream:
fwrite($pipes[0], $input);
fwrite($pipes[0], $input1);
fwrite($pipes[0], $input2);
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
So is something like this possible at all? If not, any alternatives? I can't use command line params because it's a large text with multiple lines.
It depends what you are trying to do, and what the java application expects.
If you want the Java application to see the concatenation of $input, $input2 and $input3, then sure ... your code will do that.
If you want the Java to be able to automatically see those inputs as distinct streams, then no. As far as the Java IO system is concerned, the bytes are just bytes. There are no natural boundaries ... apart from the ultimate end of the (combined) stream.
If you want the Java to see one stream that it can then split into three streams, then it is possible, but it will require some programming effort.
On the PHP side, you have to add some kind of "framing" information to the stream that tells the Java side where one "stream" ends and the next one starts.
On the Java side, you have to look for / interpret that framing information.
The framing could be done by sending a byte count for each stream followed by the bytes, or it could be done with marker characters or sequences that designate the end of a stream.
Nope, a process has only a single standard input stream, as well as a single standard output stream and a single standard error (output) stream (this is true for every process not just java or php).
You can set up some socket communication, e.g. a client-server architecture, that would allow for multiple streams, but would only help if both client (php) and server (java) can do multi threading.
You can send through the pipe some delimiter sequence, so java can distinguish the three input strings
You can simply use more than one proc_open
EDIT:
You can use files instead of the stdin and stdout (php and java could share those)
You can use unix pipes (similar to the socket solution), but this is pretty hard to implement.

Java using streams as sort of "buffers"

I'm working with a library that I have to provide an InputStream and a PrintStream. It uses the InputStream to gather data for processing and the PrintStream to provide results. I'm stuck using this library and its API cannot be altered.
There are two issues with this that I think have related solutions.
First, the data that needs to be read via the InputStream is not available upfront. Instead, the data is dynamically created by a different part of the application and given to my code as a String via method call. My code's job is to somehow allow the library to read this data through the InputStream provided as I get it.
Second, I need to somehow get the result that is written to the PrintStream and send it to another part of the application as a String. This needs to happen as immediately after the data is put in to the PrintStream as possible.
What it looks like I need are two stream objects that behave more or less like buffers. I need an InputStream that I can shove data in to whenever I have it and a PrintStream that I can grab it's contents whenever it has some. This seems a little awkward to me, but I'm not sure how else to do it.
I'm wondering if anything already exists that allows this kind of behavior or if there is a different (better) solution that will work in the situation I've described. The only thing I can come up with is to try to implement streams with this behavior, but that can become complicated fast (especially since the InputStream needs to block until data is available).
Any ideas?
Edit: To be clear, I'm not writing the library. I'm writing code that is supposed to provide the library with an InputStream to read data from and a PrintStream to write data to.
Looks like both streams need to be constantly reading/writing so you'll need two threads independent of each other. The pattern resembles JMS a little bit, in which case you're feeding information to a "queue" or "topic", and wait for it to be processed then put on a "output" queue/topic. This may introduce additional moving parts, but you could write a simple client to place info onto a JMS queue, then have a listener to just grab messages, and feed it to the input stream constantly. Then another piece of code to read from output stream, and do what you need with it.
Hope this helps.

Separating multiple images from stdin in Java

I want to write a program in Java with support for unix pipeline. The problem is that my input files are images and I need in some way to separate them from one another.
I thought that there is no problem because I can read InputStream using ImageIO.read() without reseting position. But it isn't that simple. ImageIO.read() closes the stream every time an image is read. So I can't read more than one file from stdin. Do you have some solution for this?
The API for read() mentions, "This method does not close the provided InputStream after the read operation has completed; it is the responsibility of the caller to close the stream, if desired." You might also check the result for null and verify that a suitable ImageReader is available.

Why Use java.io.Console?

Just a quick one here.
What are the benefits of using java.io.Console as opposed to using a BufferedReader wrapping an InputStreamReader for System.in?
Why would I use it?
Thanks for any advice!
Because it's code that is already written for you...no need to re-invent the wheel. Chances are, you're not going to get it any better than it already is.
You can use java.io.Console to present an interactive command-line to the user. You could do all that with System.in yourself, but you would have to implement things like noticing when the input was done, or readPassword, etc.
See java.io.Console is finally here!
One of the most popular feature
requests for J2SE in recent times has
been the request to improve console
support and provide a way to enter
passwords with echo disabled.
Developers know this feature 4050435
as it has been skulking in the Top 25
RFEs list for some time.
java.io.Console only works when you start a Java program from a command line without redirecting STDIN/STDOUT.
The main advantage I see with Console over System.in is that you have the readPassword() method, which won't echo the characters typed by the user (I couldn't find a way to do this with System.in).
You also have readLine() which will present a prompt and read a single line. You don't have to create your own LineNumberReader.
But, if you want your Java program to be able to read from STDIN when it's redirected from a file or pipe, you still have to use System.in.
Another trick I'm pretty sure you won't get with Console--I created my own input and output streams and replaced System.in/out with them. My implementation of the stream appended to a log file as well as echoing to the screen.
When I turned on my poor-man's "Debug Info", I could even have it tell me what program/line the sysout came from (It was slow though. It created an exception and examined the appropriate stack entry so it was off by default)
java.io.Console is used to take and read input from the user at runtime and output are displayed after processing the input from user.
For more and detailed information visit https://www.examsmyantra.com/article/58/java/java-io---console-input-and-output

Categories