I have a piece of code with try-catch block:
public static void writeExcelToFile(String outFileName, HSSFWorkbook workBook) throws IOException{
File file = null;
FileOutputStream fileOutputStream = null;
try {
file = getFileByFileName(outFileName);
File parent = file.getParentFile();
Path filePath = parent.toPath();
if (Files.notExists(filePath) && !parent.mkdirs()) {
throw new IOException("Couldn't create dir: " + parent);
}
fileOutputStream = new FileOutputStream(file);
workBook.write(fileOutputStream);
} catch (FileNotFoundException fileNotFoundException) {
LOGGER.error("File path is invalid, file not found ", fileNotFoundException);
throw fileNotFoundException;
} catch (IOException ioException) {
LOGGER.error("Exception occured while reading writing file ", ioException);
throw ioException;
} catch (Exception exception) {
LOGGER.error("Exception occured ", exception);
throw exception;
} finally {
if (fileOutputStream != null) {
fileOutputStream.close();
}
}
file.setWritable(true);
}
I have written the following Junit for the catch block:
//#1: FileNotFoundException
#Test(expected = java.io.FileNotFoundException.class)
public void testWriteExcelToFileException() throws IOException {
PowerMockito.mockStatic(KnewtonCIExcelWriter.class);
PowerMockito.doThrow(new java.io.FileNotFoundException()).when(KnewtonCIExcelWriter.class);
KnewtonCIExcelWriter.writeExcelToFile(anyString(), anyObject());
}
//#2: IOException
#Test(expected = IOException.class)
public void testWriteExcelIOException() throws IOException {
PowerMockito.mockStatic(KnewtonCIExcelWriter.class);
PowerMockito.doThrow(new IOException()).when(KnewtonCIExcelWriter.class);
KnewtonCIExcelWriter.writeExcelToFile(anyString(), anyObject());
}
//#3: Exception
#Test(expected = Exception.class)
public void testWriteExcelException() throws IOException {
PowerMockito.mockStatic(KnewtonCIExcelWriter.class);
PowerMockito.doThrow(new Exception()).when(KnewtonCIExcelWriter.class);
KnewtonCIExcelWriter.writeExcelToFile(anyString(), anyObject());
}
However, only the last, #3 Junit passes. #1 and #2 gives java.lang.AssertionError: Expected exception: java.io.FileNotFoundException and java.lang.AssertionError: Expected exception: java.io.IOEXception.
Question: 1) How to get the #1 and #2 JUnit passing? 2) Am I catching the
correct exceptions?
powermockito syntax on doThrow when should be
when(KnewtonCIExcelWriter.class, "your method", argument (you can user matcher));
Related
I am trying a JUNIT class, which uses calls an interface in which a method 'generateexcelreport' , builds an excel reprot based on a list of values.But when I used mockito to mock the implementation, I am getting an exception with creating a file, no w I tried using the Mockito.doNothing() on this method , but still Mockito calls the method and am getting the exception again.
Exception:
java.lang.NullPointerException: Cannot invoke "java.io.File.mkdir()" because the return value of "java.io.File.getParentFile()" is null
My Method:
public void generateExcelReport(HashMap<String, List<Object>> hydrated) throws IOException, InvalidFormatException{
Workbook workbook = new XSSFWorkbook();
hydrated.entrySet().stream().forEach(key -> {
List<Object> bodyNode = (List<Object>) key.getValue().get(0);
Sheet sheet = workbook.createSheet(key.getKey().toString());
try {
buildExcel(bodyNode,workbook,sheet);
} catch (IOException | InvalidFormatException e) {
e.printStackTrace();
}
});
try {
File report= new File(fileName);
FileOutputStream fileOut = null;
if (hydrationReport.getParentFile().mkdir()) {
fileOut = new FileOutputStream(hydrationReport);
workbook.write(fileOut);
}else if(Files.exists(Path.of(hydrationReport.getParent()))){
fileOut = new FileOutputStream(hydrationReport);
workbook.write(fileOut);
}else {
throw new IOException("Failed to create directory " + hydrationReport.getParent());
}
fileOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
And this is myy mock class, I am stuck creating it, Could someone please help
public class ExecutorImplTest {
#InjectMocks
ExecutorImpl impl;
#Test
public void vlaidateHydrationTest() throws TimeoutException, IOException, InvalidFormatException {
///when
HashMap<String, List<Object>> map = impl.validateHydration(request);
}
}
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
This question already has answers here:
Closing a Java FileInputStream
(9 answers)
Closed 5 years ago.
I'm trying to become familiar with file I/O in Java. I started off by getting a lot of errors when compiling, such as error: unreported exception IOException; must be caught or declared to be thrown. So I made some changes to the code and ended up with:
public static void main(String[] args){
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(IOException e){
}catch(FileNotFoundException e){
}
finally{
if (out != null)
out.close();
}
}
Still, I get this error:
FileIO.java:16: error: exception FileNotFoundException has already been caught
}catch(FileNotFoundException e){
^
FileIO.java:21: error: unreported exception IOException; must be caught or declared to be thrown
out.close();
^
2 errors
Where did I "already catch" FileNotFoundException?
Because of the second error, do I need to put another try and catch statement in the finally clause to catch IOException? That seems messy and over-complicated. Am I doing something else wrong? And why doesn't java let me do what I want without forcing me to catch exceptions?
EDIT:
If I do:
public static void main(String[] args){
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(FileNotFoundException e){
}catch(IOException e){
}
finally{
if (out != null)
out.close();
}
}
I get:
FileIO.java:20: error: unreported exception IOException; must be caught or declared to be thrown
out.close();
^
1 error
Where did I "already catch" FileNotFoundException?
FileNotFoundException extends IOException, which means IOException can catch FileNotFoundException exception. So, there is no point of FileNotFoundException after it.
Just reverse the order, to resolve this issue.
}catch(FileNotFoundException e){
}catch(IOException e){
}
Also, don't leave catch block blank, use them to display appropriate message, else you won't have any clue, if you got any exception.
second error, do I need to put another try and catch statement in the finally clause to catch IOException?
Yes. But, I would suggest to use try-with-resource it will take care of closing resource at the end.
As said, you should use try-with-resource instead
try (FileOutputStream out = new FileOutputStream("people.bin");)
{
out.write(contentBytes);
}
catch(FileNotFoundException e)
{
}catch(IOException e){
}
I am not really sure how the compiler let you the code. Could you please try the below code. I dont have any error when i run it.
Answer to the first question is :
Either remove FileNotFoundException line or put it above IOexception.
Answer to the second question is :
if you think that is messy, you can just duck the exception by using Throws i.e. throws IOException next to main(String[] args).
Java(compiler) pushes you to catch or declare your exceptions(using throws) because, the main purpose of Exceptions in java is not running into errors when the code is run. When an exception happens in the finally block, it leads to error and it ultimately impacts your application at run time. Have to very careful when you are closing stuff in Finally block. If you think, the code looks messy, then you can use Throws key word which solves your concern.
public static void main(String[] args){
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(IOException e){
}
finally{
if (out != null){
try{
out.close();
}catch(IOException e){
}
}
}
}
String outputPath = "output.txt";
String content = "hello";
byte[] contentBytes = content.getBytes();
try (FileOutputStream out = new FileOutputStream(outputPath)) {
out.write(contentBytes);
} catch (FileNotFoundException e) {
System.err.println("Failed to find the file to write to: " + outputPath);
} catch (IOException e) {
System.err.println("Failed to write to file: " + outputPath);
}
As QuakeCore mentioned FileNotFoundEception extends IOException, this is why you should catch FileNotFoundEception first.
It is a good practice to print at least some message, so you will not be surprised when there is no output and no exceptions in console / logs.
FileOutputStream implements AutoClosable interface. This why it is better to use try with resources. In this case JVM will close it automatically.
public static void main(String[] args) throws IOException{
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}catch(FileNotFoundException e){
}
finally{
if (out != null)
out.close();
}
}
Since FileNotFoundException extends IOException, then just by catching IOException you are catching all subtypes of IOException.
And regarding your second question, since `.close()` method also throws `IOException`, you can put all the IO code in a method, and have that method to throw `IOException`, then the caller can deal with the any exceptions.
for example:
private static void writeToFile() throws IOException{
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
out = new FileOutputStream("output.txt");
out.write(contentBytes);
}finally{
if (out != null)
out.close();
}
}
and then your main would look like this.
public static void main(String[] args){
FileInputStream in = null;
FileOutputStream out = null;
String content = "hello";
byte[] contentBytes = content.getBytes();
try{
writeToFile();
}catch(IOException e){
}
}
And have a look at tryResourceClose
public class DriverClass implements Serializable {
CafeManager cafe = new CafeManager(); - Creates the object
public static void main(String args[]) throws FileNotFoundException, IOException, ClassNotFoundException{
CafeManager newcafe;
newcafe = load(); - Calls the load module
SystemMenu menu = new SystemMenu();
menu.displaymenu(); - Running of the menu
newcafe = new CafeManager(newcafe.getMenuItems(),newcafe.getOrders()); - Once the user exits the menu, file should be saved
save(newcafe);
}
public static void save(CafeManager newcafe) throws FileNotFoundException, IOException{
try{
FileOutputStream fileOut = new FileOutputStream("system.dat");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(newcafe);
}
catch (FileNotFoundException fe){
System.out.println("File Not found.");
}
catch (IOException ie){
System.out.println("File Crappy" + ie.getMessage()); //Output: File Crappycafesys.Order
}
}
public static CafeManager load() throws FileNotFoundException, IOException, ClassNotFoundException{
CafeManager curcafe = new CafeManager();
FileInputStream fileIn = new FileInputStream("system.dat");
ObjectInputStream in = new ObjectInputStream(fileIn);
try{
curcafe = (CafeManager) in.readObject();
}
catch(ClassCastException | ClassNotFoundException ce){
//
}
catch (FileNotFoundException fe){
System.out.println("File Not found.");
}
catch (IOException ie){
System.out.println("File Crappy" + ie.getMessage()); //Output: File Crappy writing aborted; java.io.NotSerializableException: cafesys.Order
}
return curcafe;
}
I'm not sure why IOException is caught. As I have created the file and run it through the ObjectOutputStream. The exception message is:
java.io.NotSerializableException: cafesys.Order
I am trying to copy files using BufferedInputStream, and this error occurred when compile:
BufferedByteStreamCopy2.java:22: error: unreported exception IOException; must be caught or declared to be thrown
bin.close();
^
BufferedByteStreamCopy2.java:24: error: unreported exception IOException; must be caught or declared to be thrown
bout.close();
^
Could you help me to explain this? How can I modify the code? Many thanks!
import java.io.*;
public class BufferedByteStreamCopy2 {
public static void main(String[] args) {
BufferedInputStream bin = null;
BufferedOutputStream bout = null;
try {
FileInputStream fin = new FileInputStream(args[0]);
bin = new BufferedInputStream(fin);
FileOutputStream fout = new FileOutputStream(args[1]);
bout = new BufferedOutputStream(fout);
int c;
while ((c = bin.read()) != -1)
bout.write(c);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Not enough parameter.");
} catch (FileNotFoundException e) {
System.out.println("Could not open the file:" + args[0]);
} catch (Exception e) {
System.out.println("ERROR copying file");
} finally {
if (bin != null)
bin.close();
if (bout != null)
bout.close();
}
}
}
try/catch will catch an Exception but this doesn't apply to an exception thrown in a finally block. You need a try catch for the close() in there as well.
Note: copying a byte at a time is pretty inefficient, I assume this is just an exercise. As #EJP point out there is more read() and write() methods.