Android: "This file is not part of the project"

Hey everyone,

I am having a problem with the build of the Android version of my app.

The debug output says:

juce::getEnv() juce_Threads_android.cpp:0
juce::getAppDataDir(bool) juce_Files_android.cpp:811
juce::File::getSpecialLocation(juce::File::SpecialLocationType) juce_Files_android.cpp:828
::__cxx_global_var_init.187() file_locations.h:84
_GLOBAL__sub_I_component_meter.cpp component_meter.cpp:0

The LogCat:

JUCE Assertion failure in juce_Threads_android.cpp:67

JUCE Assertion failure in juce_Threads_android.cpp:67

JUCE Assertion failure in juce_Threads_android.cpp:308

This code window opens with the error message:

and in the file java.java (juce.code) line 46

public native static void initialiseJUCE (Context appContext);

initialiseJUCE : Cannot resolve corresponding JNI function Java_com_rmsl_juce_Java_initialiseJUCE.

My diagnosis: JUCE is not initialised. But Why?

So far, I have checked the following:

  • juce_Threads_android.cpp is listed in the project files. (And yet the error is still displayed above).

  • JuceApp.java → Java.initialiseJUCE (this); is called. (checked with a break point)

  • no more old “com.roli.juce” packages are used

    Im using
    Juce: 8.0.10
    Android Studio Narwhal 3 Feature Drop | 2025.1.3

Does anyone else know about this problem and can perhaps help me figure out where the problem might be? Thankx

There’s a few things going on here:

  • Firstly, the debug output. This is showing a stack trace to a getEnv() call during global initialisation. It looks like you have a static/global variable in the component_meter.cpp file that attempts to query the app data directory. However, this global initialisation will fail if it happens before the call to initialiseJUCE(). I recommend taking a look at this file and delaying any calls to File::getSpecialLocation() until you’re certain that the app has successfully initialised.
  • The logcat output is showing you some assertions that failed at runtime. Normally, assertions like these have an accompanying comment explaining potential causes of the problem. In this case, the comment for the first assertion explains that initialiseJUCE() hasn’t been called (yet).
  • The error message banner in Android Studio is harmless. JUCE Android projects are a bit complicated, and Android Studio can’t always index them successfully. The “cannot resolve corresponding JNI function” warning has the same root cause, and is also harmless.

It sounds like initialiseJUCE() is getting called eventually. The problem is that it needs to be called early on, before any other JUCE APIs are called. The best way to ensure this is to avoid declaring static/global variables that invoke JUCE functions in their constructors, and to delay such calls instead.

Thank you for this information!
I have a question about this:

Is there an event/callback when the initialisation process is complete that I can use to trigger the call to the constructor of component_meter.cpp, or does the initialisation take place in a separate thread, meaning that it might be possible to set a simple delay, which wouldn’t be ideal…

I don’t think there’s a callback that specifically alerts you when initialisation has finished. However, if you’ve written your own Application instance instead of using the JuceApp class provided with JUCE, then you can call whatever arbitrary code you like after initialiseJUCE returns. I’m not sure I’d recommend that approach, though.

A standard approach for lazily-initialising globals is to put them in a function, like this:

ComponentMeter& getComponentMeterSingleton()
{
    static ComponentMeter result;
    return result;
}

If you really need to make sure that this initialisation happens early on, rather than just before the first “real” use of getComponentMeterSingleton(), you could add a call to this function somewhere that you know will be executed shortly after startup, for example in the constructor of your main Component.

It would be even better to avoid the global variable altogether, and to create ComponentMeter instances on demand. Avoiding globals and singletons normally results in more flexible, understandable code, although it might require a little more work up-front.

I’ll do my homework with this information. I hope to get back to you soon with a ‘done’.

Thank you very much.

The problem was solved by removing all global constants that were initialised with File::getSpecialLocation().

Interestingly, this had nothing to do with the class and the code in component_meter.cpp.