I have this code which I want to test and get the max pit coverage but I am not able to kill the mutant for the negated condition if (close). I am also using mockito to throw some exception.
public static void copyBytes(InputStream in, OutputStream out, int buffSize, boolean close) throws IOException {
try {
copyBytes(in, out, buffSize);
if (close) {
out.close();
out = null;
in.close();
in = null;
}
} finally {
if (close) {
closeStream(out);
closeStream(in);
}
}
}
This is my case tests:
#Test
public void mockOutputCopyBytes1False(){
try{
OutputStream outputStream = Mockito.mock(OutputStream.class);
doThrow(new IOException()).when(outputStream).close();
copyBytes(createInputStream(), outputStream, 50, false);
outputStream.write(10);
}catch (Exception e){
e.printStackTrace();
Assert.assertEquals(IOException.class, e.getClass());
}
}
#Test
public void mockOutputCopyBytes1True(){
try{
OutputStream outputStream = Mockito.mock(OutputStream.class);
doThrow(new IOException()).when(outputStream).close();
copyBytes(createInputStream(), outputStream, 50, true);
outputStream.write(10);
}catch (Exception e){
e.printStackTrace();
Assert.assertEquals(IOException.class, e.getClass());
}
}
The finally clause is executed whether the code works or throws an exception, there is no need to code for both cases:
public static void copyBytes(InputStream in, OutputStream out, int buffSize, boolean close) throws IOException {
try {
copyBytes(in, out, buffSize);
// TODO - remove the following
//if (close) {
// out.close();
// out = null;
// in.close();
// in = null;
//}
} finally {
if (close) {
closeStream(out);
closeStream(in);
}
}
}
Related
Why in the readFile2() I need to catch the FileNotFoundException and later the IOException that is thrown by the close() method, and in the try-with-resources(inside readfile1) Java doesn't ask me to handle the FileNotFoundException, what happened?
public class TryWithResourcesTest {
public static void main(String[] args) {
}
public static void readFile1() {
try(Reader reader = new BufferedReader(new FileReader("text.txt"))) {
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readFile2() {
Reader reader = null;
try {
reader = new BufferedReader(new FileReader("text.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if(reader != null)
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
FileNotFoundException is a subclass of IOException. By catching the latter, you're catching the former too. It has nothing to do with try-catch vs. try-with-resources.
The code which I currently have as below used to write the response and recently i am getting java.io.IOException: Stream closed error frequently even though I closed the File Writer properly not sure why any body please help me on this.
Exception:
Caused by: java.io.IOException: Stream closed
at sun.nio.cs.StreamEncoder.ensureOpen(StreamEncoder.java:26)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:99)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at com.test.resp.RespWriter.write(RespWriter.java:150)
at com.ctc.wstx.sw.BufferingXmlWriter.flushBuffer(BufferingXmlWriter.java:1103)
at com.ctc.wstx.sw.BufferingXmlWriter.flush(BufferingXmlWriter.java:213)
at com.ctc.wstx.sw.BufferingXmlWriter.close(BufferingXmlWriter.java:194)
at com.ctc.wstx.sw.BaseStreamWriter.finishDocument(BaseStreamWriter.java:1690)
The place I am getting the exception at below place
fileWriter.write(buff, off, len); Here is the place I am getting Exception
public void write(char[] buff, int off, int len) throws IOException {
printWriter.write(buff, off, len);
if(count < FILE_SIZE) {
fileWriter.write(buff, off, len); Here is the place I am getting Exception
count+=len;
}
}
Code:
public RespWriter(RequestHeader header, PrintWriter printWriter)
throws InitializationException {
isClosed = false;
if(StringUtil.isEmpty(FILE_PATH) || printWriter == null) {
throw new InitializationException(
InitializationException.ERR_CODE);
} else {
this.header = header;
File responseFolder = new File(FILE_PATH.concat(
"/".concat(header.getUserId())));
boolean dirCreated = responseFolder.mkdir();
if(responseFolder.exists() && responseFolder.isDirectory()) {
responseFile = new File(responseFolder,
"R"+header.getId()+FILE_EXTENSION);
} else {
throw new InitializationException(
InitializationException.ERR_CODE,
"response folder does not exist");
}
this.printWriter = printWriter;
try {
fileWriter = new FileWriter(responseFile);
} catch (IOException e) {
log.error("FileWriter could not be created", e);
}
writeHeaderToFile();
}
}
private void writeHeaderToFile() {
String headerStr = "\nRequest Header:\nnull\n";
try {
if(header!=null) {
headerStr="\n"+Thread.currentThread().getName()
+" Request Header:\n" + header.toString() + "\n";
}
fileWriter.write(headerStr, 0, headerStr.length());
fileWriter.write("Date:");
fileWriter.write(new Date().toString()+"\n");
fileWriter.write("Response:\n"+Thread.currentThread().getName()+": ");
fileWriter.flush();
} catch (IOException e) {
log.error("IOException occurred writing header to file", e);
}
}
#Override
public void close() throws IOException {
if(!isClosed) {
try {
if(fileWriter!=null) {
try {
fileWriter.close();
} catch(IOException e) {
log.error("IOException", e);
}
}
if(printWriter!=null) {
try {
printWriter.close();
} catch(IOException e) {
log.error("IOException", e);
}
}
} finally {
isClosed = true;
}
}
}
public void flush() throws IOException {
if(printWriter!=null) {
try {
printWriter.flush();
} catch(IOException e) {
log.error("IOException", e);
}
}
if(fileWriter!=null) {
try {
fileWriter.flush();
} catch(IOException e) {
log.error("IOException", e);
}
}
}
Any thing i missed in the code or do I want to create new FileWriter instance in the Write method. Please help on this. Thanks in Advance
The stream is already closed when enters the write() method. I would suggest you println 3 different debug statements to spot the issue. 1 when you open/create the streamer, 2 when close it and 3 when you attempt to write to it, so you can see the order of operations. Also, have a look here: java IO Exception: Stream Closed
I wrote a SocketClient for connect to the socket, and add some callback in it.
public class SocketClientV2 {
public static void main(String[] args) {
SocketClientV2.Listener listener = new SocketClientV2.Listener() {
#Override
public void recv(byte[] result) {
// TODO Auto-generated method stub
System.out.println("====recv something");
}
#Override
public void connected() {
// TODO Auto-generated method stub
System.out.println("=====connected!");
}
#Override
public void disconnect() {
// TODO Auto-generated method stub
System.out.println("=====disconnect!");
}
};
SocketClientV2 client = new SocketClientV2("172.16.16.102", 4444,
10000, listener);
byte[] test = new byte[10];
test[0] = (byte) 0x1c;
test[1] = (byte) 0xff;
test[2] = (byte) 0x08;
client.send(test);
}
public interface Listener {
public void recv(byte[] result);
public void connected();
public void disconnect();
}
Socket client = null;
boolean isConnect = false;
OutputStream outputStream = null;
InputStream inputStream = null;
public SocketClientV2() {
}
Listener cb = null;
public SocketClientV2(String site, int port, int timeout, Listener cb) {
this.cb = cb;
try {
client = new Socket(site, port);
client.setSoTimeout(timeout);
System.out.println("Client is created! site:" + site + " port:"
+ port);
if (isConnected()) {
isConnect = true;
if (cb != null) {
cb.connected();
}
checkConnect();
listenRecv();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getClient() {
return this.client;
}
public void closeSocket() {
try {
isConnect = false;
inputStream.close();
outputStream.close();
client.close();
client = null;
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean isConnected() {
try {
client.sendUrgentData(0xff);
isConnect = true;
} catch (Exception e) {
System.out.println("return false....2");
isConnect = false;
e.printStackTrace();
return false;
}
return true;
}
private void checkConnect() {
new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("check connect....1");
try {
while (isConnected()) {
Thread.sleep(500);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
System.out.println("finally....3");
if (cb != null) {
cb.disconnect();
}
closeSocket();
}
}
}.start();
}
private void listenRecv() {
new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("listening Recv....");
try {
inputStream = client.getInputStream();
while (isConnect) {
byte[] result = readStream(inputStream);
if (cb != null) {
cb.recv(result);
}
Thread.sleep(500);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
public void send(final byte[] byteSend) {
new Thread() {
#Override
public void run() {
// TODO Auto-generated method stub
// System.out.println("sendMsg coming....");
if (isConnect) {
try {
outputStream = client.getOutputStream();
outputStream.write(byteSend);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
public byte[] readStream(InputStream inStream) throws Exception {
int count = 0;
while (count == 0) {
// System.out.println(0);
count = inStream.available();
// if(count!=0)
// System.out.println(count);
}
byte[] b = new byte[count];
inStream.read(b);
return b;
}
}
there is one thread checkConnect to check the connect status for the socket..
but it will disconnect after running few mins,
Client is created! site:172.16.16.102 port:4444
=====connected!
check connect....1
listening Recv....
====recv something
====recv something
====recv something
====recv something
====recv something
====recv something
====recv something
return false....2
java.io.IOException: Broken pipe
at java.net.PlainSocketImpl.socketSendUrgentData(Native Method)
at java.net.PlainSocketImpl.sendUrgentData(PlainSocketImpl.java:622)
at java.net.Socket.sendUrgentData(Socket.java:954)
at com.udpdemo.multicast.SocketClientV2.isConnected(SocketClientV2.java:100)
at com.udpdemo.multicast.SocketClientV2.access$0(SocketClientV2.java:98)
finally....3
=====disconnect!
at com.udpdemo.multicast.SocketClientV2$2.run(SocketClientV2.java:121)
java.io.IOException: Stream closed.
at java.net.PlainSocketImpl.available(PlainSocketImpl.java:483)
at java.net.SocketInputStream.available(SocketInputStream.java:217)
at com.udpdemo.multicast.SocketClientV2.readStream(SocketClientV2.java:205)
at com.udpdemo.multicast.SocketClientV2$3.run(SocketClientV2.java:154)
so what's problem with my sendUrgentData???
'Broken pipe' always means that you wrote to a connection which had already been closed by the peer. It's an application protocol error.
But unless the peer of this client isn't written in Java there is no point in using urgent data in the first place. Java can only receive urgent data 'in-line', i.e. after all the other pending data that had already been sent. And that only happens if the peer calls setOOBLine(true), otherwise
by default, this option is disabled and TCP urgent data received on a socket is silently discarded.
It's possible you're doing this to detect a broken connection. In this case, your dream came true, it worked, and all you have to do is adjust your catch and your code accordingly. But this is not in general a reliable technique.
Other notes:
isConnected() can never be false at the point you test it after creating the Socket, and it never magically becomes false afterwards. You need to revisit all the code that calls this method. Most of it doesn't make sense, or relies on false assumptions.
Your readStream() method spin-loops while available() returns zero. There is absolutely no point in this. You're just smoking the CPU. It's also completely at odds with your attempted use of a read timeout, which simply cannot possibly work while this loop is there. The following read() call will block until at least one byte of data arrives, or end of stream or an exception occurs. Your present code will never detect end of stream. You need to completely redesign this part of the code as well. It's poor practice to return a byte array for example.
That same piece of code completely ignores the count returned by read(). Never do that.
I'm trying to execute this command from the application emulator terminal (you can find it in google play) in this app i write su and press enter, so write:
screenrecord --time-limit 10 /sdcard/MyVideo.mp4
and press again enter and start the recording of the screen using the new function of android kitkat.
so, i try to execute the same code from java using this:
Process su = Runtime.getRuntime().exec("su");
Process execute = Runtime.getRuntime().exec("screenrecord --time-limit 10 /sdcard/MyVideo.mp4");
But don't work because the file is not created. obviously i'm running on a rooted device with android kitkat installed. where is the problem? how can i solve? because from terminal emulator works and in Java not?
You should grab the standard input of the su process just launched and write down the command there, otherwise you are running the commands with the current UID.
Try something like this:
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
}catch(IOException e){
throw new Exception(e);
}catch(InterruptedException e){
throw new Exception(e);
}
A modification of the code by #CarloCannas:
public static void sudo(String...strings) {
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
for (String s : strings) {
outputStream.writeBytes(s+"\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
outputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
(You are welcome to find a better place for outputStream.close())
Usage example:
private static void suMkdirs(String path) {
if (!new File(path).isDirectory()) {
sudo("mkdir -p "+path);
}
}
Update:
To get the result (the output to stdout), use:
public static String sudoForResult(String...strings) {
String res = "";
DataOutputStream outputStream = null;
InputStream response = null;
try{
Process su = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(su.getOutputStream());
response = su.getInputStream();
for (String s : strings) {
outputStream.writeBytes(s+"\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
res = readFully(response);
} catch (IOException e){
e.printStackTrace();
} finally {
Closer.closeSilently(outputStream, response);
}
return res;
}
public static String readFully(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString("UTF-8");
}
The utility to silently close a number of Closeables (Soсket may be no Closeable) is:
public class Closer {
// closeAll()
public static void closeSilently(Object... xs) {
// Note: on Android API levels prior to 19 Socket does not implement Closeable
for (Object x : xs) {
if (x != null) {
try {
Log.d("closing: "+x);
if (x instanceof Closeable) {
((Closeable)x).close();
} else if (x instanceof Socket) {
((Socket)x).close();
} else if (x instanceof DatagramSocket) {
((DatagramSocket)x).close();
} else {
Log.d("cannot close: "+x);
throw new RuntimeException("cannot close "+x);
}
} catch (Throwable e) {
Log.x(e);
}
}
}
}
}
Process p;
StringBuffer output = new StringBuffer();
try {
p = Runtime.getRuntime().exec(params[0]);
BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
p.waitFor();
}
}
catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
String response = output.toString();
return response;
Late reply, but it will benefit someone. You can use the sh command in the exec() method.
Here is my example:
try {
File workingDirectory = new File(getApplicationContext().getFilesDir().getPath());
Process shProcess = Runtime.getRuntime().exec("sh", null, workingDirectory);
try{
PrintWriter outputExec = new PrintWriter(new OutputStreamWriter(shProcess.getOutputStream()));
outputExec.println("PATH=$PATH:/data/data/com.bokili.server.nginx/files;export LD_LIBRARY_PATH=/data/data/com.bokili.server.nginx/files;nginx;exit;");
outputExec.flush();
} catch(Exception ignored){ }
shProcess.waitFor();
} catch (IOException ignored) {
} catch (InterruptedException e) {
try{ Thread.currentThread().interrupt(); }catch(Exception ignored){}
} catch (Exception ignored) { }
What have I done with this?
First I call the shell, then I change (set) the necessary environments in it, and finally I start my nginx with it.
This works on unrooted devices too.
Greetings.
I'm trying to enter some value in external application using Java.
Java application looks like this:
Runtime runtime = Runtime.getRuntime();
// ... str build ...
proc = runtime.exec(str);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
bw.write(value);
bw.flush();
bw.close();
if (proc.waitFor() != 0)
// error msg
// the end
Application hangs at waitFor method.
External application looks like this:
welcome banner
please enter 8 character input:
Welcome banner is printed using printf and input is taken with SetConsoleMode/ReadConsoleInput. ReadConsoleInput reads one char and they are masked with * character.
Help
you can use:
proc.getOutputStream().write("some date".getBytes())
keep in mind that you HAVE to read everything the app send to stdout and stderr, else it might get stuck writing there.
I use a generic class to read it in a different thread.
usage is like:
InputStreamSucker inSucker = new InputStreamSucker(proc.getInputStream());
InputStreamSucker errSucker = new InputStreamSucker(proc.getErrorStream());
proc.waitFor();
int exit = process.exitValue();
inSucker.join();
errSucker.join();
InputStreamSucker code is here:
public class InputStreamSucker extends Thread
{
static Logger logger = Logger.getLogger(InputStreamSucker.class);
private final BufferedInputStream m_in;
private final ByteArrayOutputStream m_out;
private final File m_outFile;
public InputStreamSucker(InputStream in) throws FileNotFoundException
{
this(in, null);
}
public InputStreamSucker(InputStream in, File outFile) throws FileNotFoundException
{
m_in = new BufferedInputStream(in, 4096);
m_outFile = outFile;
m_out = new ByteArrayOutputStream();
start();
}
#Override
public void run()
{
try
{
int c;
while ((c = m_in.read()) != -1)
{
m_out.write(c);
}
}
catch (IOException e)
{
logger.error("Error pumping stream", e);
}
finally
{
if (m_in != null)
{
try
{
m_in.close();
}
catch (IOException e)
{
}
}
try
{
m_out.close();
}
catch (IOException e)
{
logger.error("Error closing out stream", e);
}
if (m_outFile != null)
{
byte data[] = m_out.toByteArray();
if (data.length > 0)
{
FileOutputStream fo = null;
try
{
fo = new FileOutputStream(m_outFile);
fo.write(data);
}
catch (IOException e)
{
logger.error("Error writing " + m_outFile);
}
finally
{
try
{
if (fo != null) fo.close();
}
catch (IOException e)
{
logger.error("Error closing " + m_outFile);
}
}
}
}
}
}
public String getOutput()
{
return new String(m_out.toByteArray());
}
}
Got the answer! The trick is to use WriteConsoleInput() API because program expects keyboard event, not text ... That's why the waitFor() waited forever! :)