Java Proxy invoke for nested calls - java

I'm having problems implementing a Proxy for a class that has to print the stacktrace for every call on a function of a class, because the functions are nested one with the other.
The problem is very similar if not the same to one another user had, the answers helped me to understand how to approach it but still I can't manage to solve it ( Dynamic Proxy: how to handle nested method calls ).
I've a class :
public class NestedCalls implements INestedCalls{
private int i = 0;
public int a() {
return b(i++);
}
public int b(int a) {
return (i<42)?c(b(a())):1;
}
public int c(int a) {
return --a;
}
}
and its interface:
public interface INestedCalls {
public int a() ;
public int b(int a) ;
public int c(int a) ;
}
The handler I implemented looks like this:
public class NestHandler implements InvocationHandler {
Object base;
public NestHandler(Object base) {
this.base=base;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(base, args);
printNest();
return result;
}
private void printNest() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
StackTraceElement[] stack = new Throwable().getStackTrace();
System.out.println("num of elem " + stack.length);
for(int i=0; i<stack.length; i++) {
System.out.println("elem "+i+": "+stack[i]);
}
}
}
What I aim to do is to initialize the object and the proxy from my main and after invoking a method I expect to print the stacktrace every time a method of the class is invoked.
INestedCalls nestedcalls = new ENestedCalls();
INestedCalls nestproxy = (INestedCalls) Proxy.newProxyInstance(nestedcalls.getClass().getClassLoader(), nestedcalls.getClass().getInterfaces(), new NestHandler(nestedcalls));
nestproxy.a();
To my understanding this doesn't work because the proxy handles everything with a intra-object and so the nested methods are not called with the proxy interface.
How can I get the effect I want without touching the code of the class?

Related

Java invoke static method with Foreign Context / Check method for recursion

I wanted to check if a method uses recursion. So I wrote this mock up:
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method method = Child.class.getMethod("toBeTested", int.class);
Object result = method.invoke(Super.class, 5);
System.out.println((Integer) result);
}
}
public class Super extends Child{
public static int toBeTested(int a){
System.out.println("validating recursion");
return Child.toBeTested(a);
}
}
public class Child {
public static int toBeTested(int a){
if(a==0)return 0;
return toBeTested(a-1)+1;
}
}
So I tried executing the method in Child with the Context of Super.class hoping in the recursion it would call the Super::toBeTested and I could hence validate the method uses recursion.
Is this even possible the way I tried? If no why not? Any other ideas to check foreign code for recursion...
No, you can't do that because that's not how static methods work, they don't have a "context" that decides what they call at runtime, it's decided at compile time (unless you want to call the classloader the context).
If it was a non-static method then you could do this:
public static class Child extends Super {
public int toBeTested(int a){
System.out.println("validating recursion");
return super.toBeTested(a);
}
}
public static class Super {
public int toBeTested(int a){
if(a==0)return 0;
return toBeTested(a-1)+1;
}
}
public static void main(String args[]) throws Exception {
Method method = Super.class.getMethod("toBeTested", int.class);
Object result = method.invoke(new Child(), 5);
System.out.println((Integer) result);
}
and it would print validating recursion 6 times because the method to be called depends on the runtime type of the object.
To check if static methods call themselves you could read the bytecode of the method (if you have access to it).

How can I pass a method to a constructor? [duplicate]

