Null pointer error in dev console

Kevin

Well-Known Member
Licensed User
Longtime User
Quite some time ago I was getting null pointer errors in my dev console and I figured out the problem and they went away.

But now I have seen a few of them again in a more recent version.

The obfuscated sub is ProcessNextTask (in HTTPUtils). Naturally I have never seen this error on my phone, so I have no idea what the circumstances were. Of the 3 error reports I have, only one bothered to add a comment:

"happy"


Unfortunately that didn't help narrow it down. :rolleyes:

All three are identical so I am only showing one here.

java.lang.RuntimeException: java.lang.NullPointerException
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:153)
at anywheresoftware.b4a.BA$1.run(BA.java:218)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.cognitial.directvremote.httputilsservice._vvvvvvvvvvvvvvvvvvvvvvvvv2(httputilsservice.java:201)
at com.cognitial.directvremote.httputilsservice._hc_responseerror(httputilsservice.java:140)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:113)
 

Kevin

Well-Known Member
Licensed User
Longtime User
Maybe the comment was obfuscated as well ???

:sign0142: I actually laughed out loud!


I'm at work so I can't look up that line right now but I'll look into this some more when I get home. If nothing jumps out at me I'll post an update.
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
Maybe the comment was obfuscated as well ???

It happened after there was a communication error (after hc_ResponseError was called).
Can you post line 201 from the java source code of HttpUtilsService?


B4X:
200  //BA.debugLineNum = 60;BA.debugLine="If HttpUtils.Working = False Then";
201  if (mostCurrent._vvvvvvvvvvvvvvvvvv6._vvv5==anywheresoftware.b4a.keywords.Common.False) { 
202  //BA.debugLineNum = 61;BA.debugLine="StopService(\"\")";
203  anywheresoftware.b4a.keywords.Common.StopService(processBA,(Object)(""));
204   };
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
I've slightly modified my httputils service code:

B4X:
'Version 1.04
Sub Process_Globals
Dim hc As HttpClient
Dim task As Int
Dim countWorking As Int
Dim finishTasks As Int
Dim maxTasks As Int
maxTasks = 8 ' was 10.... trying to eliminate RejectedExecutionException errors in crash logs.
Dim taskToRequest As Map
Dim TempFolder As String
Dim Post As Boolean
Dim PostBytes() As Byte
Dim PostInputStream As InputStream
Dim PostLength As Int
Dim hcIsInitialized As Boolean
 
' NEW
Dim TimerDelay As Timer
End Sub
 
Sub Service_Create
If TempFolder = "" Then TempFolder = File.DirInternalCache
If hcIsInitialized = False Then
hc.InitializeAcceptAll("hc")
'hc.SetHttpParameter ("","")
hcIsInitialized = True
End If
If Main.httpUtilsDelay <> 0 Then
TimerDelay.Initialize ("TimerDelay",Main.httpUtilsDelay)
Else
TimerDelay.Initialize ("TimerDelay",1500)
End If
End Sub
 
Sub Service_Start
If HttpUtils.Tasks.IsInitialized = False Then Return
taskToRequest.Initialize
finishTasks = 0
task = 0
countWorking = 0
Do While task < HttpUtils.Tasks.Size
ProcessNextTask
If countWorking >= maxTasks Then Exit
Loop
End Sub
 
Sub TimerDelay_tick
TimerDelay.Enabled = False
ProcessNextTask
End Sub
 
Sub ProcessNextTask
If finishTasks >= HttpUtils.Tasks.Size Then
HttpUtils.Working = False
HttpUtils.Complete = True
'Raise job done event
If HttpUtils.CallbackJobDoneSub <> "" Then
CallSub2(HttpUtils.CallbackActivity, HttpUtils.CallbackJobDoneSub, HttpUtils.Job)
End If
'If no new job was started then we kill this service.
If HttpUtils.Working = False Then
StopService("")
End If
Return
End If
If task >= HttpUtils.Tasks.Size Then Return
Dim link As String
link = HttpUtils.Tasks.Get(task)
Dim req As HttpRequest
If Post Then
If PostInputStream.IsInitialized Then
req.InitializePost(link, PostInputStream, PostLength)
Else
req.InitializePost2(link, PostBytes)
End If
Else
req.InitializeGet(link)
End If
req.Timeout = 45000 ' Timeout in milliseconds
'Here you can modify the request object if needed
countWorking = countWorking + 1
taskToRequest.Put(task, link)
hc.Execute(req, task)
task = task + 1
End Sub
 
Sub hc_ResponseSuccess (Response As HttpResponse, TaskId As Int)
Response.GetAsynchronously("response", File.OpenOutput(TempFolder, TaskId, False), _
True, TaskId)
End Sub
 
