Wish Automatic unique base temp folder for jOkHttpUtils2

OliverA

Expert
Licensed User
Longtime User
I wish for jOkHttpUtils2 to use a unique base temp folder.

Why?

Because without a unique base temp folder, multiple applications written in B4J that run on the same user account / OS / machine and are using HttpJob to make HTTP calls can cross access each other's temp folder or block each other's temp folder (used in processing the HTTP calls). I'm attaching a test server and test client to demonstrate the issue.


Here are some of the common issues that can occur:
A)
(Client 7:Tootie) Exception occurred: java.io.FileNotFoundException: C:\Users\xxxxxxxx\AppData\Local\Temp\15 (The process cannot access the file because it is being used by another process)
java.lang.RuntimeException: java.io.FileNotFoundException: C:\Users\xxxxxxxxx\AppData\Local\Temp\33 (Access is denied)

Both of the above are attempts of one process to access another process's temp folder created/managed by jOkHttpUtils2

B)
It gets even weirder. Apps can actually access and/or overwrite each other's information that is returned by jOkHttpUtils2.
(Client 10:Veronica) Message returned: Hello Veronica
(Client 10:Veronica) Message returned: Hello Veronica
(Client 10:Veronica) Message returned:
(Client 10:Veronica) Message returned: Hello Trixieca
(Client 10:Veronica) Message returned: Hello Trixieca
(Client 10:Veronica) Message returned: Hello Tootie
(Client 10:Veronica) Exception occurred: java.io.FileNotFoundException: C:\Users\xxxxxxxxx\AppData\Local\Temp\7 (The process cannot access the file because it is being used by another process)
Received 4 incorrect messages. Incorrect received messages included:

Hello Trixieca
Hello Tootie
For the above output, I'm sending Veronica to the server and the server replies with Hello Veronica, and jOkHttpUtils2 writes the answer out to a file in the temporary directory it has created for that session. But on occasion, the current process is accessing some other processes temp folder (Hello Tootie) or another process overwrote the data of the current process (Hello Trixieca, where Hello Trixie overwrites Hello Veronica). On other occasions, I'm not sure if the process is accessing another temp folder or if the currents temp folder was manipulated by another process (where the message is blank). This is on top of the "process cannot access the file because it is being used by another process" issue.

For the A) and B) above, I ran the included spawnclients.cmd file and let it start 10 clients, for 10 seconds, with 10 milliseconds between each HTTP call, and not applying the fix. If you want to try this on your system, extract the attached file. Run the server in release mode and keep it running. Run the Client_NonUI once in release mode and kill the process. Then, in a command prompt, run the included spawnclients.cmd file. The batch file will ask for the number of clients to create, for how many seconds to run, how many milliseconds to separate each HTTP call, and if a fix should be applied (see below).

Right now, the solution is to set up a unique temporary folder for each application that uses jOkHttpUtils2. This is accomplished by setting the
B4X:
HttpUtils2Service.TempFolder
to a unique value.

One way this can be accomplished is by using @Erel's GUID code (https://www.b4x.com/android/forum/threads/b4x-guid.99529/):
B4X:
            Dim guidFolder As String = GUID
            File.MakeDir(File.DirTemp, guidFolder)
            HttpUtils2Service.Service_Create
            HttpUtils2Service.TempFolder = File.Combine(File.DirTemp, guidFolder)
This code needs to be placed before the first HTTP call.

This method is used in the test client and can be activated using the spawnclients.cmd batch file by answering the "Apply TempFolder fix?" with Y.

