Android skipping code - java

I'm experiencing a (in my view) really weird problem. I have an Android Project in Android Studio containing the following code:
if(AppSettings.isNetworkAvailable(context, showDialog)) {
return null;
}
else {
HttpResponse httpResponse = null;
AsyncHttpGet asyncHttpGet = new AsyncHttpGet(mHttpClient, mHttpContext);
String url = BASE_URI + atPath;
asyncHttpGet.execute(url);
try {
httpResponse = asyncHttpGet.get();
System.out.println("Response: " + httpResponse);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if(isAccepted(httpResponse)) {
return httpResponse;
} else {
return null;
}
}
This code returns null at runtime and gives no output. The debugger cursor jumps from the first if-clause (which returns true) directly to the last return statement without declaring or initializing any of the variables.
I have also tried removing the else as it should work without it, but that makes no difference. Does anyone have an idea where the problem could be?
EDIT: I should add: the code works just fine without the initial if-clause and returns a valid HttpResponse.

if the AppSettings.isNetworkAvailable(context, showDialog) is true, return null is the correct behaviour.
If you want to enter the else part, use this:
if(AppSettings.isNetworkAvailable(context, showDialog)) {
HttpResponse httpResponse = null;
AsyncHttpGet asyncHttpGet = new AsyncHttpGet(mHttpClient, mHttpContext);
String url = BASE_URI + atPath;
asyncHttpGet.execute(url);
try {
httpResponse = asyncHttpGet.get();
System.out.println("Response: " + httpResponse);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if(isAccepted(httpResponse)) {
return httpResponse;
} else {
return null;
}
}

Related

A "NullPointerException" could be thrown; "activationConfigParser" is nullable here

sonar issue
private void getGtcj(String gtcjStatusValue, String strArchiveReqd) throws Exception {
XPathHelper activationConfigParser = null;
try {
activationConfigParser = ConfigUtil.getInstance().getConfigParser(new URL((V21Constants.FILE
+ System.getProperty(V21Constants.USER_DIR) + "/vServe21/config/ActivationParameters.xml")));
} catch (Exception e) {
log.error(e.getMessage());
}
StringBuffer useGTCJSolution = new StringBuffer();
useGTCJSolution.append(XPathConstants.ACTIVATION_CONFIG_ACTIVATION_PARAM)
.append("/parameter[#name = '").append(XPathConstants.TAG_NAME_USE_GTCJ_SOLUTION)
.append("']");
String useGTCJSolutionStr = activationConfigParser.evaluateXPath(useGTCJSolution.toString());
log.debug("useGTCJSolutionStr value:" + useGTCJSolutionStr);
if (useGTCJSolutionStr != null && useGTCJSolutionStr.trim().equalsIgnoreCase(V21Constants.YES)
&& (gtcjStatusValue.equalsIgnoreCase(Statuses.ACTIVATION_SUCCESS)
|| gtcjStatusValue.equalsIgnoreCase(Statuses.ROLLBACK_SUCCESS)
|| gtcjStatusValue.equalsIgnoreCase("Rollback Failure"))) {
log.debug("No need to archive and send response from here.");
} else {
log.debug("inside GTCJSolution for GTCJ orders...Archiving and sending response xml");
if (strArchiveReqd != null && "Yes".equalsIgnoreCase(strArchiveReqd)) {
archiveXML(responseFileName, V21Constants.VIF_ARCHIVE_RESPONSE_XML_PATH);
}
// sending the response XML
response = new Response();
response.sendResponseXML(properties, responseXml, bNBSConnectivityFlag, queueName, address);
}
}
I figured out there should be a finally block after catch, but I don't know what to add inside the finally block. Or is there any other solution?
When you create the variable activationCOnfigParser you're in a try/Catch block. You can bypass this error :
private void getGtcj(String gtcjStatusValue, String strArchiveReqd) throws Exception {
XPathHelper activationConfigParser = null;
try {
activationConfigParser = ConfigUtil.getInstance().getConfigParser(new URL((V21Constants.FILE
+ System.getProperty(V21Constants.USER_DIR) + "/vServe21/config/ActivationParameters.xml")));
} catch (Exception e) {
actionConfigParser = <DEFAULT VALUE>
log.error(e.getMessage());
}
In catch block there is that you can replace with a value that actionConfigParser has to assuming in case of exception.

SocketException: Too many open files in AWS Lambda

This Java method is part of the executed code within an AWS Lambda function:
private static String getLocationIQAddress(double lat, double lng, boolean cached) {
lat = truncate(lat);
lng = truncate(lng);
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
RestTemplate restTemplate = new RestTemplate();
ClientHttpRequestInterceptor ri = new LoggingRequestInterceptor();
List<ClientHttpRequestInterceptor> ris = new ArrayList<>();
ris.add(ri);
restTemplate.setInterceptors(ris);
HttpEntity<?> request = new HttpEntity<Object>(headers);
ResponseEntity<LocationIQResponse> response = null;
LocationIQResponse obj = null;
try {
URIBuilder uriBuilder = new URIBuilder(LOCATIONIQ_URL);
uriBuilder.addParameter("key", LOCATIONIQ_TOKEN);
uriBuilder.addParameter("lat", String.valueOf(lat));
uriBuilder.addParameter("lon", String.valueOf(lng));
uriBuilder.addParameter("format", "json");
uriBuilder.addParameter("accept-language", "es");
long delay = 100;
boolean retry = true;
do {
try {
long start = System.currentTimeMillis();
response = restTemplate.exchange(uriBuilder.build(), HttpMethod.GET, request,
LocationIQResponse.class);
CloudWatchSubmit.sendMetric(LOCATION_IQ, ELAPSED, (double) (System.currentTimeMillis() - start));
obj = response.getBody();
} catch (HttpMessageNotReadableException e) {
LOG.log(Level.SEVERE, "Problem input: {0},{1}", new Object[] { lat, lng });
HttpInputMessage msg = e.getHttpInputMessage();
if (msg == null) {
LOG.severe("Null response body");
} else {
LOG.severe("Not null response body");
try (Scanner scanner = new Scanner(msg.getBody())) {
LOG.log(Level.SEVERE, "HTTP Body: {0}", scanner.useDelimiter("\\A").next());
}
}
LOG.log(Level.SEVERE, "cause");
LOG.log(Level.SEVERE, e.getMostSpecificCause().getMessage());
LOG.log(Level.SEVERE, "exception");
LOG.log(Level.SEVERE, e.getMessage());
retry = false;
} catch (HttpServerErrorException e) {
LOG.log(Level.SEVERE, e.getMessage() + " / " + e.getResponseBodyAsString());
CloudWatchSubmit.sendMetric(LOCATION_IQ, SERVER_ERROR, 1);
retry = false;
} catch (ResourceAccessException e) {
LOG.log(Level.SEVERE, e.getMessage());
CloudWatchSubmit.sendMetric(LOCATION_IQ, SERVER_ERROR, 1);
retry = false;
} catch (HttpClientErrorException e) {
String err = e.getResponseBodyAsString();
if (HttpStatus.TOO_MANY_REQUESTS.equals(e.getStatusCode())) {
if (err.contains(RATE_LIMITED_SECOND)) {
CloudWatchSubmit.sendMetric(LOCATION_IQ, RETRIES, 1);
try {
Thread.sleep(delay);
delay *= 2;
} catch (InterruptedException e2) {
Thread.currentThread().interrupt();
}
} else {
LOG.log(Level.SEVERE, err);
CloudWatchSubmit.sendMetric(LOCATION_IQ, err, 1);
retry = false;
}
} else {
LOG.log(Level.SEVERE, e.getMessage() + " / " + err + " / " + e.getResponseBodyAsString());
CloudWatchSubmit.sendMetric(LOCATION_IQ, CLIENT_ERROR, 1);
retry = false;
}
} finally {
CloudWatchSubmit.sendMetric(LOCATION_IQ, INVOCATIONS, 1);
}
} while (obj == null && retry);
StackTraceElement elem = Thread.currentThread().getStackTrace()[2];
StackTraceElement elem2 = Thread.currentThread().getStackTrace()[3];
CloudWatchSubmit.sendMetric(elem.getClassName(), elem.getMethodName(), elem2.getClassName(),
elem2.getMethodName(), cached);
} catch (Exception e) {
LOG.log(Level.SEVERE, "Big Problem input: {0},{1}", new Object[] { lat, lng });
LOG.log(Level.SEVERE, e.getMessage(), e);
}
return getAddress(obj);
}
After several invocations of the corresponding Lambda, we ocasionally get errors like:
Caused by: java.io.FileNotFoundException: /var/task/com/amazonaws/services/dynamodbv2/document/Table.class (Too many open files)
On another lambda using this same method we get the same Exception, but regarding log4j classes so, we are pretty sure it has to do with the referenced Java method, as it's opening HTTP connections (which correlate to file descriptors in Linux) via Spring's RestTemplate.
I've already read several posts and blogs regarding this issue on several environment where you can actually tweak the OS limits but, as we are inside an AWS Lambda the scenario is a bit different and I'd like recommendations on how to deal with this issue as, I'm trying to reproduce this issue outside Lambda and, haven't been able to do so. The idea was to get the same exception so check how several suggested changes may impact, either correcting the issue or, making it worse. But, as we haven't been able to reproduce it outside locally, we'll have to to trial and error on AWS Lambda execution environment.

Interface returning null in java

I am trying to get information from my AsyncHttpClient in my Android app, and I need to use an interface to set the variable so I can use it in my main method. However, when I run System.out.println(PostResponse);, I am getting null.
I don't understand why, because if I put the line in my callback() method, I get the values.
From my main method:
try {
JSONArray PostResponse = PerformPostRequest(new OnJSONResponseCallback() {
#Override
public JSONArray onJSONResponse(boolean success, JSONArray response) {
System.out.println("Response: " + response); //This is returning the correct value
return response;
}
}, PostData);
System.out.println("Useable: " + PostResponse); //This is returning null.
} catch (Exception e) {
e.printStackTrace();
}
The interface:
public interface OnJSONResponseCallback {
public JSONArray onJSONResponse(boolean success, JSONArray response);
}
The AsyncHttpClient:
public JSONArray PerformPostRequest(final OnJSONResponseCallback callback, JSONObject PostData) {
//To authenticate against the API we need the user's credentials
String Email = getSharedPreferences(ctx).getString("Email","");
String Password = getSharedPreferences(ctx).getString("Password","");
final JSONArray[] ResponseStorage = new JSONArray[1];
//Add the credentials to post data
try{
PostData.put("email", Email);
PostData.put("password", Password);
} catch (Exception e){
e.printStackTrace();
}
//Then we need to put the post data into request parameters so we can send them in the call.
RequestParams RequestParameters = new RequestParams();
RequestParameters.put("data", PostData);
//This is the client we will use to make the request.
AsyncHttpClient client = new AsyncHttpClient();
client.post(AppHost + "MyMeetings.php", RequestParameters, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
try {
String ResponseString = new String(responseBody);
ResponseStorage[0] = new JSONArray(ResponseString);
System.out.println(ResponseStorage[0] + "<============="); //Returns with the array
callback.onJSONResponse(true, ResponseStorage[0]);
} catch (Exception e) {
Log.e("Exception", "JSONException on success: " + e.toString());
}
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
try {
Toast.makeText(ctx, "Error: " + statusCode, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Log.e("Exception", "JSONException on failure: " + e.toString());
}
}
});
JSONArray ResponseArray = new JSONArray();
try{
System.out.println(ResponseStorage[0] + "<==============="); //Returning null?
ResponseArray = ResponseStorage[0];
} catch (Exception e){
e.printStackTrace();
}
System.out.println("ResponseArray" + ResponseArray); //Returns null
return ResponseArray;
}
Where am I going wrong? I think it is something to do with my call in the main method.
Edit:
1) I tried to return the ResponseArray (set in onsuccess) but I can't return it from onsuccess because it is public void. When I tried to change it to public JSONArray, I get an incompatible return type error.
2) I have updated the method so it returns something other than null, however, it still returns as null, even when I am printing it inside the AsyncHttp.
The general idea behind the asynchronous calls is that:
the asynchronous method call (in your case PerformPostRequest) returns immediately and does not return the expected result - instead it returns either just an accept confirmation or an object from which you can sometimes in the future get the result (such as an instance of a Future)
you provide the method a callback interface (in your case OnJSONResponseCallback) or the method returns an instance of a callback interface, and you check regularly if there is already a result ready.
You should not expect that the asynchronous method returns the result immediately, this is exactly the opposite of asynchronous call.
Here is the rough idea expressed by pictures. It is just an overall picture of the whole idea, so the implementation details may be quite different!
I was trying to set the variable from the PerformPostRequest(), which by default does not get called. At the top of my class, I set a
public JSONArray[] PostResponse = new JSONArray[1];
and updated the bit where I was calling the post request to the following:
//Make a post request
try {
JSONObject PostData = new JSONObject();
PostData.put("action","test");
PerformPostRequest(new OnJSONResponseCallback(){
#Override
public JSONArray onJSONResponse(boolean success, JSONArray response) {
PostResponse[0] = response;
System.out.println(PostResponse[0]); //This will be replaced by calling the method I want to call.
return PostResponse[0];
}
}, PostData);
System.out.println(PostResponse[0]);
} catch (Exception e){
e.printStackTrace();
}

