3636bool JavaClass::_call_method (JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) {
3737 HashMap<StringName, List<MethodInfo>>::Iterator M = methods.find (p_method);
3838 if (!M) {
39+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
3940 return false ;
4041 }
4142
@@ -756,15 +757,19 @@ bool JavaClass::_get(const StringName &p_name, Variant &r_ret) const {
756757}
757758
758759Variant JavaClass::callp (const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
759- Variant ret;
760+ // Godot methods take precedence.
761+ Variant ret = RefCounted::callp (p_method, p_args, p_argcount, r_error);
762+ if (r_error.error == Callable::CallError::CALL_OK) {
763+ return ret;
764+ }
760765
761766 String method = (p_method == java_constructor_name) ? " <init>" : p_method;
762767 bool found = _call_method (nullptr , method, p_args, p_argcount, r_error, ret);
763768 if (found) {
764769 return ret;
765770 }
766771
767- return RefCounted::callp (p_method, p_args, p_argcount, r_error );
772+ return Variant ( );
768773}
769774
770775String JavaClass::get_java_class_name () const {
@@ -858,6 +863,11 @@ String JavaClass::to_string() {
858863 return " <JavaClass:" + java_class_name + " >" ;
859864}
860865
866+ bool JavaClass::has_java_method (const StringName &p_method) const {
867+ String method = (p_method == java_constructor_name) ? " <init>" : p_method;
868+ return methods.has (method);
869+ }
870+
861871JavaClass::JavaClass () {
862872}
863873
@@ -873,10 +883,15 @@ JavaClass::~JavaClass() {
873883// ///////////////////
874884
875885Variant JavaObject::callp (const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
886+ // Godot methods take precedence.
887+ Variant ret = RefCounted::callp (p_method, p_args, p_argcount, r_error);
888+ if (r_error.error == Callable::CallError::CALL_OK) {
889+ return ret;
890+ }
891+
876892 if (instance) {
877893 Ref<JavaClass> c = base_class;
878894 while (c.is_valid ()) {
879- Variant ret;
880895 bool found = c->_call_method (this , p_method, p_args, p_argcount, r_error, ret);
881896 if (found) {
882897 return ret;
@@ -885,7 +900,7 @@ Variant JavaObject::callp(const StringName &p_method, const Variant **p_args, in
885900 }
886901 }
887902
888- return RefCounted::callp (p_method, p_args, p_argcount, r_error );
903+ return Variant ( );
889904}
890905
891906Ref<JavaClass> JavaObject::get_java_class () const {
@@ -899,6 +914,19 @@ String JavaObject::to_string() {
899914 return RefCounted::to_string ();
900915}
901916
917+ bool JavaObject::has_java_method (const StringName &p_method) const {
918+ if (instance) {
919+ Ref<JavaClass> c = base_class;
920+ while (c.is_valid ()) {
921+ if (c->has_java_method (p_method)) {
922+ return true ;
923+ }
924+ c = c->get_java_parent_class ();
925+ }
926+ }
927+ return false ;
928+ }
929+
902930JavaObject::JavaObject () {
903931}
904932
@@ -1461,7 +1489,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
14611489 return false ;
14621490}
14631491
1464- Ref<JavaClass> JavaClassWrapper::_wrap (const String &p_class, bool p_allow_private_methods_access ) {
1492+ Ref<JavaClass> JavaClassWrapper::_wrap (const String &p_class, bool p_allow_non_public_methods_access ) {
14651493 String class_name_dots = p_class.replace_char (' /' , ' .' );
14661494 if (class_cache.has (class_name_dots)) {
14671495 return class_cache[class_name_dots];
@@ -1473,10 +1501,18 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_priva
14731501 jclass bclass = jni_find_class (env, class_name_dots.replace_char (' .' , ' /' ).utf8 ().get_data ());
14741502 ERR_FAIL_NULL_V_MSG (bclass, Ref<JavaClass>(), vformat (" Java class '%s' not found." , p_class));
14751503
1476- jobjectArray constructors = (jobjectArray)env->CallObjectMethod (bclass, Class_getDeclaredConstructors);
1504+ jobjectArray constructors = (jobjectArray)env->CallObjectMethod (bclass, Class_getConstructors);
1505+ if (env->ExceptionCheck ()) {
1506+ env->ExceptionDescribe ();
1507+ env->ExceptionClear ();
1508+ }
14771509 ERR_FAIL_NULL_V (constructors, Ref<JavaClass>());
14781510
14791511 jobjectArray methods = (jobjectArray)env->CallObjectMethod (bclass, Class_getDeclaredMethods);
1512+ if (env->ExceptionCheck ()) {
1513+ env->ExceptionDescribe ();
1514+ env->ExceptionClear ();
1515+ }
14801516 ERR_FAIL_NULL_V (methods, Ref<JavaClass>());
14811517
14821518 Ref<JavaClass> java_class = memnew (JavaClass);
@@ -1515,8 +1551,9 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_priva
15151551 Vector<String> params;
15161552
15171553 jint mods = env->CallIntMethod (obj, is_constructor ? Constructor_getModifiers : Method_getModifiers);
1554+ bool is_public = (mods & 0x0001 ) != 0 ; // java.lang.reflect.Modifier.PUBLIC
15181555
1519- if (!(mods & 0x0001 ) && (is_constructor || !p_allow_private_methods_access )) {
1556+ if (!is_public && (is_constructor || !p_allow_non_public_methods_access )) {
15201557 env->DeleteLocalRef (obj);
15211558 continue ; // not public bye
15221559 }
@@ -1627,6 +1664,13 @@ Ref<JavaClass> JavaClassWrapper::_wrap(const String &p_class, bool p_allow_priva
16271664 mi.method = env->GetMethodID (bclass, str_method.utf8 ().get_data (), signature.utf8 ().get_data ());
16281665 }
16291666
1667+ if (env->ExceptionCheck ()) {
1668+ // Exceptions may be thrown when trying to access hidden methods; write the exception to the logs and continue.
1669+ env->ExceptionDescribe ();
1670+ env->ExceptionClear ();
1671+ continue ;
1672+ }
1673+
16301674 ERR_CONTINUE (!mi.method );
16311675
16321676 java_class->methods [str_method].push_back (mi);
@@ -1700,7 +1744,7 @@ JavaClassWrapper::JavaClassWrapper() {
17001744 ERR_FAIL_NULL (env);
17011745
17021746 jclass bclass = jni_find_class (env, " java/lang/Class" );
1703- Class_getDeclaredConstructors = env->GetMethodID (bclass, " getDeclaredConstructors " , " ()[Ljava/lang/reflect/Constructor;" );
1747+ Class_getConstructors = env->GetMethodID (bclass, " getConstructors " , " ()[Ljava/lang/reflect/Constructor;" );
17041748 Class_getDeclaredMethods = env->GetMethodID (bclass, " getDeclaredMethods" , " ()[Ljava/lang/reflect/Method;" );
17051749 Class_getFields = env->GetMethodID (bclass, " getFields" , " ()[Ljava/lang/reflect/Field;" );
17061750 Class_getName = env->GetMethodID (bclass, " getName" , " ()Ljava/lang/String;" );
0 commit comments