How to handle throw exceptions inside finally block in java - java

In java, it is not recommended to throw exceptions inside finally section in try-chatch block due to hide the propagation of any unhandled throwable which was thrown in the try or catch block. This practice is a blocker level violation according to default sonar profile.
Sonar Error: Remove this throw statement from this finally block.
Please consider the following code snippet.
e.g.: close input stream inside the finally block, and handle possible exceptions might be occurred when closing the stream.
public void upload(File file) {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream());
try {
String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName());
c.put(bis, uploadLocation);
} catch (SftpException e) {
throw new IllegalTargetException("Error occurred while uploading " + e.getMessage());
} finally {
try {
bis.close();
} catch (IOException e) {
throw new UnsupportedOperationException("Exception occurred while closing Input stream " + e.getMessage());
}
}
}
It would be grateful if you can show the conventional way of handling these situations.

Best way to handle this problem is to use try-with-resource. But if someone want to close the connection manually and show the exception of the try or catch block without hiding, following code snippet is the solution.
public void upload(File file) throws IOException {
ChannelSftp c = (ChannelSftp) channel;
BufferedInputStream bis = new BufferedInputStream(file.toInputStream());
SftpException sftpException = null;
try {
String uploadLocation = Files.simplifyPath(this.fileLocation + "/" + file.getName());
c.put(bis, uploadLocation);
} catch (SftpException e) {
sftpException = e;
throw new IllegalTargetException("Error occurred while uploading " + e.getMessage());
} finally {
if (sftpException != null) {
try {
bis.close();
} catch (Throwable t) {
sftpException.addSuppressed(t);
}
} else {
bis.close();
}
}
}

Related

Trying to Continue the program when it returns file not found exception in java

I i am able to read the lines from csv and download the images from url when the url is not having the image it is showing file not found exception in middle of the program i want to continue the program with out terminating.
public static void main(String[] args) throws IOException {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
BufferedReader br = new BufferedReader(new FileReader("D:\\imgdwnld\\file.csv"));
String line = br.readLine();
while ((line = br.readLine()) !=null){
URL url = new URL(line);
inputStream = url.openStream();
outputStream = new FileOutputStream("D:\\imgdwnld\\" +
line.substring(line.lastIndexOf("/")));
byte[] buffer = new byte[2048];
int length;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
}
} catch (MalformedURLException e) {
System.out.println("MalformedURLException :- " + e.getMessage());
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException :- " + e.getMessage());
} catch (IOException e) {
System.out.println("IOException :- " + e.getMessage());
} finally {
try {
inputStream.close();
outputStream.close();
} catch (IOException e) {
System.out.println("Finally IOException :- " + e.getMessage());
}
}
}
This is the relevant outline of your code:
try {
...
while ((line = br.readLine()) !=null) {
... process each CSV line ...
}
} catch (IOException e) {
... handle it ...
}
At the place where you catch the exception you have already broken out of the main loop. Change the code to have this outline:
while ((line = br.readLine()) !=null) {
try {
... process one CSV line ...
} catch (IOException e) {
... handle it, the loop will proceed with the next line
}
}
You need to remove the "return" instruction from the corresponding catch (or maybe from the whole code). In your case, the instruction allows to "exit" the main method so the rest of instruction (those after the return statement) won't be executed.
Another tip is to separate this instructions in blocs. For example, if reading the CSV and the Img are not bound, you may need to encapsulate each treatment in an individual try-catch block. When parsing/reading the CSV file fails, your code may continue fetching the image.

How to lock Files to avoid deletion using NIO package

