Creating temporary JNIEnv. This is a heavy operation and should be infrequent. To optimize, use JNI AttachCurrentThread on calling thread

Getting this error on a new headset with the vr starter template probably every frame:

OpenXR_Actions: -------- xrStopHapticFeedback ----------
OpenXR_Actions: -------- xrStopHapticFeedback ----------
Creating temporary JNIEnv. This is a heavy operation and should be infrequent. To optimize, use JNI AttachCurrentThread on calling thread

I can’t find anything on google about this, any ideas?
I have the full log but I assume there’s sensitive information in there so i’d rather send it directly to a forum moderator/epic employee.

I decided to check if building ue from source on ue5-main would help with this problem but the log spam persists.

Also at first source-built ue with the VR starter template would show a completely black level with completely white quest 2 controllers(tracking was fine) when deployed to the quest 2 but the editor viewport was completely fine. A few meshes did have a texture(the ball and the yellow squares on the table) and the sky worked fine.

Compiling Lightmass through visual studio and then building lighting in the editor did nothing. Only when I switched the editor to Vulkan instead of DX12(DX11 had the same problems) and then deploying to the quest 2 was the situation resolved and lighting properly restored. Also now switching back to DX12, the deployed level still looks good.

I’ve never seen this. Which HMD and runtime are you using?

What OS and GPU are you using? I haven’t seen this in source or binary builds. Building lighting with DX12 and Instanced Stereo = True has issues. You can either switch to DX11, or disable Instanced Stereo. This has been fixed and will ship with Binary 5.0.2, but fix is already on UE5-Main.

So regarding the xrStopHapticFeedback spam, its relatively easily “fixed” by overriding UpdateForceFeedback in a custom PlayerController and not immediately returning. Somehow SetDisableHaptics(New Disabled: True) and ForceFeedbackEnabled(False), still makes calls to UpdateForceFeedback, which in turn causes the log spam. Obviously this disables force feedback though.

The more important issue regarding

Creating temporary JNIEnv. This is a heavy operation and should be infrequent.

In the logs I see a process id of 31940 and in the Perfetto logs this corresponds to the Unreal RenderThread, I would’ve expected it to refer to some oculus process, not the RenderThread. Especially because I can’t find any reference to it in the Engine source, neither in epic’s branch nor the Oculus one. I have no idea what i’m doing regarding performance traces, but I see no mentions of JNI calls during a frame and of the calls there, nothing sticks out as particularly “heavy”.

@VictorLerp Could you shed some more light regarding the JNI log string, have you encountered this and should it be ignored?

I’ve never seen this. Which HMD and runtime are you using?

Quest 2 and the default selected “Native OpenXR with vendor extensions”.

What OS and GPU are you using?

Windows 11 - Version 10.0.22000 Build 22000
Nvidia 2070 Super

Just to check I created a new project in the src-built unreal, without touching any of the settings. Building lighting worked fine but it refused to launch at first with:

LogPlayLevel: Warning: UAT: LogCook: Warning: Cooker has been blocked from saving the current packages for 120.000000 seconds.
LogPlayLevel: UAT: LogCook: Display: 1 packages in the savequeue:
LogPlayLevel: UAT: LogCook: Display:     /Game/VRTemplate/Maps/VRTemplateMap_BuiltData
LogPlayLevel: UAT: LogCook: Display: 3 objects that have not yet returned true from IsCachedCookedPlatformDataLoaded:
LogPlayLevel: UAT: LogCook: Display:     LightMapTexture2D /Game/VRTemplate/Maps/VRTemplateMap_BuiltData.VRTemplateMap_BuiltData:HQ_Lightmap0_7
LogPlayLevel: UAT: LogCook: Display:     LightMapTexture2D /Game/VRTemplate/Maps/VRTemplateMap_BuiltData.VRTemplateMap_BuiltData:HQ_Lightmap0_6
LogPlayLevel: UAT: LogCook: Display:     LightMapTexture2D /Game/VRTemplate/Maps/VRTemplateMap_BuiltData.VRTemplateMap_BuiltData:HQ_Lightmap0_5
LogPlayLevel: UAT: LogCook: Display: Cooked packages 462 Packages Remain 1 Total 463
LogPlayLevel: UAT: LogCook: Display: Cook Diagnostics: OpenFileHandles=465, VirtualMemory=976MiB

