How do I check object null checking inside setter method in java? - java

this is the usual way
productMenu = productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId")));
if (productMenu != null) {
productPost.setProductMenu(productMenu);
}
can i do this not null object checking inside setter method
productPost.setProductMenu(productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId"))));
Trying to reduce the code. Would appreciate any sort of help.

Version >= Java 8
You could use Optional to ensure only non null value will be set.
Optional.ofNullable(request.getString("productMenuId"))
.map(value-> Integer.parseInt(value))
.map(productMenuService::getProductMenuById);
.ifPresent(productPost::setProductName);
Version < Java 8
void setProductMenu(*ProductMenuType* productMenu) {
// do all your checking before setting here
if (productMenu != null) {
productPost.setProductMenu(productMenu);
}
}
But your case doesn't make sense(no else part) because if we are not setting a value for a variable, then by default it will be NULL

if(productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId")) == null){
return new ResponseEntity<String>("Not found", HttpStatus.BAD_REQUEST);
}else{
productMenu = productMenuService.getProductMenuById(Integer.parseInt(request.getString("productMenuId")));
}
//in your repository first check that data is present or not like this
repository.findById(id).isPresent(){
return repository.getOne(id);
}else return null

Throw an exception.
If someone passes an invalid product menu ID to your application, they made a mistake. You should not act like they did nothing wrong. Your application certainly should not leave the old product menu in place and ignore the user’s request entirely.
if (productMenu == null) {
throw new RuntimeException("Invalid product menu ID.");
}
productPost.setProductMenu(productMenu);
While this won’t make your code shorter, it will make your code better.
A robust application does not pretend that it’s working when it is not in fact working. To do otherwise would frustrate users and would make debugging a lot more difficult, as it could be weeks or months or years before the problem is discovered.
Ideally, you will want to create your own exception class, and throw that instead:
if (productMenu == null) {
throw new InvalidProductMenuIDException("Invalid product menu ID.");
}
productPost.setProductMenu(productMenu);
where the exception class is simply:
public class InvalidProductMenuIDException
extends Exception {
public InvalidProductMenuIDException(String message) {
super(message);
}
public InvalidProductMenuIDException(Throwable cause) {
super(cause);
}
public InvalidProductMenuIDException(String message,
Throwable cause) {
super(message, cause);
}
}

Related

java.lang.NullPointerException to show addition information about parent object and null object

public class ExampleNullPointer {
public static void main(String[] args) {
try {
getEmployee().getDept().getLocation().getContactPerson();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
Output
java.lang.NullPointerException
at com.india.test.ExampleNullPointer.main(ExampleNullPointer.java:7)
Looking at above code and its output, when java throws java.lang.NullPointerException, is there anyway we can wrap this NullPointerException to show additional information, like which Object is null, or some info about its parent object, such as the parent object's name attributes?
I am mainly looking for parent object's attribute values, for example Dept is null so if I can log Employee's primary key or Employee's name by overriding toString() method.
Is there anyway I can generically make changes to get these information, so that whenever program throws NullPointerException I get these additional information which will help me easily identify the issue and the data which are causing the issue?
The NullPointerException should not be a part of normal application logic. It's thrown only to find bugs in your code. If you write getEmployee().getDept().getLocation().getContactPerson(), you should be absolutely sure that employee, dept, location exist. Thus you can modify your methods like this:
public Employee getEmployee() {
if(employee == null) {
// some business-level exception
throw new EmployeeAbsentException(this.toString());
}
return employee;
}
// in Employee class
public Dept getDept() {
if(dept == null) {
throw new EmployeeHasNoDeptException(this);
}
return dept;
}
And so on. Of course you should have your own system of business-logic exceptions. You may reuse the same exception class or create several ones (probably subclassing some abstract BusinessLogicException). This way you can easily distinguish what's happening and display the corresponding messages to the user or log them to investigate bugs.
If you want to be able to check whether Employee exists without catching exceptions, add another method like this:
public boolean hasEmployee() {
return employee != null;
}

Right way to use the #NonNull annotation in Android Studio

I'd like to use the #NonNull annotation in Android, but I can't figure out just the right way to do it.
I propose you this example:
public void doStuff(#NonNull String s){
//do work with s...
}
So when i call doStuff(null) the IDE will give me a warning. The problem is that I cannot rely on this annotation since, like this question points out, they don't propagate very far. So I'd like to put a null check on my method, like this:
if(s==null) throw new IllegalAgrumentException();
But the IDE, assuming that s!=null, will warn me that s==null is always false. I'd like to know what is the best way to do this.
I personally think that there should be an annotation like #ShouldntBeNull that only checks and warns that null isn't passed to it, but doesn't complains when the value is null checked.
You can use Objects.requireNonNull for that. It will do the check internally (so the IDE will not show a warning on your function) and raise a NullPointerException when the parameter is null:
public MyMethod(#NonNull Context pContext) {
Objects.requireNonNull(pContext);
...
}
If you want to throw another exception or use API level < 19, then you can just make your own helper-class to implement the same check. e.g.
public class Check {
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new IllegalArgumentException();
return obj;
}
}
and use it like so:
public MyMethod(#NonNull Context pContext) {
Check.requireNonNull(pContext);
...
}
Google examples do it as follows
import static com.google.common.base.Preconditions.checkNotNull;
...
public void doStuff(#NonNull String sParm){
this.sParm= checkNotNull(s, "sParm cannot be null!");
}
You can use the comment-style suppression to disable that specific null check warning, e.g.:
public MyMethod(#NonNull Context pContext) {
//noinspection ConstantConditions
if (pContext == null) {
throw new IllegalArgumentException();
}
...
}
You'll need that //noinspection ConstantConditions every time you do it.

Android: setRequestProperty function of URLConnection, what does this method do?

Although I know that StackOverflow has already setRequestProperty function of HttpURLConnection question, I really don't understand what this method does. I cannot "step into" it (F7) when debugging. I pressed Ctrl-B to view the method's body, but it only has the following code:
public void setRequestProperty(String field, String newValue) {
checkNotConnected();
if (field == null) {
throw new NullPointerException("field == null");
}
}
and checkNotConnected:
private void checkNotConnected() {
if (connected) {
throw new IllegalStateException("Already connected");
}
}
I mean that where is the code that puts the value to the field? Any explanation is appreciated.
UPDATE (2015/08/08):
I have found the way to view its implementation. Since it's abstract, must use Ctrl-Alt-B instead of Ctrl-B to view.
I guess you are accessing the wrong way, or have some kind of protected code...
The original function is this:
/**
* Sets the general request property. If a property with the key already
* exists, overwrite its value with the new value.
* ...
*/
public void setRequestProperty(String key, String value) {
if (connected)
throw new IllegalStateException("Already connected");
if (key == null)
throw new NullPointerException ("key is null");
if (requests == null)
requests = new MessageHeader();
requests.set(key, value);
}
Where requests.set(key, value) do what you're asking for :)!
this is back source code of setRequestProperty()
Sets the general request property. If a property with the key already exists, overwrite its value with the new value.
NOTE: HTTP requires all request properties which can legally have multiple instances with the same key to use a comma-seperated list syntax which enables multiple properties to be appended into a single property.
Parameters:
key the keyword by which the request is known (e.g., "accept").
value the value associated with it.
Throws:
java.lang.IllegalStateException
if already connected
java.lang.NullPointerException
if key is null
See also:
getRequestProperty(java.lang.String)
public void setRequestProperty(String key, String value) {
if (connected)
throw new IllegalStateException("Already connected");
if (key == null)
throw new NullPointerException ("key is null");
if (requests == null)
requests = new MessageHeader();
requests.set(key, value);
}
Source Link
I have found the way to view its implementation. Since it's abstract, must use Ctrl-Alt-B instead of Ctrl-B to view.
And the back source code of setRequestProperty as the following (inside jre\lib\rt.jar):
public void setRequestProperty(String var1, String var2) {
if(this.connected) {
throw new IllegalStateException("Already connected");
} else if(var1 == null) {
throw new NullPointerException("key is null");
} else {
if(this.isExternalMessageHeaderAllowed(var1, var2)) {
this.requests.set(var1, var2);
}
}
}

Unexpected results when displaying error messages in Java EE application (no error when field is null)

I am coding a web-app in Java-EE and find myself with a very unexpected result when I am trying to display errors on user-input.
The app is built on the JSP/Servlet/Form/Bean model. Basically, the JSP stores data in the request, and transfers it to the servlet. Then the servlet transfers the request raw to the form, which then reads the data, performs the necessary checks and returns the bean to the servlet.
Most of the fields must have specific values, some others must simply be non-null.
I have written error detection code to secure inputs however I find myself with a very strange result:
when the field is non-null but the value is incorrect (say, an hour located outside the 00:00-23:59 range), it does return the proper error, along with the error message, stored in a HashMap, and I can access it in my JSP.
However, when the field is null, it returns the message, probably stores it in the HashMap as well (I know this because the ${!empty errors.dataErrors} test returns true and the error field is displayed in my JSP) but there's no way to access the values of the errors
I have searched through my code but still can't find where the error comes from. Here are snippets of it if someone knows where the problem comes from
doPost method from the servlet:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
NewBookingForm form = new NewBookingForm();
Booking booking = form.registerBooking(request);
String VUE;
request.setAttribute("booking", booking);
request.setAttribute("errors", form);
this.getServletContext().getRequestDispatcher(VIEW).forward(request, response);
}
the map is a field in the NewBookingForm class, declared and initialized outside the registerBooking method like this private Map<String,String> dataErrors = new HashMap<String,String>(); and it has a private setter (for access within the class) and a public getter (for access in the Servlet and in the JSP)
inside the form class, I use this function to get the field values:
private static String getFieldValue(HttpServletRequest request, String fieldName)
{
String value = request.getParameter(fieldName);
if (value == null || value.trim().length() == 0){return null;}
else{return value;}
}
After getting the values with a series of calls like String fieldDepartureStation = getFieldValue(request, FIELD_DEPARTURE_STATION); at the beginning of my method, I then check them using try/catch blocks like this
try
{validation.departureStation(fieldDepartureStation);}
catch(Exception e)
{setDataErrors(FIELD_DEPARTURE_STATION, e.getMessage());}
The validations method within the validation class are a bit different if the data must have specific value-ranges or must simply be non-null.
In the former case, they are something like this:
public void departureTime(String time) throws Exception
{
if (!validationRETime(time)) { throw new Exception("Please input a time with the hh:mm pattern"); }
}
....
private boolean validationRETime(String strTime)
{
String regExp = "^([01][0-9]|2[0-3])[:][0-5][0-9]$"; // hh:mm
if (strTime.matches(regExp))
{
return true;
}
else
{
return false;
}
}
whereas in the latter case they are simply
public void departureStation(String station) throws Exception
{
if (station.equals(null)) { throw new Exception("Please input a departure station"); }
}
Finally, in my JSP, I use the following code to display errors:
<c:if test="${!empty errors.dataErrors}">
<p>Errors</p>
<c:forEach items="${errors.dataErrors}" var="message">
<p><c:out value="${message.value}" /></p>
</c:forEach>
</c:if>
And it does display the Error paragraph when I purposedly enter incorrect values, but the <c:forEach> is only looping and displaying the error messages when the wrong field is non-null but with an incorrect value. Thus with a field that only needs to be non-null, I never get the message (but I do get the error)
These are all the things I could think of that could possibly go wrong, but I have yet to discover where they did and if someone could help me, I'd be very glad.
The problem is in your departureStation method: -
public void departureStation(String station) throws Exception
{
if (station.equals(null)) {
throw new Exception("Please input a departure station");
}
}
Your test for null value is itself triggering a NPE. So, as soon as station.equals(null) is executed for station = null, a NPE exception is thrown, which is then propagated to the caller. So, your if block will not even be executed. And hence you are not throwing the Exception as you might be thinking.
Now, also note that, the NPE that is thrown does not contain any message. So, e.getMessage() will return null on it.
Now, let's move back to the caller: -
try
{validation.departureStation(fieldDepartureStation);}
catch(Exception e)
{setDataErrors(FIELD_DEPARTURE_STATION, e.getMessage());}
Here you are doing the biggest Crime in the world of Exception Handling, by using a catch block for Exception. Since Exception is the super class of all the exceptions, it will handle all the exceptions in the same way. So, it consumes the NPE, and passes it to setDataErrors().
So, you will of course get the errors, but, the value e.getMessage() will be null. And that is why you are not seeing any message. You can even test it by logging the value of e.getMessage() in the catch block above.
Solution ??
Just change your null check with this one: -
if (station == null) {
throw new Exception("Please input a departure station");
}
And everything will be ok. I think, you will have to do this change in all of your methods. Always perform the null check using == operator.
public class Test {
public static void main(String[] args) {
Test c = new Test ();
try {
c.departureTime("30:30");
} catch (Exception e) {
System.out.println(e.getMessage());
}
try {
c.departureTime(null);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void departureTime(String time) throws Exception {
if (!validationRETime(time)) {
throw new Exception("Please input a time with the hh:mm pattern");
}
}
private boolean validationRETime(String strTime) {
String regExp = "^([01][0-9]|2[0-3])[:][0-5][0-9]$"; // hh:mm
if (strTime.matches(regExp)) {
return true;
} else {
return false;
}
}
}
You will figure out your problem by running above code. Simply putting, you need to make sure exp.getMessage() always has value. To fix the issue, you might want to tweak your departureTime() method to provide more fine-grained exception handling.

Java - find the first cause of an exception

I need to check if an exception is caused by some database problem. I receive an Exception and check if its cause contains the "ORA" string and return that (something like "ORA-00001"). The problem here is that the exception I receive is nested inside other exceptions, so if I don't find out if it's an oracle exception, I have to check into the cause of that exception and so on.
Is there a cleaner way to do this? Is there a way to know the first cause (the deep-nested exception) of a given exception?
My current code looks like this:
private String getErrorOracle(Throwable e){
final String ORACLE = "ORA";
if (e.getCause() != null && e.getCause().toString().contains(ORACLE)){
return e.getCause().toString();
} else if(e.getCause() != null){
return getErrorOracle(e.getCause());
} else {
return null;
}
}
In the interests of not reinventing the wheel, if you're using Apache Commons Lang, then look at ExceptionUtils.getRootCause().
Is it worth including a library just for that? Maybe not. But if you already have it on your classpath, it's there for you, and note that it does some things that a 'naive' implementation might not do (e.g. deal with cycles in the cause chain... ugh!)
If you are already on Guava than Throwables.getRootCause() comes to the rescue.
Just traverse the exception chain until you get to an exception with no cause, and then just return that message, if you want the last one.
Your function will only get the first cause, if there is one.
You may want to look at finding the first cause in your package though, as the actual deepest one may be an oracle exception, which is helpful, but unless you can see where you created the problem, you will have a hard time fixing it.
Probably a bit overkill for your usage but I think it is cleaner (and reusable)
interface ThrowablePredicate {
boolean accept(Throwable t);
}
public OracleErrorThrowablePredicate implements ThrowablePredicate {
private static final ORA_ERR = "ORA";
public boolean accept(Throwable t) {
return t.toString().contains(ORA_ERR);
}
}
public class CauseFinder {
private ThrowablePredicate predicate;
public CauseFinder(ThrowablePredicate predicate) {
this.predicate = predicate;
}
Throwable findCause(Throwable t) {
Throwable cause = t.getCause();
return cause == null ? null
: predicate.accept(cause) ? cause : findCause(cause)
}
}
// Your method
private String getErrorOracle(Throwable e){
return new CauseFinder(new OracleErrorThrowablePredicate()).findCause(e);
}
I think that any error that is thrown by oracle will be wrapped in a SQLException (somebody please correct me if wrong). Once you have accessed the SQLException you should be able to call
getErrorCode()
Retrieves the vendor-specific exception code for this SQLException object.
Let me know if this works as I have never tried it :-)
Karl
You could improve your code checking for SQLException
import java.sql.SQLException;
private static final String ORACLE = "ORA";
public String doHandle(Throwable t) {
if (t.getClass().isAssignableFrom(SQLException.class)) {
SQLException e = (SQLException) t;
int errCode = e.getErrorCode();
String state = e.getSQLState();
String msg = e.getMessage();
if (msg.contains(ORACLE)) {
return msg;
}
} else {
if (t.getCause() != null) {
return this.doHandle(t.getCause());
}
}
return "";
}
Also, I think in Oracle "errCode" contains the number associated to ORA-nnnn
In my Spring Boot project for getRootCause IDEA suggest 3 static import:
Spring Core: org.springframework.core.NestedExceptionUtils.getRootCause
Jackson: com.fasterxml.jackson.databind.util.ClassUtil.getRootCause
Guava (Swagger transitive) com.google.common.base.Throwables.getRootCause
Most smart (with cycle check) is Spring NestedExceptionUtils.getRootCause.
But, if your excetion has no cause, method returns null.
In my case it is wrong, so I've done:
#NonNull
public static Throwable getRootCause(#NonNull Throwable t) {
Throwable rootCause = NestedExceptionUtils.getRootCause(t);
return rootCause != null ? rootCause : t;
}
ExceptionUtils.getRootCause(), and Throwables.getRootCause() returns null if the cause of the exception being passed is null.The following method will return the original throwable if an throwable without a cause is being passed as the input parameter.
/**
* #return the root cause of a given throwable.
* If throwable without a cause is being passed, the original throwable will be returned
*/
public static Throwable getRootCause(#NonNull final Throwable throwable) {
List<Throwable> throwableList = ExceptionUtils.getThrowableList(throwable);
return throwableList.get(throwableList.size() - 1);
}
One line solution using core Java API:
try {
i = 1 / 0;
} catch (ArithmeticException e) {
System.out.println(new ArithmeticException().initCause(e).getCause());
}
One more solution below works as well:
try {
i = 1 / 0;
} catch (ArithmeticException e) {
System.out.println(new Exception().initCause(e).getCause());
}
Both of them will print
java.lang.ArithmeticException: / by zero
I want to add Kotlin extension functions to get root causes:
fun Throwable.rootCause(): Throwable {
return if (cause == null) this else cause!!.rootCause()
}
//Return null if first cause is null
fun Throwable.optRootCause(): Throwable? {
return if (cause == null) null else cause!!.rootCause()
}
Or this one if need to find a cause inside the throwable chain at any points:
fun <T : Throwable> Throwable.isOrContainsCauseOfType(clazz: KClass<T>): Throwable? {
return when {
clazz.isInstance(this) -> this //remove if you want to exclude [this]
cause == null -> null
clazz.isInstance(cause) -> cause
else -> cause!!.isOrContainsCauseOfType(clazz)
}
}
If the exception being thrown is always going to be of a specific type, like OracleException, you can catch just that exception.
For example:
try {
...
} catch(OracleException oe) {
...
}
This would only apply if there are specific Oracle exceptions being thrown. I don't know much about Oracle, so before attempting this you will probably want to find out if that's what's happening.
on 28-01-2015 , i have unable to solve my problem with any of the above solution, so my recommendation is to use :
e.getMessage().toString();
Ps: i am using it on android.

Categories