I am looking for a way to pass a method by reference. I understand that Java does not pass methods as parameters, however, I would like to get an alternative.
I've been told interfaces are the alternative to passing methods as parameters but I don't understand how an interface can act as a method by reference. If I understand correctly an interface is simply an abstract set of methods that are not defined. I don't want to send an interface that needs to be defined every time because several different methods could call the same method with the same parameters.
What I would like to accomplish is something similar to this:
public void setAllComponents(Component[] myComponentArray, Method myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) { //recursive call if Container
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
} //end if node
myMethod(leaf);
} //end looping through components
}
invoked such as:
setAllComponents(this.getComponents(), changeColor());
setAllComponents(this.getComponents(), changeSize());
Edit: as of Java 8, lambda expressions are a nice solution as other answers have pointed out. The answer below was written for Java 7 and earlier...
Take a look at the command pattern.
// NOTE: code not tested, but I believe this is valid java...
public class CommandExample
{
public interface Command
{
public void execute(Object data);
}
public class PrintCommand implements Command
{
public void execute(Object data)
{
System.out.println(data.toString());
}
}
public static void callCommand(Command command, Object data)
{
command.execute(data);
}
public static void main(String... args)
{
callCommand(new PrintCommand(), "hello world");
}
}
Edit: as Pete Kirkham points out, there's another way of doing this using a Visitor. The visitor approach is a little more involved - your nodes all need to be visitor-aware with an acceptVisitor() method - but if you need to traverse a more complex object graph then it's worth examining.
In Java 8, you can now pass a method more easily using Lambda Expressions and Method References. First, some background: a functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.
Without lambda expressions:
obj.aMethod(new AFunctionalInterface() {
#Override
public boolean anotherMethod(int i)
{
return i == 982
}
});
With lambda expressions:
obj.aMethod(i -> i == 982);
Here is an excerpt from the Java tutorial on Lambda Expressions:
Syntax of Lambda Expressions
A lambda expression consists of the following:
A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p,
which represents an instance of the Person class.Note: You
can omit the data type of the parameters in a lambda expression. In
addition, you can omit the parentheses if there is only one parameter.
For example, the following lambda expression is also valid:
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
The arrow token, ->
A body, which consists of a single expression or a statement block. This example uses the following expression:
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively,
you can use a return statement:
p -> {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have
to enclose a void method invocation in braces. For example, the
following is a valid lambda expression:
email -> System.out.println(email)
Note that a lambda expression looks a lot like a method declaration;
you can consider lambda expressions as anonymous methods—methods
without a name.
Here is how you can "pass a method" using a lambda expression:
interface I {
public void myMethod(Component component);
}
class A {
public void changeColor(Component component) {
// code here
}
public void changeSize(Component component) {
// code here
}
}
class B {
public void setAllComponents(Component[] myComponentArray, I myMethodsInterface) {
for(Component leaf : myComponentArray) {
if(leaf instanceof Container) { // recursive call if Container
Container node = (Container)leaf;
setAllComponents(node.getComponents(), myMethodInterface);
} // end if node
myMethodsInterface.myMethod(leaf);
} // end looping through components
}
}
class C {
A a = new A();
B b = new B();
public C() {
b.setAllComponents(this.getComponents(), component -> a.changeColor(component));
b.setAllComponents(this.getComponents(), component -> a.changeSize(component));
}
}
Class C can be shortened even a bit further by the use of method references like so:
class C {
A a = new A();
B b = new B();
public C() {
b.setAllComponents(this.getComponents(), a::changeColor);
b.setAllComponents(this.getComponents(), a::changeSize);
}
}
Since Java 8 there is a Function<T, R> interface (docs), which has method
R apply(T t);
You can use it to pass functions as parameters to other functions. T is the input type of the function, R is the return type.
In your example you need to pass a function that takes Component type as an input and returns nothing - Void. In this case Function<T, R> is not the best choice, since there is no autoboxing of Void type. The interface you are looking for is called Consumer<T> (docs) with method
void accept(T t);
It would look like this:
public void setAllComponents(Component[] myComponentArray, Consumer<Component> myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) {
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
}
myMethod.accept(leaf);
}
}
And you would call it using method references:
setAllComponents(this.getComponents(), this::changeColor);
setAllComponents(this.getComponents(), this::changeSize);
Assuming that you have defined changeColor() and changeSize() methods in the same class.
If your method happens to accept more than one parameter, you can use BiFunction<T, U, R> - T and U being types of input parameters and R being return type. There is also BiConsumer<T, U> (two arguments, no return type). Unfortunately for 3 and more input parameters, you have to create an interface by yourself. For example:
public interface Function4<A, B, C, D, R> {
R apply(A a, B b, C c, D d);
}
Use the java.lang.reflect.Method object and call invoke
First define an Interface with the method you want to pass as a parameter
public interface Callable {
public void call(int param);
}
Implement a class with the method
class Test implements Callable {
public void call(int param) {
System.out.println( param );
}
}
// Invoke like that
Callable cmd = new Test();
This allows you to pass cmd as parameter and invoke the method call defined in the interface
public invoke( Callable callable ) {
callable.call( 5 );
}
While this is not yet valid for Java 7 and below, I believe that we should look to the future and at least recognize the changes to come in new versions such as Java 8.
Namely, this new version brings lambdas and method references to Java (along with new APIs, which are another valid solution to this problem. While they still require an interface no new objects are created, and extra classfiles need not pollute output directories due to different handling by the JVM.
Both flavors(lambda and method reference) require an interface available with a single method whose signature is used:
public interface NewVersionTest{
String returnAString(Object oIn, String str);
}
Names of methods will not matter from here on. Where a lambda is accepted, a method reference is as well. For example, to use our signature here:
public static void printOutput(NewVersionTest t, Object o, String s){
System.out.println(t.returnAString(o, s));
}
This is just a simple interface invocation, up until the lambda1 gets passed:
public static void main(String[] args){
printOutput( (Object oIn, String sIn) -> {
System.out.println("Lambda reached!");
return "lambda return";
}
);
}
This will output:
Lambda reached!
lambda return
Method references are similar. Given:
public class HelperClass{
public static String testOtherSig(Object o, String s){
return "real static method";
}
}
and main:
public static void main(String[] args){
printOutput(HelperClass::testOtherSig);
}
the output would be real static method. Method references can be static, instance, non-static with arbitrary instances, and even constructors. For the constructor something akin to ClassName::new would be used.
1 This is not considered a lambda by some, as it has side effects. It does illustrate, however, the use of one in a more straightforward-to-visualize fashion.
Last time I checked, Java is not capable of natively doing what you want; you have to use 'work-arounds' to get around such limitations. As far as I see it, interfaces ARE an alternative, but not a good alternative. Perhaps whoever told you that was meaning something like this:
public interface ComponentMethod {
public abstract void PerfromMethod(Container c);
}
public class ChangeColor implements ComponentMethod {
#Override
public void PerfromMethod(Container c) {
// do color change stuff
}
}
public class ChangeSize implements ComponentMethod {
#Override
public void PerfromMethod(Container c) {
// do color change stuff
}
}
public void setAllComponents(Component[] myComponentArray, ComponentMethod myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) { //recursive call if Container
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
} //end if node
myMethod.PerfromMethod(leaf);
} //end looping through components
}
Which you'd then invoke with:
setAllComponents(this.getComponents(), new ChangeColor());
setAllComponents(this.getComponents(), new ChangeSize());
If you don't need these methods to return something, you could make them return Runnable objects.
private Runnable methodName (final int arg) {
return (new Runnable() {
public void run() {
// do stuff with arg
}
});
}
Then use it like:
private void otherMethodName (Runnable arg){
arg.run();
}
Java-8 onwards
Java 8 onwards, you can provide the implementation of the abstract method of a functional interface (an interface that has only one abstract method) using a lambda expression and pass the same to a method as a parameter.
#FunctionalInterface
interface ArithmeticFunction {
public int calcualate(int a, int b);
}
public class Main {
public static void main(String args[]) {
ArithmeticFunction addition = (a, b) -> a + b;
ArithmeticFunction subtraction = (a, b) -> a - b;
int a = 20, b = 5;
System.out.println(perform(addition, a, b));
// or
System.out.println(perform((x, y) -> x + y, a, b));
System.out.println(perform(subtraction, a, b));
// or
System.out.println(perform((x, y) -> x - y, a, b));
}
static int perform(ArithmeticFunction function, int a, int b) {
return function.calcualate(a, b);
}
}
Output:
25
25
15
15
ONLINE DEMO
Learn more about it from Method References.
I didn't find any example explicit enough for me on how to use java.util.function.Function for simple method as parameter function. Here is a simple example:
import java.util.function.Function;
public class Foo {
private Foo(String parameter) {
System.out.println("I'm a Foo " + parameter);
}
public static Foo method(final String parameter) {
return new Foo(parameter);
}
private static Function parametrisedMethod(Function<String, Foo> function) {
return function;
}
public static void main(String[] args) {
parametrisedMethod(Foo::method).apply("from a method");
}
}
Basically you have a Foo object with a default constructor. A method that will be called as a parameter from the parametrisedMethod which is of type Function<String, Foo>.
Function<String, Foo> means that the function takes a String as parameter and return a Foo.
The Foo::Method correspond to a lambda like x -> Foo.method(x);
parametrisedMethod(Foo::method) could be seen as x -> parametrisedMethod(Foo.method(x))
The .apply("from a method") is basically to do parametrisedMethod(Foo.method("from a method"))
Which will then return in the output:
>> I'm a Foo from a method
The example should be running as is, you can then try more complicated stuff from the above answers with different classes and interfaces.
Java do have a mechanism to pass name and call it. It is part of the reflection mechanism.
Your function should take additional parameter of class Method.
public void YouMethod(..... Method methodToCall, Object objWithAllMethodsToBeCalled)
{
...
Object retobj = methodToCall.invoke(objWithAllMethodsToBeCalled, arglist);
...
}
I did not found any solution here that show how to pass method with parameters bound to it as a parameter of a method. Bellow is example of how you can pass a method with parameter values already bound to it.
Step 1: Create two interfaces one with return type, another without. Java has similar interfaces but they are of little practical use because they do not support Exception throwing.
public interface Do {
void run() throws Exception;
}
public interface Return {
R run() throws Exception;
}
Example of how we use both interfaces to wrap method call in transaction. Note that we pass method with actual parameters.
//example - when passed method does not return any value
public void tx(final Do func) throws Exception {
connectionScope.beginTransaction();
try {
func.run();
connectionScope.commit();
} catch (Exception e) {
connectionScope.rollback();
throw e;
} finally {
connectionScope.close();
}
}
//Invoke code above by
tx(() -> api.delete(6));
Another example shows how to pass a method that actually returns something
public R tx(final Return func) throws Exception {
R r=null;
connectionScope.beginTransaction();
try {
r=func.run();
connectionScope.commit();
} catch (Exception e) {
connectionScope.rollback();
throw e;
} finally {
connectionScope.close();
}
return r;
}
//Invoke code above by
Object x= tx(() -> api.get(id));
Example of solution with reflection, passed method must be public
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class Program {
int i;
public static void main(String[] args) {
Program obj = new Program(); //some object
try {
Method method = obj.getClass().getMethod("target");
repeatMethod( 5, obj, method );
}
catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
System.out.println( e );
}
}
static void repeatMethod (int times, Object object, Method method)
throws IllegalAccessException, InvocationTargetException {
for (int i=0; i<times; i++)
method.invoke(object);
}
public void target() { //public is necessary
System.out.println("target(): "+ ++i);
}
}
Use the Observer pattern (sometimes also called Listener pattern):
interface ComponentDelegate {
void doSomething(Component component);
}
public void setAllComponents(Component[] myComponentArray, ComponentDelegate delegate) {
// ...
delegate.doSomething(leaf);
}
setAllComponents(this.getComponents(), new ComponentDelegate() {
void doSomething(Component component) {
changeColor(component); // or do directly what you want
}
});
new ComponentDelegate()... declares an anonymous type implementing the interface.
Here is a basic example:
public class TestMethodPassing
{
private static void println()
{
System.out.println("Do println");
}
private static void print()
{
System.out.print("Do print");
}
private static void performTask(BasicFunctionalInterface functionalInterface)
{
functionalInterface.performTask();
}
#FunctionalInterface
interface BasicFunctionalInterface
{
void performTask();
}
public static void main(String[] arguments)
{
performTask(TestMethodPassing::println);
performTask(TestMethodPassing::print);
}
}
Output:
Do println
Do print
I'm not a java expert but I solve your problem like this:
#FunctionalInterface
public interface AutoCompleteCallable<T> {
String call(T model) throws Exception;
}
I define the parameter in my special Interface
public <T> void initialize(List<T> entries, AutoCompleteCallable getSearchText) {.......
//call here
String value = getSearchText.call(item);
...
}
Finally, I implement getSearchText method while calling initialize method.
initialize(getMessageContactModelList(), new AutoCompleteCallable() {
#Override
public String call(Object model) throws Exception {
return "custom string" + ((xxxModel)model.getTitle());
}
})
I appreciate the answers above but I was able to achieve the same behavior using the method below; an idea borrowed from Javascript callbacks. I'm open to correction though so far so good (in production).
The idea is to use the return type of the function in the signature, meaning that the yield has to be static.
Below is a function that runs a process with a timeout.
public static void timeoutFunction(String fnReturnVal) {
Object p = null; // whatever object you need here
String threadSleeptime = null;
Config config;
try {
config = ConfigReader.getConfigProperties();
threadSleeptime = config.getThreadSleepTime();
} catch (Exception e) {
log.error(e);
log.error("");
log.error("Defaulting thread sleep time to 105000 miliseconds.");
log.error("");
threadSleeptime = "100000";
}
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
// Do job here using --- fnReturnVal --- and return appropriate value
return null;
}
};
Future<Object> future = executor.submit(task);
try {
p = future.get(Integer.parseInt(threadSleeptime), TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error(e + ". The function timed out after [" + threadSleeptime
+ "] miliseconds before a response was received.");
} finally {
// if task has started then don't stop it
future.cancel(false);
}
}
private static String returnString() {
return "hello";
}
public static void main(String[] args) {
timeoutFunction(returnString());
}