I am using NIO File Channel to manage files, and locking them. So far it works, however when I lock a File using NIO File Lock it locks the file so the file Content cannot be changed. As for example if I try to edit a text file on notepad it will show me the following error message:
And that is the expected result, however if I try to delete the file from windows explorer(I haven't tested on other OS likely will be possible as well) it will allow me, and this is undesired, I would like to know if it is possible to Open a File Handle
Code Used:
private static final byte[] MessageBytes;
static {
byte tmp[];
try {
tmp = "Hello World".getBytes("UTF-8");
} catch (UnsupportedEncodingException ex) {
//if fail get the bytes in whatever the java VM charset sets as default
tmp = "Hello World".getBytes();
}
MessageBytes = tmp;
}
private static final String Filename = "Lock_test.txt";
private static void createFileandLock() {
Path FilePath = Paths.get(Filename);
FileChannel OpenFCh;
try {
OpenFCh = FileChannel.open(FilePath, StandardOpenOption.CREATE,
StandardOpenOption.READ, StandardOpenOption.WRITE
// ,StandardOpenOption.APPEND
);
System.out.println("File Channel is Open.");
} catch (IOException err) {
OpenFCh = null;
}
if (OpenFCh != null) {
FileLock Lock = null;
try {
Lock = OpenFCh.lock();
} catch (IOException err) {
System.out.println("Unable To Lock the File.");
}
try {
OpenFCh.write(ByteBuffer.wrap(MessageBytes));
OpenFCh.force(false);
System.out.println("Message Recorded");
} catch (IOException ex) {
System.out.println("Unable To write data into file");
}
try {
// at this point file still locked and open.
//lets wait for input and meanwhile ask to delete the file.
System.out.print("Please Try to delete file at: ");
System.out.println(FilePath.toString());
System.out.println("Press Enter to Continue");
System.in.read();
} catch (IOException ex) {
}
if (Lock != null) {
try {
Lock.close();
} catch (IOException ex) {
}
}
try {
OpenFCh.close();
} catch (IOException ex) {
}
}
}
After further research I notice that using RandomAccessFile Will lock the file avoiding deletion as it creates a File Descriptor that basically open a Handle on the underline Operative system.
So using the RAF does provide the desired result:
Code Used:
private static void createRAFileandLock() {
RandomAccessFile RAf;
try {
RAf = new RandomAccessFile(Filename, "rw");
} catch (FileNotFoundException ex) {
//since is open as RW shold not trigger.
RAf = null;
}
if (RAf != null) {
FileChannel OpenFCh = RAf.getChannel();
FileLock Lock = null;
try {
Lock = OpenFCh.lock();
} catch (IOException err) {
System.out.println("Unable To Lock the File.");
}
try {
OpenFCh.write(ByteBuffer.wrap(MessageBytes));
OpenFCh.force(false);
System.out.println("Message Recorded");
} catch (IOException ex) {
System.out.println("Unable To write data into file");
}
// at this point file still locked and open.
//lets wait for input and meanwhile ask to delete the file.
try {
System.out.print("Please Try to delete file at: ");
System.out.println(Filename);
System.out.println("Press Enter to Continue");
System.in.read();
} catch (IOException ex) {
}
if (Lock != null) {
try {
Lock.close();
} catch (IOException ex) {
}
}
try {
OpenFCh.close();
RAf.close();
} catch (IOException ex) {
}
}
}
However I would like to know if it is possible to archive this using only NIO. As Random Access File is on IO package.
FileLock isn't specified to prevent deletion. It's only specified to interact with other file locks, so you're already deep into platform-dependent behaviour. If RandomAccessFile somehow does what you want you may be stuck with it, but you can't rely on it.
NB of course FileChannel.open() uses a FileDescriptor, handle, etc.

Multiple tests with multiple throws

I would like to create a method that will test different things and throw an error depending on the issue (and then exit the program).
I am not really familiar with throwing exception... Is this method a good way to program it?
private static void testConnexions() throws IOException, Exception {
File file = null;
Socket socket;
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new SecurityException();
if (!file.canWrite())
throw new SecurityException();
if (!file.exists())
throw new SecurityException();
if (!file.isDirectory())
throw new SecurityException();
// Connection to  Filenet:
connexion = new FilenetConnexion(filenetURI, objectStoreName,
stanza, dossierRacine, userName, password);
connexion.connect();
// Connection to a socket:
socket = new Socket(serveurCV, portCV);
// Initialize the JavaMail Session:
Properties props = System.getProperties();
if (serveurSMTP != null)
props.put("mail.smtp.host", serveurSMTP);
Session session = Session.getInstance(props, null);
} catch (SecurityException e) {
e.getMessage();
e.printStackTrace();
} catch (UnknownHostException e) {
e.getMessage();
e.printStackTrace();
} catch (IOException e) {
e.getMessage();
e.printStackTrace();
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
}
}
I would like to catch a message detailed enough to know if the repository can't be written in, or if the System.getProperties() got an error, etc.
Thank you in advance for your help!
EDIT:
Here is the solution I chose among all your contributions, hoping it can help someone:
private static void testConnexions() {
File file = null;
Socket socket;
// Test access to the repository:
try {
file = new File(pdfRepository);
if (!file.canRead())
throw new SecurityException(pdfRepository + " can't be read.");
if (!file.canWrite())
throw new SecurityException(pdfRepository + " can't be written.");
if (!file.exists())
throw new SecurityException(pdfRepository + " doesn't exist.");
if (!file.isDirectory())
throw new SecurityException(pdfRepository + " isn't a folder.");
} catch (SecurityException e) {
logger.error(e.getMessage());
System.exit(1);
}
// Connection to  FileNet
try {
connexion = new FilenetConnexion(filenetURI, objectStoreName,
stanza, dossierRacine, userName, password);
connexion.connect();
} catch (Exception e) {
logger.error("Impossible to connect to FileNet. " + e.getMessage());
System.exit(2);
}
// Connection to FrontalSocket
try {
socket = new Socket(serveurCV, portCV);
} catch (UnknownHostException e) {
logger.error("Impossible to connect to FrontalSocket. " + e.getMessage());
System.exit(3);
} catch (IOException e) {
logger.error("Impossible to connect to FrontalSocket. " + e.getMessage());
System.exit(3);
}
// Initialize the JavaMail session
try {
Properties props = System.getProperties();
if (serveurSMTP != null)
props.put("mail.smtp.host", serveurSMTP);
else{
logger.error("The SMTP host name is null");
System.exit(4);
}
Session session = Session.getInstance(props, null);
} catch (Exception e) {
logger.error("Impossible to connect to SMTP server. " + e.getMessage());
System.exit(4);
}
}
You can do this several ways, choose which one fits your scenario best:
Throw different exceptions based on each error scenario. It is easy to subclass Exception and create the distinction this way.
Throw the same exception with a specific error message depending on the error scenario.
An example of case 1:
First define your own exceptions:
public class CannotReadException extends Exception {
// This is a separate class in your project
}
public class CannotWriteException extends Exception {
// This is a separate class in your project
}
Then throw and catch them:
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new CannotReadException();
if (!file.canWrite())
throw new CannotWriteException();
...
} catch (CannotReadException e) {
// Do stuff for the specific error
} catch (CannotWriteException e) {
// Do stuff for the specific error
}
or, case 2:
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new SecurityException( "cannot read" );
if (!file.canWrite())
throw new SecurityException( "cannot write" );
...
} catch (SecurityException e) {
// Get to your specific message using e.getMessage();
}
I can suggest in this case to throw a user define exception and pass a message detailed enough to know the responsible for that error.
public class MyException extends Exception {
//override the needed methods.
}
then throw you own defined exception with a detaied message.
try {
// Test access to the repository:
file = new File(pdfRepository);
if (!file.canRead())
throw new MyException("The fine has no read permission");

closing FileInputStream object throws exception

When I want to close InputFileStream and OutputFileStream objects, eclipse says that I need to catch IOException so here is my code after catching those exceptions.
As you can see I am catching IOException twice. Is there a more simple way that I can have only one block for catching IOException for both in.close() and in.read() ?
public class ByteStream {
public static void main(String[] args) {
FileInputStream in = null;
try {
in = new FileInputStream("testdata.txt");
int nextByte;
while((nextByte = in.read()) != -1){
System.out.println(nextByte + "-");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (in != null){
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Use the try-with-resources syntax in Java 7
try (FileInputStream in = new FileInputStream("testdata.txt");){
int nextByte;
while ((nextByte = in.read()) != -1) {
System.out.println(nextByte + "-");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
the compiler will take care of converting the above code to code that closes the in InputStream, or any other AutoCloseable object declared and instatiated in the () part of the try expression.

Get EOFException while reading serialized object in Java

I have two methods, one that serialize the Object, and it works ok:
public void record()throws RecordingException
{
ObjectOutputStream outputStream = null;
try
{
outputStream = new ObjectOutputStream(new FileOutputStream("src/data/employee.dat"));
outputStream.writeObject(this);
} catch (FileNotFoundException ex)
{
ex.printStackTrace();
throw new RecordingException(ex);
} catch (IOException ex)
{
ex.printStackTrace();
throw new RecordingException(ex);
}finally
{
try
{
if (outputStream != null) outputStream.close();
} catch (IOException ex){}
}
}
The problem here when deserializing the object, I get EOFException!:
public final User loadObject(UserType usertype) throws InvalidLoadObjectException
{
ObjectInputStream istream = null;
String path = null;
if (usertype == UserType.EMPLOYEE)
{
path = "data/employee.dat";
}else if (usertype == UserType.CUSTOMER)
{
path = "data/customer.dat";
}else
throw new InvalidLoadObjectException("Object is not a sub class of User");
try
{
istream = new ObjectInputStream(ObjectLoader.class.getClassLoader().getResourceAsStream(path));
User u = loadObject(istream);
istream.close();
return u;
}catch (EOFException ex)
{
System.out.println(ex.getMessage());
return null;
}catch(Exception ex)
{
ex.printStackTrace();
throw new InvalidLoadObjectException(ex);
}
}
private User loadObject(ObjectInputStream stream) throws InvalidLoadObjectException
{
try
{
return (User) stream.readObject();
} catch (IOException ex)
{
ex.printStackTrace();
throw new InvalidLoadObjectException(ex);
} catch (ClassNotFoundException ex)
{
ex.printStackTrace();
throw new InvalidLoadObjectException(ex);
}
}
I don't know if this is the cause of your problem, but the code that writes the file has a subtle flaw. In the finally block, you close the stream and ignore any exceptions. If the close() method performs a final flush(), then any exceptions thrown in the flush will go unreported.
Try outputStream.flush() before closing your stream in serialization object.
The file was empty, or didn't contain the full serialization of the object.

Categories

Resources