How to flushdns in java - java

I am currently trying to find a way to flush my dns cache through a program in java. When I execute my code, the command prompt appears but i cant figure out how to get my code to execute.
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
class SyncPipe implements Runnable
{
public SyncPipe(InputStream istrm, OutputStream ostrm) {
istrm_ = istrm;
ostrm_ = ostrm;
}
public void run() {
try
{
final byte[] buffer = new byte[1024];
for (int length = 0; (length = istrm_.read(buffer)) != -1; )
{
ostrm_.write(buffer, 0, length);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
private final OutputStream ostrm_;
private final InputStream istrm_;
}
public class FlushCommand {
FlushCommand(InputStream errorStream, PrintStream err) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
This is main method below:
String command = "cmd /c start cmd.exe";
{
};
Process p = null;
try {// Execute command
Process child = Runtime.getRuntime().exec(command);
// Get output stream to write from it
OutputStream out = child.getOutputStream();
out.write("cd C:/ /r/n".getBytes());
out.flush();
out.write("dir /r/n".getBytes());
out.close();
p = Runtime.getRuntime().exec(command);
} catch (IOException ex) {
Logger.getLogger(FlushDNS.class.getName()).log(Level.SEVERE, null, ex);
}
new Thread((Runnable) new FlushCommand(p.getErrorStream(), System.err)).start();
new Thread((Runnable) new FlushCommnad(p.getInputStream(), System.out)).start();
PrintWriter stdin = new PrintWriter(p.getOutputStream());
stdin.println("dir c:\\ /A /Q");
stdin.println("ipconfig/flushdns");
// write any other commands you want here
stdin.close();
int returnCode = 0;
try {
returnCode = p.waitFor();
} catch (InterruptedException ex) {
Logger.getLogger(FlushDNS.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Return code = " + returnCode);
}

Why don't you start from very basic?
Your command is just opening a command window. If I remember correctly, the following should flush your dns and remain unclosed (cmd will not be automatically closed).
String command = "cmd.exe /c start cmd.exe /c start ipconfig /flushdns";
try{
Runtime.getRuntime.exec(command);
catch(...){}
I have to check my old codes in my computer to make sure but I'd suggest you to start from basic and then do multi-threading etc.
Alternatively, you can use process builder to create your command.

Related

Java Process console output [duplicate]

This question already has answers here:
Behavior of Java sockets when closing output stream
(2 answers)
Closed 4 years ago.
I need help with process outputs.
I working on a Process console, and if I write to process output, I need to close to write. If I want to send another command, I get "Stream closed" error. Can anyone help me?
Sources:
public void runServer(String servername) throws InterruptedException{
try {
//ProcessBuilder builder = new ProcessBuilder("cmd", "/c", "start && cmd.exe && cd \""+cm.getDataPath("server")+"\\"+servername+"\\\" && java -jar \""+cm.getDataPath("main")+"\\serverfiles\\"+getServerFile(servername)+"\"");
ProcessBuilder builder = new ProcessBuilder("cmd", "/c", ""+cm.getDataPath("main")+"\\run.bat "+cm.getDataPath("server")+"\\"+servername+"\\ "+cm.getDataPath("main")+"\\serverfiles\\"+getServerFile(servername)+"\"");
final Process process = builder.start(); /*Runtime.getRuntime().exec("cmd.exe /c START "+cm.getDataPath("main")+"\\run.bat "+cm.getDataPath("server")+"\\"+servername+"\\ "+cm.getDataPath("main")+"\\serverfiles\\"+getServerFile(servername)+"\"");*/
final Thread ioThread = new Thread() {
#Override
public void run() {
try {
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
w.printConsole(line+"\n");
}
reader.close();
} catch (final Exception e) {
e.printStackTrace();
}
}
};
ioThread.start();
//process.waitFor();
runningserver = process;
} catch (IOException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void sendCommand(String command){
writer = new BufferedWriter(new OutputStreamWriter(runningserver.getOutputStream()));
try {
writer.append(command);
writer.flush();
writer.close();
} catch (IOException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
}
Every time you call sendCommand(...) you close a BufferedWriter that is wrapped around your server's OutputStream via writer.close();, and this also closes the stream. Don't do this as this prevents you from using this same stream again. In fact, your sendCommand method should re-use a writer field and your code should only close the writer when totally done with the stream.

Calling jpegoptim and pngquant from java Process, passing image in stdin and reading result in stdout: broken pipe or hang

I have an imagen in a variable of type jpeg or png and i am triying to convert it with command line jpegoptim or pngquant via java 1.6.
The problem is that i cannot make it work. I read a lot of answer but i did not find the answer.
this is the last function i tried:
public int execute(byte[] image) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
final Process process = processBuilder.start();
final ByteArrayOutputStream outputBuffer = new ByteArrayOutputStream();
final ByteArrayOutputStream errorBuffer = new ByteArrayOutputStream();
try {
// Handle stdout...
new Thread() {
public void run() {
try {
IOUtils.copy(process.getInputStream(), outputBuffer);
} catch (Exception e) {
LOG.error("Error executing " + commandLine,e);
}
}
}.start();
// Handle sderr...
new Thread() {
public void run() {
try {
IOUtils.copy(process.getErrorStream(), errorBuffer);
} catch (Exception e) {
LOG.error("Error executing " + commandLine,e);
}
}
}.start();
process.getOutputStream().write(image);
process.getOutputStream().flush();
process.waitFor();
result = outputBuffer.toByteArray();
errorMsg = errorBuffer.toString("ASCII");
} catch (InterruptedException e) {
LOG.error("Error executing " + commandLine,e);
} finally {
if( process != null ) {
close(process.getErrorStream());
close(process.getOutputStream());
close(process.getInputStream());
process.destroy();
}
}
return process.exitValue();
}
and commandline is for jpg:
this.commandLine = new ArrayList<String>();
this.commandLine.add("jpegoptim");
this.commandLine.add("-m90");
this.commandLine.add("--stdout");
this.commandLine.add("--stdin");
and for png:
this.commandLine = new ArrayList<String>();
this.commandLine.add("pngquant");
this.commandLine.add("--quality=70-80");
this.commandLine.add(">stdout");
this.commandLine.add("<stdin");
The problem with this code is broken pipe. I tried different ways of code. I read different forum here but I dont know how to make this work.
Thanks in advance.
EDIT:
As LinuxDisciple suggested I changed the command to:
List<String> commandLine = new ArrayList<String>();
commandLine.add("tee");
commandLine.add("-a");
commandLine.add("logfile.log");
And the code to:
byte[] image = jpg.read(args[0]); // path to file...
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
final Process process = processBuilder.start();
OutputStream stdin = process.getOutputStream ();
final InputStream stderr = process.getErrorStream ();
final InputStream stdout = process.getInputStream ();
Thread errorT = new Thread() {
public void run() {
byte[] buf = new byte[1024];
int len;
try {
while ((len = stdout.read(buf)) != -1) {
// process byte buffer
System.out.write(buf, 0, len);
System.out.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
errorT.start();
Thread outputT = new Thread() {
public void run() {
byte[] buf = new byte[1024];
int len;
try {
while ((len = stderr.read(buf)) != -1) {
System.err.write(buf, 0, len);
System.err.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
outputT.start();
stdin.write(image);
stdin.flush();
//stdin.close();
try {
process.waitFor();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stdin.close();
stderr.close();
stdout.close();
The waitfor never returns... what is missing?
If I put "stdin.close();" after the flush (in the code above is commented) the process ends. but the stdout is not fully processed and an error is shown: java.io.IOException: Stream closed twice (one for each thread). The logfile.log is equal to the image, but the stdout is truncated.
I test this by command line:
java -cp testProc.jar testProc.Test image.jpg > image_new.jpg
logfile.log is equal to image.jpg
image_new.jpg is smaller and a truncated version of image.jpg.
some clue?
Start with your last two lines. You don't pass stdin using >stdin. Look for some ProcessBuilder examples to see how to use a BufferedWriter to write to the process's stdin (your Java process's stdout), then do the same for your subprocess' stdout with a BufferedReader.
If you still have issues after that, then for diagnosis, you could try replacing jpegoptim and pngquant with tee -a logfile, which will take stdin and just pipe it right back to stdout (and to a file called logfile). Then you've got a file that has all the piped-in data, or you'll get an empty file and the pipe error because your Java program isn't passing in the data and you can see if it looks right. If instead you get a file with data and you don't get a pipe error, it probably means jpegoptim isn't returning any data. At that point you could pipe the data from logfile into jpegoptim on the command line and play with the options until you get it working, and then use those working options in your Java code.
Finally I made it work!
I found the solution by pure fortune!...
I discommented the line:
stdin.close();
And added just after the line "process.waitFor();": this lines:
errorT.join();
outputT.join();
To process the images the commands are:
commandLine.add("jpegoptim");
commandLine.add("-m90");
commandLine.add("--stdout");
commandLine.add("--stdin");
and:
commandLine.add("pngquant");
commandLine.add("--quality=70-80");
commandLine.add("-");
The final code:
public int execute(List<String> commandLine, byte[] image) throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
final Process process = processBuilder.start();
OutputStream stdin = process.getOutputStream ();
final InputStream stderr = process.getErrorStream ();
final InputStream stdout = process.getInputStream ();
final ByteArrayOutputStream bos = new ByteArrayOutputStream();
Thread errorT = new Thread() {
public void run() {
byte[] buf = new byte[1024];
int len;
try {
while ((len = stdout.read(buf)) != -1) {
// process byte buffer
bos.write(buf, 0, len);
bos.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
errorT.start();
Thread outputT = new Thread() {
public void run() {
byte[] buf = new byte[1024];
int len;
try {
while ((len = stderr.read(buf)) != -1) {
System.err.write(buf, 0, len);
System.err.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
outputT.start();
stdin.write(image);
stdin.flush();
stdin.close();
try {
process.waitFor();
errorT.join();
outputT.join();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
stdin.close();
stderr.close();
stdout.close();
System.out.write(bos.toByteArray());
return 0;
}

Executing 'adb logcat' command using Runtime class

I was trying to get the logcat content into a JTextPane. I used following code hoping it will return the content as String but it freeze and also, doesn't produce an error.
Process exec = null;
try {
exec = Runtime.getRuntime().exec("adb logcat -d");
InputStream errorStream = exec.getErrorStream();
BufferedReader ebr = new BufferedReader(new InputStreamReader(errorStream));
String errorLine;
while ((errorLine = ebr.readLine()) != null) {
System.out.println("[ERROR] :- " + errorLine);
}
if (exec.waitFor() == 0) {
InputStream infoStream = exec.getInputStream();
InputStreamReader isr = new InputStreamReader(infoStream);
BufferedReader ibr = new BufferedReader(isr);
String infoLine;
while ((infoLine = ibr.readLine()) != null) {
System.out.println("[INFO] :- " + infoLine);
}
}
} catch (IOException | InterruptedException ex) {
ex.printStackTrace();
} finally {
if (exec != null) {
exec.destroy();
}
}
I referred to some tutorials but, they were not filling my problem. Is this wrong? Are there any other methods to get the logcat content as a String programmatically? Sorry if this is a dumb question.
The issue you're seeing is that you're trying to process command streams and wait for the executing process, all in the same thread. It's blocking because the process reading the streams is waiting on the process and you're losing the stream input.
What you'll want to do is implement the function that reads/processes the command output (input stream) in another thread and kick off that thread when you start the process.
Second, you'll probably want to use ProcessBuilder rather than Runtime.exec.
Something like this can be adapted to do what you want:
public class Test {
public static void main(String[] args) throws Exception {
String startDir = System.getProperty("user.dir"); // start in current dir (change if needed)
ProcessBuilder pb = new ProcessBuilder("adb","logcat","-d");
pb.directory(new File(startDir)); // start directory
pb.redirectErrorStream(true); // redirect the error stream to stdout
Process p = pb.start(); // start the process
// start a new thread to handle the stream input
new Thread(new ProcessTestRunnable(p)).start();
p.waitFor(); // wait if needed
}
// mimics stream gobbler, but allows user to process the result
static class ProcessTestRunnable implements Runnable {
Process p;
BufferedReader br;
ProcessTestRunnable(Process p) {
this.p = p;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(p.getInputStream());
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
// do something with the output here...
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
}

ProcessBuilder process not running

I'm fairly new to ProcessBuilder and working with threads. In it's current state I have a J-Button which starts a scheduled executor service. The scheduled executor service is used to delegate a process to one of two process builders. The application is meant to record a user conversation. During the conversation, after x minutes it creates a wav and delegates it to an available process for transcription. The problem begins when the transcription class is called. The process is started and the application runs as expected. However, the transcription process doesn't actually do anything until I exit the parent application. Only then it will begin. Checking the task manager it shows as a process but uses 0.0% of the CPU and around 238MB of memory until I exit then the two processes jump to 30%-40% and 500-1000 MB of memory. Also, I am using the .waitFor() but am using a thread to run the .waitFor() process as from what I gather it causes the application to hang. How would I go about fixing this. Sorry I am unable to provide more details but I'm new to this. Thanks in advance!
public class TranDelegator {
Future<?> futureTranOne = null;
Future<?> futureTranTwo = null;
ExecutorService transcriberOne = Executors.newFixedThreadPool(1);
ExecutorService transcriberTwo = Executors.newFixedThreadPool(1);
final Runnable transcribeChecker = new Runnable() {
public void run() {
String currentWav = null;
File inputFile = new File("C:\\convoLists/unTranscribed.txt");
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(inputFile));
} catch (FileNotFoundException e1) {
System.out.println("reader didn't initialize");
e1.printStackTrace();
}
try {
currentWav = reader.readLine();
} catch (IOException e) {
System.out.println("currentWav string issue");
e.printStackTrace();
}
try {
reader.close();
} catch (IOException e) {
System.out.println("reader couldn't close");
e.printStackTrace();
}
if(currentWav != null){
if (futureTranOne == null || futureTranOne.isDone()) {
futureTranOne = transcriberOne.submit((transcriptorOne));
}
else if (futureTranTwo == null || futureTranTwo.isDone()) {
futureTranTwo = transcriberTwo.submit((transcriptorTwo));
}
}
}
};
final Runnable transcriptorOne = new Runnable() {
public void run() {
System.out.println("ONE");
try {
String classpath = System.getProperty("java.class.path");
String path = "C:/Program Files/Java/jre7/bin/java.exe";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp",
classpath, Transcriber.class.getName());
Process process = processBuilder.start();
try {
process.waitFor();
} catch (InterruptedException e) {
System.out.println("process.waitFor call failed");
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("Unable to call transcribeConvo");
e.printStackTrace();
}
}
};
final Runnable transcriptorTwo = new Runnable() {
public void run() {
System.out.println("TWO");
try {
String classpath = System.getProperty("java.class.path");
String path = "C:/Program Files/Java/jre7/bin/java.exe";
ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp",
classpath, Transcriber.class.getName());
Process process = processBuilder.start();
try {
process.waitFor();
} catch (InterruptedException e) {
System.out.println("process.waitFor call failed");
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("Unable to call transcribeConvo");
e.printStackTrace();
}
}
};
}
public class Transcriber {
public static void main(String[] args) throws IOException,
UnsupportedAudioFileException {
retreiveEmpInfo();
TextoArray saveConvo = new TextoArray();
ArrayList<String> entireConvo = new ArrayList();
URL audioURL;
String currentWav = wavFinder();
ConfigReader configuration = new ConfigReader();
ArrayList<String> serverInfo = configuration
.readFromDoc("serverconfig");
while (currentWav != null) {
audioURL = new URL("file:///" + currentWav);
URL configURL = Transcriber.class.getResource("config.xml");
ConfigurationManager cm = new ConfigurationManager(configURL);
Recognizer recognizer = (Recognizer) cm.lookup("recognizer");
recognizer.allocate(); // allocate the resource necessary for the
// recognizer
System.out.println(configURL);
// configure the audio input for the recognizer
AudioFileDataSource dataSource = (AudioFileDataSource) cm
.lookup("audioFileDataSource");
dataSource.setAudioFile(audioURL, null);
// Loop until last utterance in the audio file has been decoded, in
// which case the recognizer will return null.
Result result;
while ((result = recognizer.recognize()) != null) {
String resultText = result.getBestResultNoFiller();
// System.out.println(result.toString());
Collections.addAll(entireConvo, resultText.split(" "));
}
new File(currentWav).delete();
saveConvo.Indexbuilder(serverInfo, entireConvo);
entireConvo.clear();
currentWav = wavFinder();
}
System.exit(0);
}
private static String wavFinder() throws IOException {
String currentWav = null;
int x = 1;
File inputFile = new File("C:\\convoLists/unTranscribed.txt");
File tempFile = new File("C:\\convoLists/unTranscribedtemp.txt");
BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
String currentLine = null;
String newLine = System.getProperty("line.separator");
while ((currentLine = reader.readLine()) != null) {
if (x == 1) {
currentWav = currentLine;
} else {
writer.write(currentLine);
writer.write(newLine);
}
x = 2;
}
reader.close();
writer.flush();
writer.close();
inputFile.delete();
// boolean successful =
tempFile.renameTo(inputFile);
// System.out.println("Success: " + successful);
// System.out.println("currentWav = " + currentWav);
return currentWav;
}
private static void retreiveEmpInfo() throws IOException {
File tempFile = new File("C:\\convoLists/tmp.txt");
BufferedReader reader = new BufferedReader(new FileReader(tempFile));
CurrentEmployeeInfo.setName(reader.readLine());
CurrentEmployeeInfo.setUserEmail(reader.readLine());
CurrentEmployeeInfo.setManagerEmail(reader.readLine());
reader.close();
}
}
This problem may be related to sub-process's input stream buffers.
You should clear the sub-process's input stream buffers.
These stream buffers got increased within the parent process's memory with time and at some moment your sub-process will stop responding.
There are few options to make sub-process work normally
Read continuously from sub-process's input streams
Redirect sub-process's input streams
Close sub-process's input streams
Closing sub-process's input streams
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
InputStream inStream = process.getInputStream();
InputStream errStream = process.getErrorStream();
try {
inStream.close();
errStream.close();
} catch (IOException e1) {
}
process.waitFor();
Reading sub-process's input streams
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
final BufferedReader reader = new BufferedReader(tempReader);
InputStreamReader tempErrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
final BufferedReader errReader = new BufferedReader(tempErrReader);
try {
while ((line = reader.readLine()) != null) {
}
} catch (IOException e) {
}
try {
while ((line = errReader.readLine()) != null) {
}
} catch (IOException e) {
}
process.waitFor();
Redirecting sub-process's input streams
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectInput();
processBuilder.redirectError();
Process process = processBuilder.start();
process.waitFor();
(from comments)
Looks like process hang is due to out/error streams becoming full. You need to consume these streams; possibly via a thread.
Java7 provides another way to redirect output.
Related : http://alvinalexander.com/java/java-exec-processbuilder-process-3

Run a batch file with java program

try {
try {
String[] command = {"cmd.exe", "/C", "Start", "D:\\test.bat"};
Runtime r = Runtime.getRuntime();
Process p = r.exec(command);
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Error" +"Execution!","Error",JOptionPane.ERROR_MESSAGE);
}
} catch (IOException ex) {
Logger.getLogger(DBBackUp.class.getName()).log(Level.SEVERE, null, ex);
}
When I run this code, I got only command promt. .bat file is not running.
How can I execute the batch file using this code?
Thank in Advance
Consider
using Apache Commons Exec.
let your "test.bat" be like this:
dir
pause
then you can execute this batch file as follows:
try
{
Runtime r = Runtime.getRuntime();
Process p = r.exec("rundll32 url.dll,FileProtocolHandler " + "D:\\test.bat");
p.waitFor();
}catch(Exception ex){ex.printStackTrace();}
You can try something like this:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class BatchExecuteService {
public static void main(String[] args) {
BatchExecuteService batchExecuteService = new BatchExecuteService();
batchExecuteService.run();
}
public void run() {
try {
String cmds[] = {"D:\\test.bat"};
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(cmds);
process.getOutputStream().close();
InputStream inputStream = process.getInputStream();
InputStreamReader inputstreamreader = new InputStreamReader(inputStream);
BufferedReader bufferedrReader = new BufferedReader(inputstreamreader);
String strLine = "";
while ((strLine = bufferedrReader.readLine()) != null) {
System.out.println(strLine);
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}

Categories

Resources