I'm currently having issues with null analysis on both Eclipse and IntelliJ where they don't understand a piece of code that handles null pointer exceptions. Basically I got the method below:
#Nullable
public static <T> T getValueOrNull(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result).orElse(null);
} catch (NullPointerException e) {
return null;
}
}
Normally I wouldn't catch those types of exceptions but in the project I'm working this method makes things much more readable.
It is called this way:
getValueOrNull(() -> obj.getObj2().getObj3()...getObjN())
This call returns the value or null if anything is null in the chain.
The problem is that null analysis will complain about possible null pointer exceptions while calling the method. While it is true that any of them may be null the method is handling that error. Is there a way to either skip null analysis for the parameters of a method or help the analyzer understand what is happening?
It seems that even a very simple test where null pointer exceptions are being caught still flags potential null issues inside the try block. That makes me think that try catch blocks are never even considered by the analyzer.
Also I do know that there are other ways of doing this such as the code below but if possible I'd like to be able to use what we are currently doing due to readability. Also even the code below has issues with the null analysis for the IDEs mentioned above.
Optional.ofNullable(objectA)
.map(a -> a.getObjectB())
.map(b -> b.getObjectC())
.map(c -> c.getObjectD())
.map(d -> d.getObjectE())
.map(e -> e.getName())
.orElse("");
Related
I am currently creating a retry mechanism for performing requests using the failsafe-lib.
The issue: the RetryPolicy that I defined includes several timeout-related exceptions, but when I use the failsafe-lib (Failsafe.with(someFallback, somePolicy).get(() -> performRequest), exceptions that I did not specify (DataBufferLimitException) to be handled are negated instead of being thrown.
Now I understand that the FailsafeExecutor(...).get() method takes a CheckedSupplier, and this (possibly) might cause in negation of unchecked exceptions (please correct me if I'm wrong, this is just an assumption). However, I am still curious if I have done something wrong and if there is something that I can do to resolve this issue.
Below I have a simplified version of my code:
public Response performRequest() {
RetryPolicy<Object> retryPolicy = RetryPolicy.builder()
.withDelay(Duration.ofMillis(60_000L))
.handle(exceptionA, exceptionB, ...)
.withMaxRetries(3)
.onSuccess(o -> log.info("someRandomMessage"))
.onFailure(o -> log.warn("someRandomWarnMessage"))
.onRetriesExceeded(o -> log.error("someRandomErrorMessage"))
.build();
Fallback<Object> fallback = Fallback.of(event -> {
Throwable rootException = ExceptionUtils.getRootCause(event.getLastException());
if (rootException instanceof TimeoutException || rootException instanceof ConnectException) {
throw new someRandomException(rootException.getMessage());
}
}
);
Response response Failsafe.with(fallback, retryPolicy).get(() -> someRequest);
return response;
The scenario that is performed with this code:
We perform a request and (during testing) we expect to see an unchecked exception. However, this exception is 'swallowed' by functionality of the failsafe-lib, while I in fact want to see back this exception. I know this is more on my end, but I'm not sure how to fix this issue. Any tips, alternatives or corrections are much appreciated.
Found my own mistake: if the if-statement was not triggered, no exception would be thrown and null would be returned. This resulted in an empty response, etc.
I have a lot of cases where boolean variables begin a reactive sequence and in case they are a certain value (mostly false) an exception is supposed to be thrown and the sequence broken. For example
Mono.just(foo.isValid())
.flatMap(b -> b ? Mono.empty() : Mono.error(new FooNotValidException(foo.detail1, foo.detail2)))
.then(bar.doProcess())
.flatMap(b -> b ? Mono.empty() : Mono.error(new BarProcessingNotSuccessful(bar.detail1, bar.detail2)))
....
Here if foo is not valid bar is not executed and sequence is broken with a detailed exception, same if bar processing fails.
that up there is the shortest i managed to get it to, but there is a lot of repetition so i am wondering if this can be made any less verbose?
From Borises comment i rewrote the above code example to
Mono.fromRunnable(foo::isValidOrThrow) // may throw FooNotValidException
.then(Mono.fromRunnable(bar::doProcessOrThrow)) // may throw BarProcesingNotSuccessful
....
This looks much nicer.
I've been using Spark Dataset API to perform operations on a JSON to extract certain fields as needed. However, when the specification that I provide to let spark know what field to extract goes wrong, spark spits out an
org.apache.spark.sql.AnalysisException
How can unchecked runtime exceptions be handled in a distributed processing scenario like this ? I understand that throwing a try-catch would get things sorted but what is the recommended way to handle such a scenario
dataset = dataset.withColumn(current, functions.explode(dataset.col(parent + Constants.PUNCTUATION_PERIOD + child.substring(0, child.length() - 2))));
In scala, you should simply wrap the call in a Try and manage Failure. Something like:
val result = Try(executeSparkCode()) match {
case s: Success(_) => s;
case Failure(error: AnalysisException) => Failure(new MyException(error));
}
Note 1: If your question implies how to manage exception in scala, there are a lot of doc and post about this subject (i.e. don't throw). For example, you can check that answer (of mine)
Note 2: I don't have a scala dev env right here, so I didn't test this code)
In java there is a tricky situation however: the compiler doesn't expect an AnalysisException which is unchecked so you cannot catch this exception specifically. Probably some scala/java misunderstanding because scala doesn't track checked exceptions. What I did was:
try{
return executeSparkCode();
} catch (Exception ex) {
if(ex instanceOf AnalysisException){
throw new MyException(ex);
} else {
throw ex; // unmanaged exceptions
}
}
Note: In my case, I also tested the content of the error message for a specific exception that I must managed (i.e "path does not exist") in which case I return an empty dataset instead of throwing another exception. I was looking for a better solution and happened to get here...
When I am scanning code with sonar lint the following code shows the bug as "The return value of "orElseThrow" must be used"
itemList.stream()
.filter(item -> orderItemId.equals(item.getId()))
.findAny()
.orElseThrow(() -> new BadRequestException("12345","Item Not Found"));
This is just for a validation purpose no need to return anything from this statement. need to validate whether the item exists or not.
FYI: Eclipse showing a quick fix as squid:S2201
Anybody have any idea how to resolve this bug?
I'm assuming this is a warning (not using the value returned by orElseThrow() shouldn't be an error).
If you wish to eliminate that warning, use isPresent() instead:
if (!itemList.stream().filter(i->orderItemId.equals(i.getId())).findAny().isPresent()) {
throw new BadRequestException("12345","Item Not Found");
}
or just avoid using Optionals, and use anyMatch() instead:
if (!itemList.stream().anyMatch(i->orderItemId.equals(i.getId()))) {
throw new BadRequestException("12345","Item Not Found");
}
I am using Sonar and I have got this kind of violation from it for a peace of my code:
Correctness - Possible null pointer dereference
Has anyone know about this rule in findbugs? I searched a lot but I can not find a good sample code (in Java) which describe this rule, unfortunately findbugs site did not have any sample code or good description about this rule.
Why does this violation appear?
a sample code is something like this.
String s = null ;
if (today is monday){
s = "Monday" ;
else if (today is tuesday){
s = "Tuesday" ;
}
System.out.println(s.length()); //Will throw a null pointer if today is not monday or tuesday.
It says here
NP: Possible null pointer dereference (NP_NULL_ON_SOME_PATH)
There is a branch of statement that, if executed, guarantees that a null value will be dereferenced, which would generate a NullPointerException when the code is executed. Of course, the problem might be that the branch or statement is infeasible and that the null pointer exception can't ever be executed; deciding that is beyond the ability of FindBugs.
If you would have posted some code it would be easier to answer.
EDIT I don't see a lot of documentation but here is one example! Hope this helps!
Okay
This is two simple Examples :
First one gives a : Possible null pointer dereference
1. Error
ArrayList a = null;
a.add(j, PointSet.get(j));
// now i'm trying to add to the ArrayList
// because i'm giving it null it gives me the "Possible null pointer dereference"
2. No Error
ArrayList a = new ArrayList<>();
a.add(j, PointSet.get(j));
// adding elements to the ArrayList
// no problem
Simple ?
I got this issue with the following piece of code:-
BufferedReader br = null;
String queryTemplate = null;
try {
br = new BufferedReader(new FileReader(queryFile));
queryTemplate = br.readLine();
} catch (FileNotFoundException e) {
// throw exception
} catch (IOException e) {
// throw exception
} finally {
br.close();
}
Here, the br BufferedReader can be null in br.close(). However it can only be null if new BufferedReader() fails, in which case we are throwing the relevant exceptions.
This is thus a false warning. Findbugs docs mention the same:-
This may lead to a NullPointerException when the code is executed.
Note that because FindBugs currently does not prune infeasible
exception paths, this may be a false warning.
In simple language, if a variable value is assigned as null, and you try to access it with any inbuilt method like add/get. Then null pointer dereference issue comes with SONAR. Because there are changes for it go null, and throw null pointer exception. Try to avoid it if possible.
For example:
File file=null;
file.getName();
will throw "Possible null pointer dereference"
It may not happen directly as mentioned in the example, it can be unintentionally.