Automatically delegating all methods of a java class

Say I have a class with many of public methods:
public class MyClass {
public void method1() {}
public void method2() {}
(...)
public void methodN() {}
}
Now I would like to create a wrapper class which would delegate all the methods to wrapped instance (delegate):
public class WrapperClass extends MyClass {
private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delagate = delegate;
}
public void method1() { delegate.method1(); }
public void method2() { delegate.method2(); }
(...)
public void methodN() { delegate.methodN(); }
}
Now if MyClass has a lot of methods I would need to override each of them which is more or less the same code which just "delegates". I was wondering if it is possible to do some magic to automatically call a method in Java (so the Wrapper class would need to say "Hey if you call a method on me just go to delegate object and call this method on it).
BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final).
NOTE: I do not want IDE generation. I know I can do it with help of IntelliJ/Eclipse, but I'm curious if this can be done in code.
Any suggestions how to achieve something like this? (NOTE: I would probably be able to do it in some scripting languages like php where I could use php magic functions to intercept the call).
Perhaps the dynamic Proxy of java can help you. It only works if you consequently use interfaces. In this case, I will call the interface MyInterface and set up a default implementation:
public class MyClass implements MyInterface {
#Override
public void method1() {
System.out.println("foo1");
}
#Override
public void method2() {
System.out.println("foo2");
}
#Override
public void methodN() {
System.out.println("fooN");
}
public static void main(String[] args) {
MyClass wrapped = new MyClass();
wrapped.method1();
wrapped.method2();
MyInterface wrapper = WrapperClass.wrap(wrapped);
wrapper.method1();
wrapper.method2();
}
}
The wrapper class implementation would look like:
public class WrapperClass extends MyClass implements MyInterface, InvocationHandler {
private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delegate = delegate;
}
public static MyInterface wrap(MyClass wrapped) {
return (MyInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyInterface.class }, new WrapperClass(wrapped));
}
//you may skip this definition, it is only for demonstration
public void method1() {
System.out.println("bar");
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) {
return m.invoke(this, args);
}
m = findMethod(delegate.getClass(), method);
if (m != null) {
return m.invoke(delegate, args);
}
return null;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Note that this class:
extends MyClass, to inherit a default implementation (any other would do)
implements Invocationhandler, to allow the proxy to do reflection
optionally implement MyInterface (to satisfy the decorator pattern)
This solution allows you to override special methods, but to delegate all others. This will even work with sub classes of Wrapper class.
Note that the method findMethod does not yet capture the special cases.
This question is 6 months old already and #CoronA's wonderful answer has satisfied and been accepted by #walkeros, but I thought I would add something here as I think this can be pushed an extra step.
As discussed with #CoronA in the comments to his answer, instead of having to create and maintain a long list of MyClass methods in WrapperClass (i.e. public void methodN() { delegate.methodN(); }), the dynamic proxy solution moves this to the interface. The issue is that you still have to create and maintain a long list of signatures for the MyClass methods in the interface, which is perhaps a bit simpler but doesn't completely solve the problem. This is especially the case if you don't have access to MyClass in order to know all the methods.
According to Three approaches for decorating your code,
For longer classes, a programmer must choose the lesser of two evils:
implement many wrapper methods and keep the type of decorated object
or maintain a simple decorator implementation and sacrifice retaining
the decorated object type.
So perhaps this is an expected limitation of the Decorator Pattern.
#Mark-Bramnik, however, gives an fascinating solution using CGLIB at Interposing on Java Class Methods (without interfaces). I was able to combine this with #CoronaA's solution in order to create a wrapper that can override individual methods but then pass everything else to the wrapped object without requiring an interface.
Here is MyClass.
public class MyClass {
public void method1() { System.out.println("This is method 1 - " + this); }
public void method2() { System.out.println("This is method 2 - " + this); }
public void method3() { System.out.println("This is method 3 - " + this); }
public void methodN() { System.out.println("This is method N - " + this); }
}
Here is WrapperClass which only overrides method2(). As you'll see below, the non-overridden methods are, in fact, not passed to the delegate, which can be a problem.
public class WrapperClass extends MyClass {
private MyClass delagate;
public WrapperClass(MyClass delegate) { this.delagate = delegate; }
#Override
public void method2() {
System.out.println("This is overridden method 2 - " + delagate);
}
}
Here is MyInterceptor which extends MyClass. It employs the proxy solution using CGLIB as described by #Mark-Bramnik. It also employs #CononA's method of determining whether or not to send the method to the wrapper (if it is overridden) or the wrapped object (if it is not).
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyInterceptor extends MyClass implements MethodInterceptor {
private Object realObj;
public MyInterceptor(Object obj) { this.realObj = obj; }
#Override
public void method2() {
System.out.println("This is overridden method 2 - " + realObj);
}
#Override
public Object intercept(Object arg0, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
Method m = findMethod(this.getClass(), method);
if (m != null) { return m.invoke(this, objects); }
Object res = method.invoke(realObj, objects);
return res;
}
private Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Here is Main and the results you get if you run it.
import net.sf.cglib.proxy.Enhancer;
public class Main {
private static MyClass unwrapped;
private static WrapperClass wrapped;
private static MyClass proxified;
public static void main(String[] args) {
unwrapped = new MyClass();
System.out.println(">>> Methods from the unwrapped object:");
unwrapped.method1();
unwrapped.method2();
unwrapped.method3();
wrapped = new WrapperClass(unwrapped);
System.out.println(">>> Methods from the wrapped object:");
wrapped.method1();
wrapped.method2();
wrapped.method3();
proxified = createProxy(unwrapped);
System.out.println(">>> Methods from the proxy object:");
proxified.method1();
proxified.method2();
proxified.method3();
}
#SuppressWarnings("unchecked")
public static <T> T createProxy(T obj) {
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new MyInterceptor(obj));
T proxifiedObj = (T) e.create();
return proxifiedObj;
}
}
>>> Methods from the unwrapped object:
This is method 1 - MyClass#e26db62
This is method 2 - MyClass#e26db62
This is method 3 - MyClass#e26db62
>>> Methods from the wrapped object:
This is method 1 - WrapperClass#7b7035c6
This is overridden method 2 - MyClass#e26db62
This is method 3 - WrapperClass#7b7035c6
>>> Methods from the proxy object:
This is method 1 - MyClass#e26db62
This is overridden method 2 - MyClass#e26db62
This is method 3 - MyClass#e26db62
As you can see, when you run the methods on wrapped you get the wrapper for the methods that are not overridden (i.e. method1() and method3()). When you run the methods on proxified, however, all of the methods are run on the wrapped object without the pain of having to delegate them all in WrapperClass or put all of the method signatures in an interface. Thanks to #CoronA and #Mark-Bramnik for what seems like a pretty cool solution to this problem.
Check the #Delegate annotation from Lombok framework:
https://projectlombok.org/features/Delegate.html
Switch to Groovy :-)
#CompileStatic
public class WrapperClass extends MyClass {
#Delegate private final MyClass delegate;
public WrapperClass(MyClass delegate) {
this.delagate = delegate;
}
//Done. That's it.
}
http://mrhaki.blogspot.com/2009/08/groovy-goodness-delegate-to-simplify.html
You don't have to do this -- your Wrapper class is a subclass of the original class, so it inherits all of its publicly accessible methods -- and if you don't implement them, the original method will be called.
You shouldn't have extends Myclass together with a private MyClass object -- that's really really redundant, and I can't think of a design pattern where doing that is right. Your WrapperClass is a MyClass, and hence you can just use its own fields and methods instead of calling delegate.
EDIT: In the case of MyClass being final, you'd be circumventing the willfull declaration to not allow subclassing by "faking" inheritance; I can't think of anyone willing to do that other than you, who is in control of WrapperClass; but, since you're in control of WrapperClass, not wrapping everything you don't need is really more than an option -- it's the right thing to do, because your object is not a MyClass, and should only behave like one in the cases you mentally considered.
EDIT you've just changed your question to mean something completely different by removing the MyClass superclass to your WrapperClass; that's a bit bad, because it invalidates all answers given so far. You should have opened another question.
Credits go to CoronA for Pointing out the Proxy and InvocationHandler classes. I worked out a more reusable utility class based on his solution, using generics:
public class DelegationUtils {
public static <I> I wrap(Class<I> iface, I wrapped) {
return wrapInternally(iface, wrapped, new SimpleDecorator(wrapped));
}
private static <I> I wrapInternally (Class<I> iface, I wrapped, InvocationHandler handler) {
return (I) Proxy.newProxyInstance(wrapped.getClass().getClassLoader(), new Class[] { iface }, handler);
}
private static class SimpleDecorator<T> implements InvocationHandler {
private final T delegate;
private SimpleDecorator(T delegate) {
this.delegate = delegate;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method m = findMethod(delegate.getClass(), method);
if (m == null) {
throw new NullPointerException("Found no method " + method + " in delegate: " + delegate);
}
return m.invoke(delegate, args);
}
}
private static Method findMethod(Class<?> clazz, Method method) throws Throwable {
try {
return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
return null;
}
}
}
Test it:
public class Test {
public interface Test {
public void sayHello ();
}
public static class TestImpl implements Test {
#Override
public void sayHello() {
System.out.println("HELLO!");
}
}
public static void main(String[] args) {
Test proxy = DelegationUtils.wrap(Test.class, new TestImpl());
proxy.sayHello();
}
}
I wanted to create an automatic delegation class that executes the delegatee's methods on the EDT. With this class, you just create a new utility method that will use an EDTDecorator, in which the implementation will wrap m.invoke in a SwingUtilities.invokeLater.
However, if I reflect on this, I may want to reconsider making a non-Reflection based proxy per interface that I have - it might be cleaner and faster, and more understandable. But, it's possible.
Define a method in WrapperClass i.e. delegate() that returns the instance of MyClass
OR
You can use reflection to do that but the caller has to pass the method name as an argument to an exposed method. And there will be complications regarding the method arguments/overloaded methods etc.
BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final)
The code that you have posted has public class WrapperClass extends MyClass
Actually your current implementation of WrapperClass is actually a decorator on top of MyClass
Let me redefine the problem for a specific case.
I want to override the close method of ResultSet interface in jdbc. My aim is to close the preparedstatement in close method of result set. I could not access to the Class (DelegatingResultSet) that implements in ResultSet interface. There are a lot of methods in ResultSet interface and overriding them one by one and calling the corresponding method from the ResultSet object is one solution. For a dynamic solution I used Dynamic ProxyClasses (https://docs.oracle.com/javase/1.5.0/docs/guide/reflection/proxy.html).
// New ResultSet implementation
public class MyResultSet implements InvocationHandler {
ResultSet rs;
PreparedStatement ps;
private Method closeMethod;
public MyResultSet(ResultSet rs, PreparedStatement ps) {
super();
this.rs = rs;
this.ps = ps;
try {
closeMethod = ResultSet.class.getMethod("close",null);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
public void close() {
try {
rs.close();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static Object newInstance(ResultSet rs, PreparedStatement ps) {
return java.lang.reflect.Proxy.newProxyInstance(rs.getClass().getClassLoader(), rs.getClass().getInterfaces(),
new MyResultSet(rs,ps));
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Object result = null;
try {
Class declaringClass = m.getDeclaringClass();
if (m.getName().compareTo("close")==0) {
close();
} else {
result = m.invoke(rs, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
} finally {
}
return result;
}
}
// How to call it:
ResultSet prs = (ResultSet) MyResultSet.newInstance(rs,ps);
I really appreciated #CoronA's answer. I also looked at #Mark Cramer's answer, but, if I'm not missing something, I think that there are always at least two instances of the "proxified" class with a strange relationship beteen the two objects.
This, along with the fact that cglib is now deprecated, pushed me to find a new implementation based on ByteBuddy.
This is what I came up with:
public class MyClass {
public String testMethod() {
return "11111";
}
public String testMethod2() {
return "aaaaa";
}
}
public class MyClassWithDelegate extends MyClass {
private static final Constructor<? extends MyClassWithDelegate> CONSTRUCTOR_WITH_DELEGATE;
static {
Constructor<? extends MyClassWithDelegate> temp = null;
try {
final var instrumentedMyClassWithDelegateType =
new ByteBuddy()
.subclass(MyClassWithDelegate.class)
.method(ElementMatchers.any())
.intercept(MethodDelegation.to(MethodInterceptor.class))
.make()
.load(MyClassWithDelegate.class.getClassLoader())
.getLoaded();
temp = instrumentedMyClassWithDelegateType.getConstructor(MyClass.class);
} catch (final Exception e) {
LOGGER.error("Cannot instrument class {}", MyClassWithDelegate.class, e);
}
CONSTRUCTOR_WITH_DELEGATE = temp;
}
public static MyClassWithDelegate getInstanceWithDelegate(final MyClass myClass) {
try {
return CONSTRUCTOR_WITH_DELEGATE.newInstance(myClass);
} catch (final Exception e) {
LOGGER.error("Cannot get instance of {}", MyClassWithDelegate.class, e);
throw new IllegalStateException();
}
}
private final boolean initialized;
private final MyClass delegate;
public MyClassWithDelegate(final MyClass delegate) {
super();
this.delegate = delegate;
this.initialized = true;
}
public String testMethod() {
return "22222";
}
public static class MethodInterceptor {
#RuntimeType
public static Object intercept(#This final MyClassWithDelegate self,
#Origin final Method method,
#AllArguments final Object[] args,
#SuperMethod final Method superMethod) throws Throwable {
if (!self.initialized || method.getDeclaringClass().equals(MyClassWithDelegate.class)) {
return superMethod.invoke(self, args);
} else {
return method.invoke(self.delegate, args);
}
}
}
}
The initialized field is used to prevent method calls the super constructor from being redirected to the delegate before its assignment (in this case it wouldn't be a problem, but I wanted to create a generic solution).
Every method called on an instance of MyClassWithDelegate will be redirected to the delegate, except from methods declared inside MyClassWithDelegate itself.
In this example, calling testMethod() on an instance of MyClassWithDelegate will return "22222", while testMethod2() will return "aaaaa".
Obviously, the delegation will actually work only if every instance of MyClassWithDelegate is obtained calling the getInstanceWithDelegate factory method.

Is there a way in Java to call a different hashCode() for an interface representation of an object

I've been dealing with a domain issue where I have classes that implement a common interface and I want to be able to get hashes from these objects differently depending on if the object is accessed as an interface or as a concrete class instance. Basically what I want is the following:
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
public class B implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
public class C implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int Bar.hashCode(){ return 123;}
}
Bar interfaceObject = new A();
interfaceObject.hashCode(); //return 123
Bar aObject = new A();
aObject.hashCode();// return 1
As far as I know there isn't a way to do this, and I can think of lots of reasons why this could cause issues, but I wanted to ask those smarter than I if they had any nice ways of doing this outside of making the interface have a function like public int getCustomHashCodeForJustThisInterface(). I like being able to use these objects in hashMaps without having to jump through hoops, but with their current implementation of hashCode they would break, since these objects can have multiple views of their identity depending on how they are used, and I don't want to change their base implementation of hashCode;
You can't do that, because Java does not support non-polymorphic instance methods (static methods are not polymorphic, as the previous answer showed).
What you can do is to make your classes not directly implement Bar, but another interface (e.g. BarProvider) with a toBar() or getBar() method, which returns a custom object of type Bar, which behaves as you want.
public class A implements BarProvider{
#Override
public int hashCode(){ return 1;}
#Override
public Bar toBar() {
return new Bar() {
#Override
public int hashCode() { return 123; }
};
}
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
Bar interfaceObject = aObject.toBar();
interfaceObject.hashCode(); // return 123
Several improvements are possible, such as having the Bar object stored as a final field (to avoid multiple initializations), and having a reverse reference that allows you to get back from the Bar to its BarProvider.
Another possibility is to use an external provider, that makes your computations
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
}
public final class BarHasher implements Hasher<Bar> }
#Override
public int hashFor(Bar object) { return 123; }
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
BarHasher.hashFor(aObject); // return 123
or a static method that calls some other method
public class A implements Bar{
#Override
public int hashCode(){ return 1;}
#Override
public int hashAsBar() { return 123; }
}
public interface BarHasher implements Hasher<Bar> {
#Override
public int hashFor(Bar object) { return object.hashAsBar(); }
}
A aObject = new A();
interfaceObject.hashCode(); //return 1;
BarHasher.hashFor(aObject); // return 123
In case you don't know it, what you're trying to do is possible (and it's the default behavior) in C++ (you must declare methods as virtual to have the same behavior as Java) and in C# (but you will have a warning, unless you use the modifier new on the overriding method)
There's no way to do this that I know of.
Here's something you can do that you may not have known of (I'm not suggesting this is a good idea):
package com.sandbox;
import java.io.IOException;
public class Sandbox {
public static void main(String[] args) throws IOException {
A.speak();
B.speak();
A a = new A();
a.speak(); //my ide rightly gives a warning here. static function accessed through instance
A b = new B();
b.speak(); //my ide rightly gives a warning here. static function accessed through instance
}
public static class A {
public static void speak() {
System.out.println("A");
}
}
public static class B extends A {
public static void speak() {
System.out.println("B");
}
}
}
This will print:
A
B
A
A
Just to reiterate: This is NOT a good idea. I'm just letting you know for educational purposes.
It's easy to invoke different methods based on the declared type of a variable. That's called overriding, and here's an example of it:
public class Example {
public static void main(String[] argv) throws Exception {
Integer v1 = 12;
Number v2 = v1;
System.out.println(v1.hashCode() + " -> " + new KeyWrapper(v1).hashCode());
System.out.println(v2.hashCode() + " -> " + new KeyWrapper(v2).hashCode());
}
private static class KeyWrapper {
private Object obj;
private int hash;
public KeyWrapper(Integer v) {
this.hash = v.hashCode() * 3;
}
public KeyWrapper(Number v) {
this.hash = v.hashCode() * 5;
}
#Override
public int hashCode() {
return hash;
}
}
}
When you run this, you get the following output:
12 -> 36
12 -> 60
Why this is a bad idea is that you can't implement equals() in in a way that preserves its contract (which is that two equal objects must have equal hashcodes). At compile-time you have information about how the values are referenced, but at runtime you only know what they are.
That said, if you want to use different hashcode calculations for objects that do implement an interface, versus those that don't, you can write a KeyWrapper that uses instanceof.
public class Example {
public static void main(String[] argv) throws Exception {
Integer v1 = 12;
String v2 = "foo";
System.out.println(v1.hashCode() + " -> " + new KeyWrapper(v1).hashCode());
System.out.println(v2.hashCode() + " -> " + new KeyWrapper(v2).hashCode());
}
private static class KeyWrapper {
private Object wrapped;
public KeyWrapper(Object obj) {
this.wrapped = obj;
}
#Override
public boolean equals(Object obj) {
return wrapped.equals(obj);
}
#Override
public int hashCode() {
return (wrapped instanceof Number) ? wrapped.hashCode() * 3 : wrapped.hashCode() * 5;
}
}
}
This, of course, doesn't care about the declared type of the variable, only its actual type.

How to get class object without an instance or class name

I have an abstract class MyClass with a static method to populate given collection with a number of MyClassDescendant objects. This method should call a static getRandom() method of MyClassDescendant to get object instances.
My current code looks like this:
public static void populate(Collection<MyClass> coll, Class<? extends MyClass> cl, int num) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
for (int i = 0; i < num; i++) {
Method m;
m = cl.getMethod("getRandom");
coll.add((MyClass)(m.invoke(null)));
}
}
Then I call it like that:
MyClass.populate((Collection<MyClass>)(Collection<?>)collection, MyClassDescendant.class, 3);
This code works, but it's ugly. What I actually wanted to achieve would look like this:
MyClassDescendant.populate(collection, 3);
If it wasn't a static method, I'd just use this.getClass(). I know that MyClass.class would work for static method, but I don't want class for MyClass, but for specific MyClassDescendant (there are few descendant types).
Is there any way to get class object without having its instance or class name?
Since you are in a static context you'll have to duplicate some code, but you can do delegation.
public class MyClassDescendant extends MyClass {
public static void populate(Collection<MyClass> coll, int count) {
MyClass.populate(coll, MyClassDescendant.class, count);
}
}
Now you can call
MyClassDescendant.populate(collection, 3);
Try restructuring your method in this way:
public static <T extends Base> void populate(Collection<T> coll, int num) throws Exception{
for (T item : coll) {
Method m;
m = item.getClass().getMethod("getRandom");
coll.add((T)(m.invoke(null)));
}
}
With regards to one the comments, you can also use the template method design pattern to utilize inheritance for your getRandom() method by making it abstract and calling it within your populate method.
If get random is a static method couldn't you just call it?
public interface MyClassInterface {
MyClass getRandom();
}
public abstract class MyClass implements MyClassInterface {
public static void populate(Collection<MyClass> coll, int num) {
for (int i = 0; i < num; i++) {
coll.add((MyClass)MyClassDescendant.getRandom());
}
}
}
public class MyClassDescendant extends MyClass {
public MyClass getRandom() {
// implementation of getRandom
}
}

Categories