NoSuchMethodException using reflection

I wan’t to use the protected method colorCalc in the PGraphics object.
I get a NoSuchMethodException and I have no clue why.
Can someone help?

import java.lang.reflect.*;


void setup() {
  int c = g_color(g, 128);
}


Method colorCalcMethod_one_int;
Field calcColor;

public int g_color(PGraphics g, int c) {
  try {

    if (colorCalcMethod_one_int == null) {
      colorCalcMethod_one_int = g.getClass().getDeclaredMethod("colorCalc", Integer.class);
      colorCalcMethod_one_int.setAccessible(true);
    }
    if (calcColor == null) {
      calcColor = g.getClass().getDeclaredField("calcColor");
      calcColor.setAccessible(true);
    }

    colorCalcMethod_one_int.invoke(g, c);
    return calcColor.getInt(g);
  } 
  catch (Exception e) {
    e.printStackTrace();
  }

  return -1;
}

I don’t believe you can access protected methods outside the class.

I doubt Class::getDeclaredMethod() is able to find methods that a class inherited from any of its parents: :cold_sweat:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html#getDeclaredMethod(java.lang.String,java.lang.Class...)

Instead, method colorCalc() is found declared inside class PGraphics: :world_map:

And not in any of its subclasses: :woozy_face:

Therefore, you’re gonna need to use PGraphics.class in place of g.getClass(). :nerd_face:

Good catch but it does not work…
I start to understand now why some people call reflection in java black magic.

This works but really sucks:

           Method[] methods = PGraphics.class.getDeclaredMethods();
                
                for (Method m : methods) {
                    if (m.getName().equals("colorCalc")) {

                        Class<?>[] parameter_types = m.getParameterTypes();
                        if(parameter_types.length == 1) {
                            if(parameter_types[0].getName().equals("int")) {
                                colorCalcMethod_one_int = m;
                                break;
                            }
                        }

                    }
                }

A better solution then the above is still welcome.

getDeclaredMethod("colorCalc", int.class) IIRC

2 Likes

Thanks!, never new int.class was a thing, being int a primitive.
Here the complete working code:

import java.lang.reflect.*;


void setup() {
  int c = g_color(g, 128);
}


Method colorCalcMethod_one_int;
Field calcColor;

public int g_color(PGraphics g, int c) {
  try {

    if (colorCalcMethod_one_int == null) {
      colorCalcMethod_one_int = PGraphics.class.getDeclaredMethod("colorCalc", int.class);
      colorCalcMethod_one_int.setAccessible(true);
    }
    if (calcColor == null) {
      calcColor = PGraphics.class.getDeclaredField("calcColor");
      calcColor.setAccessible(true);
    }

    colorCalcMethod_one_int.invoke(g, c);
    return calcColor.getInt(g);
  } 
  catch (Exception e) {
    e.printStackTrace();
  }

  return -1;
}
1 Like

Yep, it is one of the weirder aspects of doing reflection! :smile:

Glad you got it working.