I counted 13x in my logs before I killed it(I still have the logs). I then retried the build and the result was the same, again hanging on the Warning: Cooker has been blocked .

Restarting Unreal and building again caused it to compile everything over again([840/840]) and this time it succeeded but instead of being deployed to the quest it popped up in windows desktop(Quest must have went into standby I guess).

Finally retrying again deployed it correctly on the quest with correct graphics. I can’t tell you why I had the initial black and white graphics, maybe it’s an cache issue somewhere or maybe like you said I enabled Instanced Stereo right at the start and if I recompiled Unreal completely from scratch it might happen again but this takes too long and I’m much more interested in the JNI issue.

I’m also getting the JNI temp thread issue on 4.27 on a Quest 2. It’s killing my game.

For my current projects, and a new one I just tested I’m not getting temp JNIENV When I build a project from the Oculus 4.27 branch by following the oculus unreal quick start guide. Based on this other project that uses the native oculus VR SDK (OVRSDK), it looks like the JNIENV is an issue specifically with the oculus VR SDK and android, not the unreal or unity implementation. The “fix” would be to do as the log states, to use JNI AttachCurrentThread on calling thread. Searching that yields some results that are not at all in the unreal context. So even if it was figured out how to do that, who knows if it could break packaging to android. While Quest 2 technically works on launcher and source 4.27/UE5, it’s not officially supported by oculus, so you may run into technical issues like these that may be extremely difficult to solve on your own. Unless there is something specifically in vanilla ue4.27 or 5.0 that your project absolutely depends on, then it would probably be best to stick with the Oculus maintained fork of 4.27, as that is the version of unreal engine that is intended to be used with the quest 2

1 Like

Do you have a link to that fork?

Oculus maintained unreal engine 4.27: https://github.com/Oculus-VR/UnrealEngine/tree/4.27
There is a 5.0 but it’s is missing features and stability from 4.27

Oculus getting started prerequisites guide: Getting Started Developing Unreal Engine Apps for Quest: Unreal | Oculus Developers
Shows you how to download oculus developer hub in prep to submit content to oculus store, the developer app has lots of useful options to toggle on the quest

Oculus getting started creating a project guide: Creating Your First Oculus Quest VR App in Unreal Engine: Unreal | Oculus Developers
these are just steps for setting the settings required for starting a new project

These functions are definitely present in the source of UE:

AndroidJavaEnv.cpp:40
const jint AttachResult = CurrentJavaVM->AttachCurrentThread(&CachedEnv, nullptr);
AndroidJavaEnv.cpp:131
jint AttachResult = CurrentJavaVM->AttachCurrentThread(&Env, &Args);
AndroidJavaEnv.cpp:167
jint AttachResult = CurrentJavaVM->AttachCurrentThread(&Env, &Args);
AndroidPlatformMemory.cpp:37
jint AttachThreadResult = GJavaVM->AttachCurrentThread(&Env, NULL);

The GetEnv calls are roughly in the same locations in those files.
Definitely thanks for checking if it was happening on your projects.

Right, yes it is in the unreal source which judging from those snippets looks like its not a OVR problem but a problem with androids implementation in unreal engine. You won’t get that fixed on launcher 4.27/5.0, and the source versions would require being a game engine/android engineer. If you want the performance gains, and to not have this JNIENV issue, Oculus has this fixed on their 4.27 fork, but you have to make sure to follow both the prerequisites guide and the project quick start guide (in that order) as you may have missed installing something for android that’s requiring, therefore needing to creating this temporary JNIENV to make up for whatever is missing. This is a low level issue that only a company with a use case (oculus running unreal on quest 2) can fix. In addition to that (correct me if I’m wrong here) I’m actually not sure you can submit a non-app-lab app to oculus store without building it from their fork of unreal engine, since it may fail some oculus specific checks, and the standard unreal doesn’t have an oculus entitlement check to my knowledge. Any reason in particular why you don’t want to use the 4.27 oculus fork?

That seems unlikely, missing prerequisites would just fail the initial build.

A bunch of interesting features in 5.0(Mass and Lyra specifically).

I spent quite some time trying to debug the problem but I’m very early in my project so I’d rather just work on that and patiently wait while Oculus has their 5.0 branch working correctly.

@Antidamage Can hopefully inform us if switching to the Oculus branch fixed the problem.