Java reflection finding method - java

I have a problem with finding a method with Java, for example, I have to print a value to System.out via reflection:
public static void print(Object value) {
Method method = PrintStream.class.getMethod("print", value.getClass());
method.invoke(System.out, value);
}
It works fine with strings, but when I pass an instance of MyClass, for example, I receive the following error:
java.lang.NoSuchMethodException: java.io.PrintStream.print(MyClass)
at java.lang.Class.getMethod(Class.java:1786)
at Test.print(Test.java:20)
at Test.main(Test.java:15)
I believe that's because Java cannot find the method with the exact signature, but here java.io.PrintStream.print(java.lang.Object) suits well. How can I find a method that suits the following classes, not just has the same signature? The approach should also work for multiple arguments.

I believe that's because Java cannot find the method with the exact signature ...
That is correct. The reflection APIs don't support this. There is no simple way to replicate Java's (static) method overload resolution when looking up a method reflectively.
The non-simple way is to:
Identify all of the classes and interfaces that MyClass implements. (You can do that reflectively.)
Call PrintStream.class.getMethod("print", type) for each of those class / interface types.
If you get more than one result from step 2, use some heuristic to work out which method is the "best" one to use. (It doesn't have to be one that mirrors what the JLS does, though that would probably be the "least surprising" approach to use.)
There are 3rd party libraries that will do this for you; look at this Q&As for some suggestions:
Getting the best fit Instance Method in Java

Related

Is it possible to use JNA to get the signature of a function

Is it possible to use JNA to check that the signature of the Java interface is consistent with the signature of the associated C funtions?
For example suppose that I have the following C interface for my C code:
__declspec(dllexport) void receive(bool boolValue, int intValue);
And the associated Java interface:
public interface MyLibrary extends Library {
public void receive(int intValue, bool boolValue);
}
If I load the library, I will have no problem, but of course I will have an error if calling the receive method of the interface because the signature of the method is not aligned with the signature of the corresponding function.
Is there any way to know that the alignment is off before calling the method? I though about using:
Function function = NativeLibrary.getFunction("receive");
But after that it seems that I have no way to know anything about the signature of the function.
No, there is no automated mechanism, and in fact incorrectly mapping types is probably the most common error made when implementing JNA mappings, and that's usually the very first thing I check when code misbehaves.
If JNA can't find a matching function with the same number of arguments, you'll get an error:
java.lang.UnsatisfiedLinkError: Error looking up function 'Foo': The specified procedure could not be found.
If the method name matches the native function, and the number of arguments matches, JNA will not give any obvious indication of an improper mapping, however if you write robust unit tests and attempt to obtain sane/expected output from the native function, this will help catch most errors (although "catch" means "displays odd symptoms.")
You still may miss platform-dependent errors such as 32- vs. 64-bit long or pointer types.
There are still cases where it is technically impossible to know the correct mapping for a compiled library where the byte width of some types depends on compile-time switches, such as for the off_t type. There is no foolproof way of determining this at run time.

Java Class.cast to most specific with method overloading

I have a code that looks like this
function a(Object m) {}
function a(BasicDbObject) {}
function a(TypeA) {}
function a(TypeB) {}
function a(TypeC) {}
.....
function b(Object m) {
// Some function using Java reflection to determine class of Object m
Class X = c(m);
a(X.cast(m));
}
Here is the problem. It always execute a(Object m) rather than a(BasicDbObject m), even it is BasicDbObject.
My end goal is to execute most closest function to the object passed.
What you are trying cannot be done, because Java is statically typed, and the method overload is resolved at compile-time, not run-time.
The only way to resolve the overload at runtime, is for the method call itself to be done with reflection.
Serious non-answer: wrong approach.
You don't use reflection to dynamically determine a type, to then figure which overloaded method to call.
Instead, use polymorphism. Meaning: don't overload, but override.
Rest assured: getting "reflection" working is hard. Getting it correct, and robust and stable is a super challenging, uphill battle.
You basically want to invent your own personal dynamic dispatch implementation. Unless you have super hard pressing reasons to do so, that is a terrible idea. Because chances are that you will get it wrong. Many many times. And even when your code is working, there will be many incidents later on, when unforeseen things happen in production.
As said: don't do this. Don't fight the language, instead use the means that the language offers you to solve such problems: an inheritance tree of classes, and polymorphic methods. Then let the JVM decide which method to invoke. Most likely, the JVM will do a much better job, compared to what you will come up with.
function a(Object m) {}
function a(BasicDbObject) {}
When methods are overloaded, it may not be intuitive to know the method which gets invoked for any set of parameters because, unlike the situation with overridden methods, the method overloading that gets invoked is determined at compile time (i.e. statically) rather than at run time (i.e. dynamically). This behavior is confusing because overriding methods is more common and this sets our expectations for method invocation.
There are some rules for doing method overloading as robustly and as simply as possible. These are all nicely enumerated in Effective Java (J. Bloch, 2nd and 3rd eds.).
Your situation is made complex because:
You have two overloadings with the same number of parameters whose types are not radically different ... and ...
The behavior of the overloadings is apparently dependent on the type of the parameter (if the behavior was identical, then you simply have one overloading forward to the other)
When this situation arises, you should try to correct it by giving the overloadings different names. It should always be possible to do this and doing so often improves the clarity and maintainability of the code.
If this can't be done for any reason, then the best workaround is to replace the overloadings with a method that accepts the most general parameter type and which invokes helper methods based on the most specific type of the passed argument.
So instead of the above, you can get the behavior you want by using...
public Function a(Object m) {
if (m instanceof BasicDbObject) return doDbObject(m);
if (m instanceof OtherDbObject) return doOtherDbObject(m);
return doGenericObject(m);
}
Note that this isn't the code that you would use when Java adopts pattern matching in the language. Note also that the effect of this code is to give your overloadings different names, but the selection of the distinct method is made at run time using instanceof comparisons rather than at compile time by simply using a distinct name.
TLDR; if you are doing method overloading in a circumstance in which the parameter types are not (or may not be) radically different then you are better off not overloading and using distinct method names.

Eclipse JDT Core - Resolve generic return type for parameterised super method

I am v. inexperienced with the JDT apis, so would be great if someone could help me.
My question is how do I resolve the return type of the test method in the code below?
public interface BaseInterface<T> {
T test();
}
public interface Messages extends BaseInterface<String> {}
I have tried all sorts of searching on google and stackoverflow (ASTParser, visitor, method bindings, etc, but can't seem to find an easy way to get the return type with JDT.
EDIT***
This is related to a bug I created/found a bug in https://github.com/gwt-plugins/gwt-eclipse-plugin/issues/373, and was trying to fix it. My first time working with both JDT and gwt-eclipse plugin code, so it was just a stab, not sure if you can give any advice on it. The whole thing maybe need to be attacked in a slightly different way.
It calls the JavaModelSearch.findMethodInHierarchy first which grabs the IMethod, and passes that down, but then can't figure out the return type of T
You should first find the org.eclipse.jdt.core.dom.ITypeBinding for interface "Messages".
From there you can navigate to getSuperclass() or in your case getInterfaces(). This should grant access to the parameterized type "BaseInterface<String>" (note, that the light-weight JavaModel consisting of IType, IMethod etc. does not support the notion of a parameterized type as needed here).
From the latter binding, asking getDeclaredMethods() should answer the desired method "String test()" with return type "String" indeed.
For further inspiration you may want to look that the internal method org.eclipse.jdt.internal.corext.dom.Bindings.findMethodInHierarchy(ITypeBinding, String, ITypeBinding[]).

How to determine if a Java method modifies an object passed as parameter

I come from a C++ background and I am currently learning Java. One question arose when I have tried using some third party libraries. How do I determine if the call to a method taking an object reference as parameter modifies the object?
In C++ this is clear thanks to the use of the const keyword. If the method signature is:
void foo(Boo& boo);
I know that the referenced object might be modified, while if the method signature is:
void foo(const Boo& boo);
The compiler guarantees that the referenced object is not modified.
I haven't seen something analogous in Java, as only the reference itself can be declared final, not the referenced object, and a final argument doesn't make much sense in the first place since it is passed by value anyway. Therefore, when I see a method such as:
void foo(Boo boo) {...}
How do I determine if the object referenced by boo is modified inside the body of the function (maybe using annotations)? If there is no way to know, is there some widely used convention or some best practices to avoid confusion and bugs?
how do I determine if the object referenced by boo is modified inside the body of the function (maybe using annotations)?
The only way is to read the code unfortunately.
If there is no way to know, is there some widely used convention or some best practices to avoid confusion and bugs?
The common convention is to pass an object which cannot be modified, using a wrapper if needed. This ensure the class cannot modify the object.
List<String> readOnly = Collections.unmodifiableList(list);
If the object is Cloneable, you can also use clone() but another common approach is to use a copy.
List<String> readOnly = new ArrayList<>(list);
If you care about such behaviour, unit tests can show whether a method modifies an object or not. If you have unit tests already, it is usually one or two lines extra to check for this.
There's no such facility built in to the language, unfortunately. A good defensive practice is to define the data objects you pass around as immutable (i.e., without any public method that allows modifying their state). If you are really concerned about this, you could copy/clone an object before passing it to a method you don't trust, but this is usually a redundant precaution.
NOTE: this answer is a more detailed version of
You can also write purity or side-effect annotations in your code — mernst
There exists the Checker Framework among the various things it can check at compile-time via annotations is the IJG Immutablity checker. This checker allows you to annotate object references with #Immutable or #ReadOnly.
The problem is that you often would have to annotate the library yourself. To ease your task the Checker Framework can automatically infer part of the annotations; you will still have to do much yourself.
A side effect analysis is not built into the Java language.
You can perform side effect analysis via manual inspection, but several tools exist to automate the process.
You can use an inference tool (1, 2, 3) to detect whether your code side-effects a parameter.
You can also write purity or side-effect annotations in your code and then use a checking/verification tool (1, 2) to ensure that your code conforms to the annotations you have written.
All of the above-linked tools have limitations, but you might find them useful. If you know of other tools, mention them in comments.
How do I determine if the object referenced by boo is modified inside
the body of the function (maybe using annotations)?
I must agree with other answers that there is no direct way to determine that method will modify your object or not and yes to make sure that method can not modify your Object you all have to do it is from your side.
If there is no way to know, is there some widely used convention or
some best practices to avoid confusion and bugs?
Here the method name comes to the scene. Moving ahead with the naming convention of method we have to take a look at some method declarations which clearly convince you that your Object will not be changed at all.
For example, You know that Arrays.copyOf will not change your actual array, System.out.println(boo) will not change your boo
Method names are real weapons to provide as much information as possible to the method user.(Yes! it's always not possible but quite a good practice to follow.)
Let's consider it in your case that say printBoo will only print, copyBoo will only copy, clearBoo will reset all attributes, checkAndCreateNewBoo will check your boo Object and create new if required.
So, ultimately if we can use them in a proper way caller can be assured with the fact that Object will remain the same after calling the method.
As everyone says, prefer using immutable objects and also avoid void methods
The available purposes of methods like this
void foo(Boo boo) {...}
are to change the state of the object itself or change the object passed as a parameter
void completOrder(Order order) { ... }
//or
void parserTokenEnded(String str) { ... }
There is a way , that the method developer should mark parameter as final , if it is not going to modify the parameter.
public void test(final Object param)
However very few people follow this , so it is difficult to know. However good programmer follow this rule , especially writing the api. If you want to write method and expose it. Make param final to indicate that passed object is not going to be modified.

Groovy: Dynamically addings methods with a specific signature

So, I need to dynamically create (or inject) methods into an object that have a specific return type and method signature, because a Java tool we're using will be finding this methods via Reflection and checks for void type. Method names will be determined at runtime.
Using metaClass. = { ... } however adds a closure which doesn't show up as a regular method (even if it can be used as one) and also has a return type.
I can't modify the method finding code, and it it not Groovy-aware.
I can't use methodMissing() or invokeMethod() because the method needs to actually exist. If I could overload class.getMethods() I think it would be possible, but I can't figure out how.
Is there any way to do this in Groovy?
You could use AST Transformations to add the code at compile time, but it wont work on classes that you don't compile, so I'm guessing that probably wont work.
You could probably replace the object with a CGLIB based proxy. If you can be more specific about the code in question...
EDIT: A little more info. Groovy metaClass magic is not available in Java unless the Java code were to explicitly call groovyClass.invokeMethod("someMethod",args);. So there isn't a way to do what you're asking with MetaClasses. CGLIB maybe.

Categories

Resources