- Edited
Godot Version
4.5dev3 (or any)
Question
Long Story Short:
I made this Java Plugin to manage Android Audio Capture.
The plugin Builds correctly, with Gradle,
and generates the corresponding .aar file.
Everything is on place.
When running we get:
[AudioCaptureService] _ready() CALLED. OS: Android
[AudioCaptureService] Running on Android. Will check for Java plugin 'AudioCaptureMaster'.
[AudioCaptureService] Engine.has_singleton('AudioCaptureMaster') is TRUE.
[AudioCaptureService] SUCCESS: Java plugin 'AudioCaptureMaster' instance obtained: <JNISingleton#2835349665>
ERROR: [AudioCaptureService] ERROR: Java plugin instance does NOT have the method 'checkConnection()' (checked exact Java name)!
ERROR: [AudioCaptureService] This implies a fundamental issue with @UsedByGodot method exposure or the naming convention.
ERROR: [AudioCaptureService] WARNING: Java plugin instance does NOT have the method 'getPluginName()' (checked exact Java name).
So what happens is:
The plugin is indeed Included on Build.
And its name even read and printed..
However the functions/methods inside cannot be Called.
-Just calling the most basic method gives the above error.
Functions:
@UsedByGodot
@Override
public String getPluginName() {
Log.i(TAG, "Java getPluginName() called.");
return "AudioCaptureMaster"; // Use the TAG for plugin name
}
@UsedByGodot
public String checkConnection() {
Log.i(TAG, "Java checkConnection() method was successfully called from GDScript!");
return "Java plugin is connected and responding!";
}
Calls:
var exact_java_test_method_name = "checkConnection" # Exact Java method name
if _plugin_instance.has_method(exact_java_test_method_name):
# Call using the exact Java name
var connection_result = _plugin_instance.checkConnection() # CALLING CAMEL CASE
print("[%s] Call to Java method '%s()' successful! Result: '%s'" % [SCRIPT_NAME, exact_java_test_method_name, connection_result])
var exact_java_get_plugin_name_method = "getPluginName" # Exact Java method name
if _plugin_instance.has_method(exact_java_get_plugin_name_method):
var reported_name = _plugin_instance.getPluginName() # CALLING CAMEL CASE
print("[%s] Java plugin's %s() reports: '%s'" % [SCRIPT_NAME, exact_java_get_plugin_name_method, reported_name])
if reported_name != java_plugin_name_to_check:
printerr("[%s] WARNING: Java plugin name mismatch! Expected '%s', got '%s'" % [SCRIPT_NAME, java_plugin_name_to_check, reported_name])
else:
printerr("[%s] WARNING: Java plugin instance does NOT have the method '%s()' (checked exact Java name)." % [SCRIPT_NAME, exact_java_get_plugin_name_method])
printerr("[%s] This might be normal if getPluginName is not intended for direct GDScript calls." % SCRIPT_NAME)
Doesnt matter what you try.
It's not callable!
I thought it could be a snake_case vs camelCase problem, but nope..
-About the Java Plugin build...
I'm building the plugin .aar file with Gradle.
This needs to be built with:
(in build.gradle)
dependencies {
compileOnly files('libs/godot-lib.template_release.aar')
implementation 'androidx.core:core:1.9.0'
The file godot-lib.template_release.aar comes directly from the android_source.zip file,
be it on the Android Templates, or Github etc..
But the Java Plugn can also be built online with a Maven dependency repo:
implementation 'org.godotengine:godot:4.4.1.stable'
So in essence, we're using the right files for the Gradle build..
the Java code iapparently tight, and thats why the build is succesful.. ?
But In any case, doesnt matter how you build the Java Plugin,
the result is the same:
Plugin is Included on Build.
Godot Can find it!
Plug Cannot be Called..
Doesnt matter what I try, and as far as I can tell,
or Gemini and Grok can tell... (me noob)
Both Java Plugin, and Godot Plugin code is perfectly on the line and should be ready to go.
Long Version:
-I'm loading this with a custom made V2 style Godot Plugin.
plugin.cfg:
[plugin]
name="AudioCaptureMaster"
script="export_plugin.gd"
And somehow managed to include it on Build with: (export_plugin.gd)
func _get_android_libraries(platform, debug):
return PackedStringArray(["../android/plugins/audiocapturemaster/acmrelease.aar"])
---
@tool
extends EditorPlugin
var export_plugin : AndroidExportPlugin
func _enter_tree():
print("AudioCaptureMaster ExportPlugin entered tree.")
export_plugin = AndroidExportPlugin.new()
add_export_plugin(export_plugin)
add_custom_type("AudioCaptureSignals", "Node", preload("res://addons/audio_capture/AudioCaptureSignals.gd"), null)
func _exit_tree():
print("AudioCaptureMaster ExportPlugin exited tree.")
remove_export_plugin(export_plugin)
remove_custom_type("AudioCaptureSignals")
export_plugin = null
class AndroidExportPlugin extends EditorExportPlugin:
var _plugin_name = "AudioCaptureMaster"
func _supports_platform(platform):
if platform is EditorExportPlatformAndroid:
return true
return false
func _get_android_libraries(platform, debug):
return PackedStringArray(["../android/plugins/audiocapturemaster/acmrelease.aar"])
----
This grants the inclusion of the .aar plugin file on Build.
However I cannot even do the most basic Calls:
they get lost on the way
or lost in translation..
-About the Project/Plugin config..
The Plugin is loaded on Project Settings/Plugins
(thanks to the .cfg file)
A Singleton - AudioCaptureService.gd is loaded in Globals/Autoload.
that is what makes the basic call, getPluginName, just to check the plug availability..
The plugin doesnt appear on Export on its own,
but it's included on build, we know that:
[AudioCaptureService] Engine.has_singleton('AudioCaptureMaster') is TRUE.
[AudioCaptureService] SUCCESS: Java plugin 'AudioCaptureMaster' instance obtained: <JNISingleton#2835349665>
In order to make the plugin appear on Export menu, you need to have a .gdap file.
for instance:
[config]
name="AudioCaptureMaster"
binary_type="local"
binary="audiocapturemaster/acmrelease.aar"
But that is unnecesary, (and will not work on its own)
the Plugin will be included on build thanks to:
func _get_android_libraries(platform, debug):
return PackedStringArray(["../android/plugins/audiocapturemaster/acmrelease.aar"])
And that's the situation!
-I have seen other Godot Java plugins work: Admob or Appodeal (outdated).
We have revised how those plugins are made, Top to Bottom,
and as far as we can tell, our Java plug, and the accompanying Godot plug, are well made.
But yeah, doesnt matter what we try..!
It's just not possible to Call the functions/methods in our Java plugin from within Godot.
Any ideas?
What's the correct way to do this?
Ofc we have checked the documentation:
https://docs.godotengine.org/en/stable/tutorials/platform/android/android_plugin.html
And we're adhering to it 100%.
And that's part of the problem too..
If we're following the given steps and doing a semingly correct implementation,
why is this failing?
Where's the rest of Android/Java related documentation?
What can we do to make Godot be able to Call the functions contained inside a Java plugin, which we know is included on Build?
-This is really maddening..
If we could communicate with the Java Plug we will see if it's well made/not,
if it works/not, and we'll be able to work on it and make it Go..!
But since we cannot Call the plugin on the most fundamental level,
we're Blocked and there's nothing we can do!