Notes:
0) This is a client only issue. The server returns the correct responses. It's the client processing the returned values that is messing up. And with client I mean the underlying client HTTP library that is implemented by jOkHttpUtils2.
1) This only applies the B4J code section of the library that deals with the TempFolder.
2) It could also affect the jServer portion, even using/activating the thread safe code path of the library, if more than one jServer application is running on the same account / OS / machine (untested).
3) I initially bumped into this, and so did @Diceman back in 2019 (see https://www.b4x.com/android/forum/t...session-id-in-jrdc2-client.108642/post-686343), but I did not spend any more time investigating, since the issue only seemed to occur during testing. @Diceman seemed to have a good guess as to what may be happening then (https://www.b4x.com/android/forum/t...session-id-in-jrdc2-client.108642/post-686351)
 

Attachments

  • HttpJobTmpTest.zip
    141.2 KB · Views: 130

Chris2

Active Member
Licensed User
Longtime User
I've been playing with pre-setting a unique base temp folder for each app as described here, but am finding that it seems to cause more frequent java.io.FileNotFoundException errors.
For example, after implementing the code:
B4X:
Dim guidFolder As String = GUID
File.MakeDir(File.DirTemp, guidFolder)
HttpUtils2Service.Service_Create
HttpUtils2Service.TempFolder = File.Combine(File.DirTemp, guidFolder)

Then overnight having four apps running that all connect to a jRDC2 based app using jOkHttpUtils2 V3.02, three of the apps errored with java.io.FileNotFoundException errors as shown below:
2023-10-18 00:44:18.244
(FileNotFoundException) java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\344784D4-EB19-A2FA-17A7-0D751A6B8141\69003 (The system cannot find the path specified)

java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\344784D4-EB19-A2FA-17A7-0D751A6B8141\69003 (The system cannot find the path specified)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(Unknown Source)
at java.base/java.io.FileOutputStream.<init>(Unknown Source)
at b4j/anywheresoftware.b4a.objects.streams.File.OpenOutput(Unknown Source)
at b4j/newfoundenergy.atlas.atlasems.httputils2service._hc_responsesuccess(Unknown Source)
at jdk.internal.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
at b4j/anywheresoftware.b4a.BA$3.run(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(Unknown Source)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
2023-10-17 23:44:06.676
(FileNotFoundException) java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\1A280263-4131-6AFD-1410-24D1E666253C\55078 (The system cannot find the path specified)

java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\1A280263-4131-6AFD-1410-24D1E666253C\55078 (The system cannot find the path specified)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(Unknown Source)
at java.base/java.io.FileOutputStream.<init>(Unknown Source)
at b4j/anywheresoftware.b4a.objects.streams.File.OpenOutput(Unknown Source)
at b4j/newfoundenergy.atlas.comms.httputils2service._hc_responsesuccess(Unknown Source)
at jdk.internal.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
at b4j/anywheresoftware.b4a.BA$3.run(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(Unknown Source)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
2023-10-18 03:30:46.544
(FileNotFoundException) java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\D173FCE7-B312-D84C-5CE7-8706C01BA167\3485 (The system cannot find the path specified)

java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\D173FCE7-B312-D84C-5CE7-8706C01BA167\3485 (The system cannot find the path specified)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(Unknown Source)
at java.base/java.io.FileOutputStream.<init>(Unknown Source)
at b4j/anywheresoftware.b4a.objects.streams.File.OpenOutput(Unknown Source)
at b4j/newfoundenergy.atlas.atlasreprunner.httputils2service._hc_responsesuccess(Unknown Source)
at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
at b4j/anywheresoftware.b4a.BA$3.run(Unknown Source)
at b4j/anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(Unknown Source)
at b4j/anywheresoftware.b4a.StandardBA.startMessageLoop(Unknown Source)
at b4j/anywheresoftware.b4a.keywords.Common.StartMessageLoop(Unknown Source)
at b4j/newfoundenergy.atlas.atlasreprunner.main._appstart(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent(Unknown Source)
at b4j/newfoundenergy.atlas.atlasreprunner.main.main(Unknown Source)

2023-10-18 03:30:46.578
(RuntimeException) java.lang.RuntimeException: java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\D173FCE7-B312-D84C-5CE7-8706C01BA167\3485 (The system cannot find the path specified)

java.lang.RuntimeException: java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\D173FCE7-B312-D84C-5CE7-8706C01BA167\3485 (The system cannot find the path specified)
at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
at b4j/anywheresoftware.b4a.BA$3.run(Unknown Source)
at b4j/anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(Unknown Source)
at b4j/anywheresoftware.b4a.StandardBA.startMessageLoop(Unknown Source)
at b4j/anywheresoftware.b4a.keywords.Common.StartMessageLoop(Unknown Source)
at b4j/newfoundenergy.atlas.atlasreprunner.main._appstart(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent2(Unknown Source)
at b4j/anywheresoftware.b4a.BA.raiseEvent(Unknown Source)
at b4j/newfoundenergy.atlas.atlasreprunner.main.main(Unknown Source)
Caused by: java.io.FileNotFoundException: C:\Users\Chris\AppData\Local\Temp\D173FCE7-B312-D84C-5CE7-8706C01BA167\3485 (The system cannot find the path specified)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(Unknown Source)
at java.base/java.io.FileOutputStream.<init>(Unknown Source)
at b4j/anywheresoftware.b4a.objects.streams.File.OpenOutput(Unknown Source)
at b4j/newfoundenergy.atlas.atlasreprunner.httputils2service._hc_responsesuccess(Unknown Source)
at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
... 13 more

Under similar testing prior to adding in the code to manually set HttpUtils2Service.TempFolder, I did encounter the errors decribed in post #1 on one occassion, but not as frequently as this.
Could the suggested wish be causing this issue?
 
Last edited:

Chris2

Active Member
Licensed User
Longtime User
Are all apps located on the same path?
I'm not sure what you mean by this. Are you asking if the built executables/packages are all in the same installation folder?
Sorry, I understand now that you're checking that File.DirApp is not the same for all the apps.
If not then set TempFolder to File.DirApp\"Temp"
Should the quotes be included in the folder name?
Sorry, stupid question - folder names can't contain quotes.

Edit: I should realise that I've got to an age where I need to let what I read absorb for 5 minutes before questioning it. I'll give the suggestion a go, thanks.
 
Last edited:

Chris2

Active Member
Licensed User
Longtime User
Are all apps located on the same path? If not then set TempFolder to File.DirApp\"Temp"

Maybe the system does something with the temporary folders.
I made a slight change to your suggestion @Erel, and set
B4X:
HttpUtils2Service.TempFolder = File.Combine(File.DirData(appName), guidFolder)
After running the same test I did in post #3 I've had no errors after two days of running four apps.

Obviously this is only a limited test, done by one person, but based on this (and subject to further testing by anyone else who wants to test this), I'd suggest an amendment to @OliverA's wish to avoid putting the temp folder created by jOkHttpUtils2 in File.DirTemp (daft as it may seem!).
 
Top