How to detect what class is used in proxy? - java

For example I have proxy that is proxing interface CashManagment, toString of this proxy is somepackage.CashManagment:Stateless. I would like to know what real classes is being used by this proxy.
I think its EJB. CashManagment has more than one implementation.

As far as I know, java.lang.reflect.Proxy — I'm assuming that's what you're talking about — does not offer any way of discovering what the underlying proxied object is, or its class for that matter. It might be obtainable by using reflection, but that would be dependent on the runtime implementation and thus not a good idea.
If you're using Spring and its proxy mechanisms, then perhaps there is a way to obtain this.

You could introduce a function getType() in the interface, which returns the type of the implementation.

Related

Override equals on a cglib proxy

I would like to use a CGLIB proxy to add my own reusable equals() method to existing objects.
The objects do not necessarily implement any interfaces and I need to be able to cast the proxied object to the original class (without getting the target of the proxy).
Unfortunately, it seems that CGLIB implements its own equals() method and makes sure that only that method is called: there is a private static class (EqualsInterceptor) whose method intercept() implements a reasonable logic to compare proxied objects.
The problem is that this method, at the end, delegates the comparison to the target objects: I need instead to reuse some logic that is not implemented by the target classes.
Using a standard proxy, I was able to intercept the call to the equals() method and execute my logic. The problem is that these kind of proxies cannot be cast to the original class.
It seems that the only way is to rewrite some classes in the CGLIB library. It does not seem a good idea.
No, this is not possible using cglib.
You can use another library such as Byte Buddy which allows you to intercept equals/hashCode just like any other method.
For disclosure: I am the author of Byte Buddy and a maintainer for cglib which are both Apache 2.0 licensed.

When to use "Dynamic Proxy class" or "standard proxy" pattern?

Why should one use a "Dynamic Proxy class" instead of the "standard proxy" pattern?
What are the disadvantages or advantages of both?
It seems like they both have the same end result, except that they are implemented differently.
Dynamic proxy class
https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html
A dynamic proxy class is a class that implements a list of interfaces
specified at runtime such that a method invocation through one of the
interfaces on an instance of the class will be encoded and dispatched
to another object through a uniform interface. Thus, a dynamic proxy
class can be used to create a type-safe proxy object for a list of
interfaces without requiring pre-generation of the proxy class, such
as with compile-time tools. Method invocations on an instance of a
dynamic proxy class are dispatched to a single method in the
instance's invocation handler, and they are encoded with a
java.lang.reflect.Method object identifying the method that was
invoked and an array of type Object containing the arguments.
Standard proxy pattern https://en.wikipedia.org/wiki/Proxy_pattern
A proxy, in its most general form, is a class functioning as an
interface to something else. The proxy could interface to anything: a
network connection, a large object in memory, a file, or some other
resource that is expensive or impossible to duplicate. In short, a
proxy is a wrapper or agent object that is being called by the client
to access the real serving object behind the scenes. In the proxy
extra functionality can be provided, for example caching when
operations on the real object are resource intensive, or checking
preconditions before operations on the real object are invoked. For
the client, usage of a proxy object is similar to using the real
object, because both implement the same interface.
You have appeared to answer your own question. You should use the one which is easier to implement for your use case.
You need to dynamic proxy when you do not have an implementation for each method at compile time.
For example, mocking test libraries use the dynamic proxies so that can write code to handle any method generically.

Java: How to listen on methods invocation without registering each object explicitely?

I want to listen on method calls in order to attach additional behavior dynamically around the call. I've already done it on JUnit methods with a custom annotation and runner. I'm trying to do it on a standard java application.
The main idea is to do:
#Override
public void beforeInvoke (Object self, Method m, Object[] args){
Object[] newargs = modifyArgs (args);
m.invoke (self, newargs);
}
It's just an abstract idea, I don't have any concrete example, but I'm curious if it's possible in java.
I've found some approaches:
java.lang.reflect.Proxy.newProxyInstance(...)
where a proxy is defined for an interface only (but not used to decorate concrete classes). It seems similar to injection pattern and it's a different concern.
Another approach here using a factory pattern with the ProxyFactory class. This other solution requires explicit calls to create() method to produce object proxies listening on method invocations. So, if you bypass it by using natural constructors of your classes, it's not working. It's very constraining if you must explicit a call to a factory each time you have to create an object.
There is a way to do it with transparency ?
Like Proxy.newProxyInstance() but working also on concrete classes ?
Thanks.
Well,this is commonly seen with Spring Framework and Aspect Oriented Programming. Since you delegate your constructor calls to Spring, it is quite easy for Spring to put a proxy in place to intercept calls to the actual objects.
As far as I can tell, the only way to intercept calls is to use a proxy. Either in the way you mentioned or using Spring and AOP.
I think cglib let you instrument concrete classes.
As far as I know there is no easy way to intercept method calls that are called on a concrete class.
As mentioned you could manipulate the bytecode during compilation (as Used in AOP) or at class loading time (as used from cglib).
Another product to instrument Classes would be jmockit (http://jmockit.org/). Usually I would use this special kind of black magic only in testing environments and not in an productive environment.
Another way you could go is Annotation Processing. It work's during compiling process. You have to write a Processor which will walk through your source code and generate source-code that contains the original code plus the enhanced method-calls you need.
Depending on how much source-code you have to enhance, this method might be a good idea, but in general it is a lot of work.
Here's a link (https://deors.wordpress.com/2011/10/08/annotation-processors/).
Despite usually it's used in combination with annotations, this is not a strict requirement.

Java EJB interfaces

Could anyone explain me how do the functions inside the HOME and REMOTE interfaces relate to the Bean object?
The interfaces are instanciated so that the functions are used. But the functions body rests only in the Bean object. What am I missing?
The actual EJB instances will typically be instances of java.lang.reflect.Proxy that delegate calls to the bean's implementation class after doing their transaction-, clustering- and security-stuff.
The Java EE container is dealing with those details for you. It knows to find the bean implementation when a call is made to that interface. It hides all the magic from you.

Test if a Java Interface has been Proxied

Is there a simple way through reflections to test if a Java interface has been proxied?
Use Proxy.isProxyClass()
Proxy.isProxyClass(yourInterface.getClass())
Look at the implementation: Check this.getClass().getName() for generic names or this.getClass().isAssignableFrom(Class<?>) if you have a specific proxy in mind.
Proxy.isProxyClass() might also help (depending on the method used for implementing the proxy.

Categories