HttpClient Replicate in Java from C# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have an Android project built in Xamarin (.NET) I wish to convert to native Java. In the Xamarin app I have built an API class used to access HTTP data utilising Generics, which looks like this:
public class InventoryAPI {
HttpClientHandler handler;
Uri baseAddress;
HttpClient client;
public InventoryAPI() {
// .. Init code here
}
public async Task<Response> EnrolMultipleItemsAsync(EnrolItemModel[] _items) {
try {
var result = await PostAsync<Response>("api/inventory/enrolmultipleitems", _items);
Console.WriteLine(result.Message);
return result;
}
catch (Exception ex) {
App.Current.Logger.LogInfo("Exception at InventoryAPI - Error: EnrolItemAsync:");
App.Current.Logger.LogError(ex.Message);
throw ex;
}
}
public Response EnrolMultipleItems(EnrolItemModel[] _items) {
try {
var result = Post<Response>("api/inventory/enrolmultipleitems", _items);
return result;
}
catch (Exception ex) {
App.Current.Logger.LogInfo("Exception at InventoryAPI - Error: EnrolItem:");
App.Current.Logger.LogError(ex.Message);
throw ex;
}
}
private async Task<T> PostAsync<T>(string apiLocation, object postData) {
var response = await client.PostAsync(apiLocation, postData.ToHttpContentString());
T result = default(T);
if (response.StatusCode == HttpStatusCode.OK) {
var json = await (response.Content.ReadAsStringAsync());
result = DeserializeJson<T>(json);
}
return result;
}
private T Post<T>(string apiLocation, object postData) {
var response = client.PostAsync(apiLocation, postData.ToHttpContentString()).Result;
T result = default(T);
if (response.StatusCode == HttpStatusCode.OK) {
var json = response.Content.ReadAsStringAsync().Result;
result = DeserializeJson<T>(json);
}
return result;
}
public T DeserializeJson<T>(string json) {
var parsed = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(json);
return parsed;
}
}
I like this style of API and it has worked well in the Xamarin app, so now I wish to port this to Java - and here's where I'm stuck!
Here's what I have so far:
public class APIDownloader extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... ts) {
String url = ts[0].toString();
return Get(url);
}
private String Get(String url) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
HttpEntity entity = null;
String result = "";
try {
//Execute and get the response.
HttpResponse response = httpclient.execute(httpget);
entity = response.getEntity();
if (entity != null) {
result = EntityUtils.toString(entity);
//final JSONArray jObject = new JSONArray(EntityUtils.toString(entity));
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Catch no internet connectivity exception
e.printStackTrace();
}
return result;
}
}
And then a separate API class:
public class InventoryAPI {
public List<LocationModel> GetAllLocations() throws IOException {
String url = "https://domain.com/api/inventory/getall";
String response = null;// Get(url);
try {
response = new APIDownloader().execute(url).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
Gson gson = new Gson();
LocationModel[] mcArray = gson.fromJson(response, LocationModel[].class);
return Arrays.asList(mcArray);
}
}
Whilst the Java code above does work just fine (I've only implemented the GET so far) it does seem like it's going to get out of hand very quickly, especially after I port the POST methods in the C# library to the Java package.
What would be the best approach to replicate the Xamarin API Class I have above in Java?
If you're going to go native Java then do yourself a favor and use Retrofit. That will save you a ton of code in your API layer. Regular Java Http stuff is ugly, Retrofit makes it much easier.
When you get comfortable, look at RxAndroid (RxJava) to really help with some of your Async code.

java try catch and return

I have a small function in java that does a HTTP POST, and returns a JSON Object. This function return the JSON Object.
public JSONObject send_data(ArrayList<NameValuePair> params){
JSONObject response;
try {
response = new JSONObject(CustomHttpClient.executeHttpPost(URL, params).toString());
return response;
} catch(Exception e) {
// do smthng
}
}
This shows me an error that the function must return a JSONObject. how do i make it work? I cant send a JSONObject when there is an error, can I? It would be useless to send a blank jsonobject
This is because you are only returning a JSONObject if everything goes smoothly. However, if an exception gets thrown, you will enter the catch block and not return anything from the function.
You need to either
Return something in the catch block. For example:
//...
catch(Exception e) {
return null;
}
//...
Return something after the catch block. For example:
//...
catch (Exception e) {
//You should probably at least log a message here but we'll ignore that for brevity.
}
return null;
Throw an exception out of the method (if you choose this option, you will need to add throws to the declaration of send_data).
public JSONObject send_data(ArrayList<NameValuePair> params) throws Exception {
return new JSONObject(CustomHttpClient.executeHttpPost(URL, params).toString());
}
You could change it to this:
public JSONObject send_data(ArrayList<NameValuePair> params){
JSONObject response = null;
try {
response = new JSONObject(CustomHttpClient.executeHttpPost(URL, params).toString());
} catch(Exception e) {
// do smthng
}
return response;
}
There's a path through the function that doesn't return anything; the compiler doesn't like that.
You can change this to
catch(Exception e) {
// do smthng
return null; <-- added line
}
or put the return null (or some reasonable default value) after the exception block.
It's reasonble to return 'something' even in an error condition.
Look at JSend for a way to standardize your responses - http://labs.omniti.com/labs/jsend
In my opinion it's easiest to return an error json object and handle that on the client side then to solely rely on HTTP error codes since not all frameworks deal with those as well as they could.
The send_data() method should throw an exception so that the code calling send_data() has control over how it wants to handle the exception.
public JSONObject send_data(ArrayList<NameValuePair> params) throws Exception {
JSONObject response = new JSONObject(CustomHttpClient.executeHttpPost(URL, params).toString());
return response;
}
public void someOtherMethod(){
try{
JSONObject response = sendData(...);
//...
} catch (Exception e){
//do something like print an error message
System.out.println("Error sending request: " + e.getMessage());
}
}
I prefer one entry and one exit. Something like this seems reasonable to me:
public JSONObject send_data(ArrayList<NameValuePair> params)
{
JSONObject returnValue;
try
{
returnValue = new JSONObject(CustomHttpClient.executeHttpPost(URL, params).toString());
}
catch (Exception e)
{
returnValue = new JSONObject(); // empty json object .
// returnValue = null; // null if you like.
}
return returnValue;
}

Categories

Resources