Sub Response_StreamFinish (Success As Boolean, TaskId As Int)
finishTasks = finishTasks + 1
countWorking = countWorking - 1
If Success = False Then
HandleError(TaskId, LastException.Message)
Else
HttpUtils.SuccessfulUrls.Put(taskToRequest.Get(TaskId), TaskId)
'Raise URL done event
If HttpUtils.CallbackUrlDoneSub <> "" Then
CallSub2(HttpUtils.CallbackActivity, HttpUtils.CallbackUrlDoneSub, taskToRequest.Get(TaskId))
End If
End If
'ProcessNextTask
TimerDelay.Enabled = True
End Sub
 
Sub hc_ResponseError (Response As HttpResponse, Reason As String, StatusCode As Int, TaskId As Int)
countWorking = countWorking - 1
finishTasks = finishTasks + 1
HandleError(TaskId, Reason)
If Response <> Null Then
Try
Log(Response.GetString("UTF8"))
Catch
Log ("Could not decode response.")
End Try
Try
Response.Release
Catch
End Try
End If
ProcessNextTask
End Sub
 
Sub HandleError(TaskId As Int, Reason As String)
Dim link As String
link = taskToRequest.Get(TaskId)
'Log("Error. Url=" & link & " Message=" & Reason)
 
'Enable logging above to see URLs that fail (such as when scanning for STBs)
End Sub
 
Sub Service_Destroy
HttpUtils.Working = False
End Sub

Mostly I added a time delay after a successful download. My reason was I thought it might make my scans more reliable. What it is doing is sending an HTTP request to every possible IP address on the network and looking for a valid response from a satellite receiver. I figured putting a delay in there after a successful attempt would give the app some time to process the info as well as prevent the network / router from being overloaded with too many HTTP requests to sift through. At one point I added a delay after a failure too but that was a disaster. It took the app forever to go through all IP addresses (as you would expect) since most requests would fail (+/- 255 requests). Unfortunately I didn't think of that until people complained about how sloooooow it had gotten. :eek:

But anyway, does anything stand out?

Another question: my app uses 3 services, all based off of HTTPUTILS. I changed some variables in order to try and avoid conflicts, but not all of them. Theoretically only one service should be in use at a time but it is possible for people to get impatient and try doing a bunch of stuff too quickly which I suspect could cause issues.

An example of some things I have changed. These are all the same HttpUtils.Working thing, but named differently in each service module:

B4X:
HttpUtils.Working = False (original HTTPUTILS service)
 
MacroBlaster.WorkingMacro = False (one variation of the service)
 
GD.WorkingGD = False (the other variation of the service).



The subtle name changes were to help me remember what went where and of course to avoid any possible conflicts.


BUT, I was just wondering about this:


B4X:
Sub Process_Globals
Dim hc As HttpClient
Dim task As Int
Dim countWorking As Int
Dim finishTasksGD As Int
Dim maxTasksGD As Int
maxTasksGD = 8 ' was 10.... trying to eliminate RejectedExecutionException errors in crash logs.
Dim taskToRequest As Map
Dim TempFolder As String
Dim Post As Boolean
Dim PostBytes() As Byte
Dim PostInputStream As InputStream
Dim PostLength As Int
Dim hcIsInitialized As Boolean
 
End Sub

In all three of my custom services, I did NOT change the names of variables in the Process_Globals subs. My thought was that each service is its own process and therefore there should be no conflicts, but now I am wondering if I should maybe change them all. Are process globals found in ALL modules of an app truly process-wide and available from all other modules, even service modules?

I could do something like:

B4X:
Sub Process_Globals
Dim hc1 As HttpClient
Dim task1 As Int
Dim countWorking1 As Int
Dim finishTasksGD1 As Int
Dim maxTasksGD1 As Int
maxTasksGD1 = 8 ' was 10.... trying to eliminate RejectedExecutionException errors in crash logs.
Dim taskToRequest1 As Map
Dim TempFolder1 As String
Dim Post1 As Boolean
Dim PostBytes1() As Byte
Dim PostInputStream1 As InputStream
Dim PostLength1 As Int
Dim hcIsInitialized1 As Boolean
 
End Sub

To keep them all unique. Or is that overkill?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
HttpUtils is pretty complicated. It is hard to say what will be the effects of this timer.

I think that you can just remove the timer. There are never more then MaxTasks calls at a time.

Did you create 3 copies of the service and code module? It should work fine as long as you make sure that each service points to the correct code module.
You do not need to change any variable name. There are no conflicts as each variable is declared in its own module.

You should set MaxTasks to 6 as you don't want to have more than 20 tasks running at the same time (it will cause the exception).
 
Upvote 0

Kevin

Well-Known Member
Licensed User
Longtime User
I haven't seen a report of RejectedExecutionException in quite a while.

Yes, there are three copies of the services (service and associated code module). Good to know that shouldn't cause any conflicts.

I just can't figure out the source of the null pointer exception. I don't see too many crash reports (hopefully a good sign) but I have seen 3 of these all with the latest version and within a couple weeks of each other. It's enough to make me worry that there is a problem I need to fix but unfortunately I can't duplicate it.
 
Upvote 0
Top