I have catch block, i want to execute the catch block. My Class file is,
public class TranscoderBean implements TranscoderLocal {
public byte[] encode(final Collection<?> entitySet) throws TranscoderException {
Validate.notNull(entitySet, "The entitySet can not be null.");
LOGGER.info("Encoding entities.");
LOGGER.debug("entities '{}'.", entitySet);
// Encode the Collection
MappedEncoderStream encoderStream = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
// Create the encoder and write the the DSE Logbook messgae
encoderStream = new MappedEncoderStream(outputStream, this.encoderVersion);
encoderStream.writeObjects(new ArrayList<Object>(entitySet), false);
encoderStream.flush();
}
catch (Exception e) {
LOGGER.error("Exception while encoding entities", e);
throw new TranscoderException("Failed to encode entities", e);
}
finally {
if (encoderStream != null) {
try {
encoderStream.close();
}
catch (IOException e) {
LOGGER.error("Exception while closing the endcoder stream.", e);
throw new TranscoderException("Failed to close encoder stream", e);
}
}
}
}
My Test Class file is,
public class TranscoderBeanTest {
private TranscoderBean fixture;
#Mock
MappedEncoderStream mappedEncoderStream;
#Test
public void encodeTest() throws TranscoderException {
List<Object> entitySet = new ArrayList<Object>();
FlightLog log1 = new FlightLog();
log1.setId("F5678");
log1.setAssetId("22");
FlightLog log2 = new FlightLog();
log2.setId("F5679");
log2.setAssetId("23");
entitySet.add(log1);
entitySet.add(log2);
MockitoAnnotations.initMocks(this);
try {
Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();
Mockito.doReturn(new IOException()).when(this.mappedEncoderStream).close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] encode = this.fixture.encode(entitySet);
Assert.assertNotNull(encode);
}
}
I have tried, Mockito.doThrow and Mockito.doReturn methods but still the catch block is not executed. What am doing wrong.
To test a try-catch block, you can use a TestNG way which consists in implementing a test method with the following annotation expectedExceptions.
The code of this method, you have to implement it in order to provoke this exception, so the catch block will be executed.
You can have a look at http://testng.org/doc/documentation-main.html#annotations
Are you sure you have the right test class. I do not see any reference to TranscoderBean in your
You expect Mockito to do things that it does not claim to do:
Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();
This statement asserts that whenever someone calls close() on the mapperEncoderStream-Object will receive an IOException. You never call close.
Try to add mapperEncoderStream.close(); after your Mockito-actions and the catch block will be entered - but note: this won't help you with your problem, since mockito cannot help here.
For your problem you can consider following alternative:
rewrite
encoderStream = new MappedEncoderStream(outputStream, this.encoderVersion);
to
encoderStream = createMappedEncoderStream(outputStream);
MappedEncoderStream createMappedEncoderStream(ByteArrayOutputStream outputStream) {
return new MappedEncoderStream(outputStream, this.encoderVersion);
}
this lets you inject the mock as dependency.
Then init your fixure like this:
fixture = new TranscoderBean() {
MappedEncoderStream createMappedEncoderStream(ByteArrayOutputStream outputStream) {
return mappedEncoderStream; //this is your mock
}
}
This injects the mock into your TranscoderBean.encode method.
Then change your mock Annotation:
#Mock(answer=CALLS_REAL_METHODS)
MappedEncoderStream mappedEncoderStream;
This is needed, because your encode method does not only call close on mappedEncoderStream, but also writeObjects and flush. These calls may throw exceptions so they have to be mocked or replaced by calls to the real object.
prune your test like that
#Test(expected=TranscoderException.class)
public void encodeTest() throws TranscoderException {
//... same as above
MockitoAnnotations.initMocks(this);
Mockito.doThrow(new IOException()).when(this.mappedEncoderStream).close();
this.fixture.encode(entitySet); //this will throw an exception
}
This does the following:
the encode method does not return null! It throws a TranscoderException, so it is placed as expected
override the close method with exception throwing
call encode
Related
Is it any possible way there to write catch block inside a method and call it from finally when an exception occured in try block
Ex:
try
{
int a=0,b=0;
a=b/0;
}
finally
{
callExceptions();
}
}
public static void callExceptions()
{
catch(Exception e)
{
System.out.println(e);
}
}
catch block must follow a try block. It can't stand alone.
And finally block are made to be after the catch.
You wrote an alone catch inside a finally. That doesn't make sense.
The easiest solution is to pass the exception to the method as a parameter:
public static myMethod() {
try
{
int a=0,b=0;
a=b/0;
}
catch (Exception e)
{
callExceptions(e);
}
finally
{
// do what ever you want or remove this block
}
}
public static void callExceptions(Exception e)
{
System.out.println(e);
}
Ways to uses try/catch/finally
1.- when you want to try to use some method, if everything goes well, will continue else one exception will be thrown on catch block.
try {
// some method or logic that might throw some exception.
} catch (ExceptionType name) {
// catch the exception that was thrown.
}
2.- It's the same the first but adding finally block means that the finally block will always be executed independently if some unexpected exception occurs.
try {
// some method or logic that might throw some exception.
} catch (ExceptionType name) {
// catch the exception that was thrown.
} finally {
// some logic after try or catch blocks.
}
3.- try and finally blocks are used to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. For example:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
Referencias Official documentation JAVA for try/catch/finally blocks
On your case:
public static myMethod() {
try {
int a=0,b=0;
a=b/0;
} catch (Exception e) {
callException(e);
}
}
public static void callException(Exception e) {
System.out.println(e);
}
This was too long for a comment so sorry it's not a direct answer to your question (as others have pointed out, that's not possible). Assuming what you're trying to do is define a common way to handle your exception logic in one place, Callable might be a way to go. Something like the following might suffice... Although I'm not going to comment on whether any of it is a good idea...
static E callAndHandle(final Callable<E> callable) {
try {
return callable.call();
} catch (final Exception ex) {
System.out.println(ex);
return null;
}
}
static void tryIt() {
final String result = callAndHandle(() -> {
// Thing which might throw an Exception
return "ok";
});
// result == null => there was an error here...
}
Unfortunately Runnable doesn't declare any Exception in the signature, so if you know it always needs to be void and you don't like the return null; or similar hacks, you'd have to define your own interface to pass in.
Ive two method that throw the same exception throws IOException
the problem is that each method throw it from different reason, I wrap the methods
in the main with try catch, what is the recommended way to solve it ?
I need different message for each exception with the same type..
public static void main(String[] args) {
try{
….
readFile(path);
convert(file)
} catch (IOException e) {
…..
}
private static String readFile(String path) throws IOException {
//Here files requires IOException - Reason here cannot Read file
String lineSeparator = System.getProperty("line.separator");
List<String> lines = Files.readAllLines(Paths.get(path));
}
private static String convert(String file) throws IOException {
//Here reader requires also ioException- Reason here cannot parse file
ObjectMapper reader = new ObjectMapper(new YAMLFactory());
Object obj = reader.readValue(file, Object.class);
}
There are several ways you could approach this. One way, perhaps the heaviest in terms of new code you would need to write, would be throw a custom exception from each of your helper methods. Then you could catch each specific exception in a separate block.
But what I might recommend here is that you simply wrap each of the two calls to your helper methods in separate try-catch blocks:
try {
readFile(path);
} catch (IOException e) {
// handle first exception here
}
// more code
try {
convert(file)
} catch (IOException e) {
// handle second exception here
}
This is fairly clean and doesn't require a lot of refactoring. If you keep encountering this problem, then maybe consider creating custom exceptions for your application. If you have a look at many Java libraries, you will see that they often use their own custom exceptions.
If you wanted to go the route of using a custom exception, you could define one, e.g.
public class FileReadIOException extends Exception {
public FileReadIOException(String message) {
super(message);
}
}
and then use it:
private static String readFile(String path) throws FileReadIOException {
try {
String lineSeparator = System.getProperty("line.separator");
List<String> lines = Files.readAllLines(Paths.get(path));
}
catch (Exception e) {
throw new FileReadIOException(e.getMessage());
}
}
try {
readFile(path);
// more code
convert(file)
} catch (FileReadIOException e) {
// handle first exception here
} catch (SomeOtherException e) {
// handle second exception here
}
The above code showing custom exception is a bit contrived, because the reality is that all of your code is throwing IOException. Creating custom exceptions in your case does not add much value, because they are already (rightfully) throwing an IOException. I'm not sure that it doesn't make sense to handle just one type of exception. More typically, if you were working on a large enterprise application, you would use custom exceptions to handle situations which go wrong in your own custom code.
My way is usually to create your own exception and throw it like that
public class Snippet {
public static void main(String[] args) {
try {
String path = "";
readFile(path);
String file = "";
convert(file);
} catch (MyException e) {
// do whatever
}
}
private static String readFile(String path) throws MyException {
try {
String lineSeparator = System.getProperty("line.separator");
List<String> lines = Files.readAllLines(Paths.get(path));
} catch (Exception e) {
throw new MyException("Custom 'readFile' message", e);
}
}
private static String convert(String file) throws MyException {
try {
ObjectMapper reader = new ObjectMapper(new YAMLFactory());
Object obj = reader.readValue(file, Object.class);
} catch (Exception e) {
throw new MyException("Custom 'convert' message", e);
}
}
}
class MyException extends Exception {
private static final long serialVersionUID = -3166824380774329449L;
public MyException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}
}
Tim's way is valid too.
#OP The best person to solve this would be you yourself.
There are quite easily multiple ways to solve that. Check which one suits you more properly.
One of the solution as per me is below. This is based on the reason IOException is superclass to many other exceptions. IOException documentation
try {
readFile(path);
} catch ( FileNotFoundException e) {
// handle first exception here
} catch ( EOFException e) {
// handle 2nd exception here
}
For the above to work you would need to know which type of IOException is being thrown.
Another solution is check individual exception messages when you know what are expected messages you may receive.
try {
readFile(path);
} catch ( IOException e) {
if(e. getMessage().contains("TXT 1...") {
//Case handle #1
} else if(e. getMessage().contains("TXT 2...") {
//Case handle #2
}
}
The best way to handle exception is not to have them. When exception is thrown, it indicates that natural lifecycle of your application has been interrupted for one reason or another. Most exceptions are self-explanatory and provide you with precise explanation of what happend, therefore creating new exceptions and re-mapping those thrown is almost always counterproductive and may result in more confusion than usefulness(especial if you work in a team).
Furthermore exceptions doesn't need to be terminal, in most cases, a scenario can be devised to retry/prompt different input etc. to ensure that lifecycle is not interrupted. Killing an application on exception can create more problems in some cases (e.g: not closing files properly, hence losing processed data).
Now to your actual problem. If you have two or more components, that throws unrelated exceptions(name is not a relation in this case), it is best not to have them in the same try/catch structure as less workaround will be necesary to scrap that one part, instead of the whole thing which can still exit on its own, or doesn't even need to be initiated.
Here is my 5 cents
public static void main(String[] args) throws Exception {
String path = "path";
String path2 = "path2";
try{
readFile(path);
} catch (IOException e) {
throw new Exception("read file exception", e);
}
try{
convert(path2);
} catch (IOException e) {
throw new Exception("convert exception", e);
}
}
private static String readFile(String path) throws IOException {
//Here files requires IOException - Reason here cannot Read file
String lineSeparator = System.getProperty("line.separator");
List<String> lines = Files.readAllLines(Paths.get(path));
}
private static String convert(String file) throws IOException {
//Here reader requires also ioException- Reason here cannot parse file
ObjectMapper reader = new ObjectMapper(new YAMLFactory());
Object obj = reader.readValue(file, Object.class);
}
I have a case in which I need duplicate try..catch block on controller level.
Let me provide sample code for this issue:
List<String> loadedList =
engine.findSomething(param); //At this point we can obtain Exception, so this code block we should move to existing try block or create another.. but the problem if we move this to try block below, the WebApplicationException that throws in condition below will be catched in existing try block..
// if not found - return NOT_FOUND.
if (CollectionUtils.isEmpty(loadedList)) {
log.info(errorMessage);
throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(errorMessage).type("text/plain").build()); //exception from Jersey lib
}
try {
for (String item : loadedList) {
//some business logic
//I know that on controller layer we should avoid business logic but it is not my code and I can not change it..
}
return Response.ok().build();
} catch (Exception e) {
throw processException(e); //Helper method that avoids code duplication when preparing webException
}
How can I refactor this code?
Thanks!
You can benefit from #ControllerAdvice and implement global controller exception handler.
#ControllerAdvice
public class GlobalExceptionHandler {
#ExceptionHandler(Exception.class)
public String handleException(HttpServletRequest request, Exception ex){
//handle error here
return "error";
}
In order GlobalExceptionHandler to work, Exception must be thrown out of your controller.
You can simply add a specific try/catch statement for the
List<String> loadedList = engine.findSomething(param);
invocation.
You should just declare List<String> loadedList before the call to engine.findSomething(param); in order that it is outside the try catch scope to be able to use it later.
List<String> loadedList = null;
try{
loadedList = engine.findSomething(param);
}
catch (Exception e){ // or a more specific exception if it makes sense
// exception logging and processing
}
try
{
List<String> loadedList = engine.findSomething(param);
// if not found - return NOT_FOUND.
if (CollectionUtils.isEmpty(loadedList)) {
log.info(errorMessage);
throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(errorMessage).type("text/plain").build()); //exception from Jersey lib
}
for (String item : loadedList) {
//some business logic
//I know that on controller layer we should avoid business logic but it is not my code and I can not change it..
}
return Response.ok().build();
}
//You can first catch WebApplicationException before the Exception and
//redirect the throw to the parent class
catch(WebApplicationException we)
{
throw we;
}
catch(Exception e)
{
throw processException(e);
}
Another approach different from davidxxx one.
Move the code inside the try..catch clause. If it happens to throw the WebApplicationException then catch it, do whatever you need to do with it and then throw it again.
try {
List<String> loadedList =
engine.findSomething(param);
// if not found - return NOT_FOUND.
if (CollectionUtils.isEmpty(loadedList)) {
log.info(errorMessage);
throw new WebApplicationException(Response.status(Status.NOT_FOUND).entity(errorMessage).type("text/plain").build()); //exception from Jersey lib
}
for (String item : loadedList) {
//some business logic
//I know that on controller layer we should avoid business logic but it is not my code and I can not change it..
}
return Response.ok().build();
} catch (WebApplicationException e1){
//log the exception
//throw it again using throw e1
} catch (Exception e2) {
throw processException(e2); //Helper method that avoids code duplication when preparing webException
}
I have the following code in a JUnit test (only including the relevant parts)
private String testRoot = System.getProperty("user.home");
private String destFail2 = testRoot + "/GoogleDrive/TestFail//..\\...//*";
#Test
public void given_NamedParameterizedFileSet_when_SavedWithInvalidFileName_then_Exception() {
String invalidFullPathToFileSet = fsPathDir + invalidBackupName;
//test save fully parameterized empty file set at non-existent directory
try {
FileSet fs = new FileSet(backupName, dest);
try {
FileSet.save(invalidFullPathToFileSet, fs);
fail("Save name is invalid, should refuse save");
} catch (IOException e) {
assert(true);
}
} catch (Exception e1) {
e1.printStackTrace();
fail("Could not create the file set");
}
}
The code for FileSet.save() is as follows:
public static void save(String fullPathToFile, FileSet fileSet) throws IOException {
ObjectOutputStream out = null;
Path outFilePath = Paths.get(fullPathToFile);
Path outDirPath = outFilePath.getParent();
if (Files.exists(outFilePath)) {
Files.delete(outFilePath);
}
if (!Files.exists(outDirPath)) {
Files.createDirectories(outDirPath);
}
try {
out = new ObjectOutputStream(new
BufferedOutputStream(Files.newOutputStream(outFilePath)));
out.writeObject(fileSet);
} catch (Exception e) {
e.printStackTrace();
} finally {
out.close();
}
}
The FileSet.save() method above SHOULD fail because it's being given what I think is an invalid file name, but somehow the code runs just fine without throwing an exception (on a Mac; haven't tried it on Windows).
Why is the code running?
Given the code, where do I look for the file it created?
What kind of filename do I need that is "bad?" I tried creating one with a colon (:) in it as it's supposed to be the only illegal character on a Mac, but even that works and it ends up creating a file with a colon in the middle of the name...
Is there a "better" way to write FileSet.save() (rather than using Path, should I be using File and passing the path in to the constructor as a string)?
Firstly, don't use assert keyword - if you run the java application without -ea parameter ("enable assertions"), this line will not execute at all. By the way assert true does nothing.
Secondly, exceptions that you do not care about, those that you are not testing, like e1 shouldn't be caught, declare that test method throws it. It will reduce the unnecessary complexity.
Finally, I would recommend using ExpectedException to do this assertion:
#Rule
public final ExpectedException expectedException = ExpectedException.none();
#Test
public void given_NamedParameterizedFileSet_when_SavedWithInvalidFileName_then_Exception() throws Exception {
String invalidFullPathToFileSet = fsPathDir + invalidBackupName;
FileSet fs = new FileSet(backupName, dest);
expectedException.expect(IOException.class);
FileSet.save(invalidFullPathToFileSet, fs);
}
This allows you to also check a message. It also checks that the exception is thrown after expect line. So if new FileSet(...) throws IOException, the test will fail. Note, ExpectedException needs to be annotated as #Rule to let junit now to perform a check at the end of test.
The test is successful because of improper exception handling. In the inner try-catch:
try {
FileSet.save(invalidFullPathToFileSet, fs);
fail("Save name is invalid, should refuse save");
} catch (IOException e) {
assert(true);
}
The line FileSet.save(invalidFullPathToFileSet, fs); throws an exception and for this reason the next line, which should fail the test, is not executed and the execution flow is redirected to the catch block where you simply assert(true) (which is a completely useless statement in a unit test) and then exit the inner and then the outer try-catch blocks, leading to successful execution.
What you should do is something like:
try {
FileSet.save(invalidFullPathToFileSet, fs);
} catch (IOException e) {
e.printStackTrace();
fail("Save name is invalid, should refuse save");
}
This will fail the test whenever an exception is thrown.
Due to my company's policy of using Eclipse and using Eclipse's code-autofix, the following code pattern appears excessively in the codebase:
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// handle error
}
}
}
IMO it's extremely fugly and hard to read, especially the portion within the finally block (is there really a need to catch 2 instances of IOException?). Is there anyway to streamline the code such that it looks cleaner?
Why do anything? It's working code. It's correct.
Leave it be.
First, about using IOUtils - may worth a shot telling your supervisors that the very application-server / Java runtime environment they might use, uses IOUtils and similar libraries itself. so in essence you're not introducing new components to your architecture.
Second, no, not really. There isn't really any way around it other than writing your own utility that will immitate IOUtils' closeQuietly method.
public class Util {
public static void closeStream(inputStream is) {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// log something
}
}
}
Now your code is
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
Util.closeStream(is);
}
Not a lot else to do as the IOException in the catch might have some specific processing.
See this question, use the closeQuietly() solution.
InputStream is = null;
try {
is = url.openConnection().getInputStream();
// .....
} catch (IOException e) {
// handle error
} finally {
IoUtils.closeQuietly(is);
}
// stolen from the cited question above
public class IoUtils {
public static closeQuietly (Closeable closeable) {
try {
closeable.close();
} catch (IOException logAndContinue) {
...
}
}
}
Or wait for JDK7's ARM blocks.
You could define something like this somewhere:
private static interface InputStreamCallback {
public void doIt(InputStream is) throws IOException;
}
private void with(InputStreamCallback cb) {
InputStream is = null;
// Creational code. Possibly adding an argument
try {
cb.doIt(is);
} catch (IOException e) {
// handle error or rethrow.
// If rethrow add throws to method spec.
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// handle error or rethrow.
}
}
}
}
And invoke your code like this:
with(new InputStreamCallback() {
#Override
public void doIt(InputStream is) throws IOException {
is = url.openConnection().getInputStream();
// .....
}
});
If you declare with method static in a helper class, then you could even do an import static of it.
There's a drawback. You need to declare url final.
EDIT: creational code is not the point. You can arrange it in several ways. The callback is the point. You could isolate what you need to do there.