I have a super simple line:
JSONObject params = new JSONObject("{\"values\": { \"barcode\": \"testing\" } }");
Android studio tells me that this line 'throws JSONException', but why? I must be doing something stupid here. Any help is appreciated
JSONException is a checked exception. This means that you need to have code in place to deal with it. You need to either catch the exception or let it bubble up by declaring throws JSONException on your method.
This is the case for all checked exceptions in Java (all exception except those that extend RuntimeException).
In your case, since the String is constant and correct, I would do
} catch ( JSONException e) {
// should never happen
throw new IllegalArgumentException("unexpected parsing error",e);
}
This will convert the JSONException (if for some reason it does happen after all) into an (unchecked) RuntimeException.
public JSONObject(String source) throws JSONException {
this(new JSONTokener(source));
}
You are using above method/constrcutor to create your JSONObject and its saying in its signature that it throws JSONException so you can't simply do what you have done ,
JSONObject params = new JSONObject("{\"values\": { \"barcode\": \"testing\" } }");
You need to enclose above line in Java try- catch since method signature is clearly specifying a checked Exception so you need to handle that in try catch.
try{
JSONObject params = new JSONObject("{\"values\": { \"barcode\": \"testing\" } }");
}catch(JSONException ex){
//eat or rethrow your exception
}
You have to note that there are other JSONObject constructors which doesn't specify any checked exceptions so you can use those in a simple line, like you did but the one you are trying to use specifies a checked exception so you need to handle that - otherwise your code won't compile.
Related
im currently working in a complete generic scenario in which i map a json as string to a dto class. That works fine with my function mapJsonToDto but im trying to make it more generic so that the developer who uses this function can also specify what exception to be thrown. So they can catch as they like. With this i avoid catching an IOException. Letting the function handle everything.
public class MapperUtils {
public <T extends Throwable> Object mapJsonToDto(Class<?> dtoClass, String jsonDto, T exceptionToThrow) throws IOException {
Object dto = null;
try {
dto = new ObjectMapper().readValue(jsonDto, dtoClass);
} catch (IOException e) {
throw new exceptionToThrow();
}
return dto;
}
}
I cannot understand how to pass an exception class instance to a function and throwing that specific as well.
Instead of passing the exception to throw (which would then have a completely wrong stack trace), I think you'd want a function that converts an exception from one type to another:
public <T extends Throwable, D> D mapJsonToDto(Class<D> dtoClass, String json, Function<IOException, T> exceptionMapper) throws T {
try {
return new ObjectMapper().readValue(json, dtoClass);
// if readValue doesn't do the casting right, try:
return dtoClass.cast(new ObjectMapper().readValue(json, dtoClass);
} catch (IOException e) {
throw exceptionMapper.apply(e);
}
}
And an example:
Person p = mapJsonToDto(Person.class, "{name: \"Joe\"}",
e -> new IllegalArgumentException("malformed JSON", e));
As a general rule, though, this seems like boneheaded design. If you find the IOException overly general, then you can't handwave the problem away by allowing the caller to provide a no doubt similarly overly general mapper. The only way out for a caller is to do a deep dive on the exception and write, I dunno, an if/elseif block with a ton of levels to it to try to ascertain the real problem e.g. via analysing the message, which is all sorts of ugly.
Either you don't care about that level of detail and you should therefore just stick with IOException (what point is there adding code and pointless layers of indirection?), or you do care and this isn't good enough; you'd want to design a better error system. Except, that's not your job, that'd be ObjectMapper.readValue's job. Which is why the IOException it throws should probably just be sent on unmolested.
Your example is nearly done.
I changed only the throws Type to T and throw the given exception.
public <T extends Throwable> Object mapJsonToDto(Class<?> dtoClass, String jsonDto, T exceptionToThrow) throws T {
Object dto = null;
try {
dto = new ObjectMapper().readValue(jsonDto, dtoClass);
} catch (IOException e) {
throw exceptionToThrow;
}
return dto;
}
Call: mapJsonToDto(String.class, "helo", new IllegalStateException());
I'm trying to get the same result as when I use #Valid in object parameter from a Controller. When the object is invalid an exception (MethodArgumentNotValidException) is throw by my ExceptionHandlerController who has #RestControllerAdvice.
In my case I want to validate an object, but I only can validate it in service layer. The object have bean validation annotations, so I'm trying to programmatically throw MethodArgumentNotValidException for my ExceptionHandlerController handle it, but I'm not having success.
So far I have this:
private void verifyCard(CardRequest card) {
BeanPropertyBindingResult result = new BeanPropertyBindingResult(card, "card");
SpringValidatorAdapter adapter = new SpringValidatorAdapter(this.validator);
adapter.validate(card, result);
if (result.hasErrors()) {
try {
throw new MethodArgumentNotValidException(null, result);
} catch (MethodArgumentNotValidException e) {
e.printStackTrace();
}
}
}
The first parameter is from type MethodParameter and I'm not been able to create this object. Is it the best way to handle my problem?
EDIT 1:
I can't remove the try/catch block. When I remove it I get compile error. How to work around?
You have already handled it by the catch block, you should remove try-catch to your global handler catch it.
then specify the method like below
private void verifyCard(CardRequest card) throws MethodArgumentNotValidException
MethodArgumentNotValidException is a subclass of Exception. This means that it's "checked": To throw it out of your verifyCard(..) method, you have to declare that verifyCard(..) can throw it:
private void verifyCard(CardRequest card) throws MethodArgumentNotValidException {
// your code
}
If you have lombok dependency in your project, you can also fake compiler by using #SneakyThrows annotation.
https://projectlombok.org/features/SneakyThrows
throw new MethodArgumentNotValidException(null, result);
Above constructor will not work as method parameter is necessary.
Valid constructor (reference) is:
MethodArgumentNotValidException(MethodParameter parameter, BindingResult bindingResult);
Hence, in your case:
throw new MethodArgumentNotValidException(new MethodParameter(
this.getClass().getDeclaredMethod("verifyCard", YourClassName.class), 0), errors);
I'm getting the following findbugs error:
"Method call passes null for nonnull parameter : Null passed for nonnull parameter of getApiStatus(ApiResponse)"
If the apiResponse is null in the CallApi method (not shown here for brevity's sake), it simply throws an exception that is caught in handleApiException and thrown again if we can't do anything else about the exception.
There is no way that a null value for apiResponse could be passed into getApiStatus() method at the botton of this code snippit. How can I tell findbugs that this is the case without doing yet another null check on top of the null check that is done in the apiService.CallApi method? I've tried using the NonNull annotation, but that didn't resolve the issue. Here's the code in question:
ApiResponse apiResponse = null;
try {
apiResponse = apiService.CallApi(apiURL, requestObject);
}
catch (ApiException ex) {
handleApiException(ex);
}
boolean apiStatus = getApiStatus(apiResponse);
Any Ideas?
My suggestion would be to NOT handle the exception, but to set this method as throws ApiException. And then handle it higher up the chain. If your code gets an exeption in that try block, then handles the exception in the catch, then apiResponse can easily be null. And will then go on to try the getApiStatus method, hence passing in a null.
public void yourMethod() throws ApiException {
ApiResponse apiResponse = apiService.CallApi(apiURL, requestObject);
boolean apiStatus = getApiStatus(apiResponse);
// Whatever else you need to do here.
}
Your only other option is to put the apiStatus call below the apiResponse one inside the try block, like so:
ApiResponse apiResponse = null;
try {
apiResponse = apiService.CallApi(apiURL, requestObject);
boolean apiStatus = getApiStatus(apiResponse);
} catch (ApiException ex) {
handleApiException(ex);
}
Or, as you say, do a null check before calling getApiStatus, but that's not as preferable as the options above.
In your code, the getApiStatus(apiResponse) will be called regardless of the ApiException occurring or not.
You should have this instead:
try {
ApiResponse apiResponse = apiService.CallApi(apiURL, requestObject);
// line bellow will not execute if CallApi throws ApiException
boolean apiStatus = getApiStatus(apiResponse);
}
catch (ApiException ex) {
handleApiException(ex);
}
// lines bellow will execute after try-catch block above
// regardless of the ApiException occurring or not
If CallApi throws an exception, then it will be handled and control will continue to getApiStatus, without apiResponse ever being assigned anything other than the initial null.
Let's say we have such a simple parser:
public class ResourceManager {
private final static Logger LOG = Logger.getLogger(ResourceManager.class);
public Museum parseJSONFile(String filePath) /*throws IOException ???? */ {
Museum museum = null;
try {
ObjectMapper objectMapper = new ObjectMapper();
museum = objectMapper.readValue(new File(filePath), Museum.class);
} catch(IOException e) {
LOG.error(e);
}
return museum;
}
}
Should the exception be caught in method or in the calling code? Which variant is better?
Parser can't do anything with exception, so that's an exceptional situation for a parser and it can't produce any expectable result. Someone from the outside should handle it.
In particular, it should not return null as it will result in bunch of null-checks in calling code (which you can easily forget to put, or due to the lack of documentation on your implementation I just don't know whether I have to check for null without seeing the code). This is one of the problems that exceptions in Java were intended to solve. By declaring checked-exception in method signature, you're enforcing users of your parser to deal with fact that value might not come.
I am using netbeans to make webservices, I want to make composite webservice using PBEL,
I face a problem in throwing exception in each service, I define complex Type in the schema of the exception I want to throw, and I make it in WSDL too , but inside the service I don't know how can I throw the exception , Here's the example I am working on :
#WebService(serviceName = "CreditCardService", portName = "CreditCardPort", endpointInterface = "org.netbeans.j2ee.wsdl.creditcard.CreditCardPortType", targetNamespace = "http://j2ee.netbeans.org/wsdl/CreditCard", wsdlLocation = "WEB-INF/wsdl/NewWebServiceFromWSDL/CreditCard.wsdl")
public class NewWebServiceFromWSDL implements CreditCardPortType {
public org.netbeans.xml.schema.creditcard.CreditCardResponseType isCreditCardValid(org.netbeans.xml.schema.creditcard.CreditCardType creditCardInfoReq) throws IsCreditCardValidFault {
List<CreditCardType> creditCards = parseCreditCardsFile();
CreditCardResponseType creditCardResponseElement = new CreditCardResponseType();
for (CreditCardType aCreditCard : creditCards) {
if (creditCardInfoReq.getCreditCardNo() == Long.parseLong(String.valueOf(aCreditCard.getCreditCardNo())) {
creditCardResponseElement.setValid(true);
return creditCardResponseElement;
}
}
throws IsCreditCardValidFault(); //here I want to throw an exception .
}
Please can Someone help?
throws IsCreditCardValidFault(); //here I want to throw an exception .
needs to be written as
throw new IsCreditCardValidFault();
throws is used in your declaration of the method, where the throw keyword is used inside the method to indicate where you will throw the exception.
so as an example
try {
//do something which generates an exception
}catch(Exception e){
throw e;
}
but in your case, you want to initiate the exception yourself so you have to create a new object of that exception type. You will create the exception yourself, so no need to enclose in a try/catch block.
throw new IsCreditCardValidFault();