what's the best approach to unwrap a dynamic proxy to retrieve the original object beneath?
The dynamic proxy has been created using java.lang.reflect.Proxy.newProxyInstance()
Thank you.
There's no good method: Proxy.getInvocationHandler(proxy) returns handler, but the problem is to extract the original object from the handler. If your handler is an anonymous class, the only way to extract original object is to use reflection and extract original from field named val$something - very ugly method.
Better way is to create non-anonymous handler class with a getter, then you do:
((YourHandler)Proxy.getInvocationHandler(proxy)).getOriginalObject()
Each proxy has an InvocationHandler associated with it. Only the InvocationHandler knows which object (if any) underlies the proxy. If you control the creation of the proxy, then you can supply your own InvocationHandler that will have the extra functionality that you desire (i.e. will be able to disclose the underlying object.) If you don't, then I am afraid you're out of luck.
You can use the Proxy.getInvocationHandler(proxy) method to obtain the original InvocationHandler.
Related
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.
Serialization makes sense as an instance method - an object might reasonably be able to serialize itself. An object should only ever be in a valid state, and all valid states of an object should be permissible to serialize. There is nothing invalid about this idea.
But deserialization does not make sense as an instance method. No part of an object's state should have any bearing on the process of constructing another object from data. There is no class foo such that you need a constructed foo in order to construct a foo.
So my question is, does standard java have a pre-existing set of interfaces/facilities to facilitate static deserialization? If you implement the instance-based approach, your deserialization "just works" (as much as anything does) with anything that works with Java's default deserialization ability.
Is there anything built in, to use classes as factories for objects of that class, constructed from serial data? Is there anything in Java I could pass a class to, such that this facility would know to call some static method to deserialize to construct an object from its flat form?
The deserialization instance method readObject is private. There is no way to call it from the outside. You could call it from one of your instance methods, but that would be very strange and I'd question why you'd be doing that in the first place. You say:
No part of an object's state should have any bearing on the process of constructing another object from data.
True, but I don't see why you think this would be an issue. There's no way you could call readObject from the outside (unless you call it from some other public method, which as I said, is kind of iffy) on an instance that you have already created. When you deserialize, you will most probably be using ObjectInputStream, which will use the no-args constructor to create a new instance, and then will hydrate that object using the data from the stream (when you call ObjectInputStream#readObject). So there is no question of the state of the instance affecting deserialization, because what you get back is an instance created from the serialized data (as Object, but you will then cast it to the concrete type).
In effect, readObject behaves somewhat like a constructor, except that it uses previously-serialized data to create an instance of an object. Extending the analogy, your question wouldn't make sense because you would be asking "Why does creating an object using the constructor have anything to do with the state of the instance?". The question of state doesn't even apply because you don't even have an instance! Similarly, state doesn't come into play with readObject because can never* deserialize and create an instance by using an existing instance.
If you want greater control over serialization, you can override readObject and writeObject from Serializable within your class if you want to handle things in a special way. You can exert greater control over how the data is written out by implementing Externizable and providing implementations for readExternal and writeExternal.
In your second question you're wondering what the "something" is that calls readObject. The "something" is reflection; ObjectInputStream will check to see if the class has a readObject method. If you've provided your own implementation, it will call that. Otherwise it will call defaultReadObject (which contains the logic for default serialization).
As far as built-in factories for deserialization, there isn't anything and I haven't really felt a need something since the standard serialization/deserialization approach seems to work well.
If you want more information on this, I suggest taking a look at the serialization specification for a comprehensive and in-depth view of how Java tackles serialization, and specifically Object Input Classes for your particular question.
*The only way state comes into it is if you do something strange like calling the readObject method from some other instance method (which would have to take in an ObjectInputStream), and then you have custom logic that performs deserialization based on the state of the existing instance. In other words, the only way the object's state has any bearing on deserialization logic is if you explicitly write it that way. Again, as I mentioned before, that would be very strange code, with a whole lot of caveats and of minimal value.
I am trying to use flexjson library. But in my object I have to use:
com.google.api.client.util.DateTime which do not have no parameters constructor. I always get NoSuchMethodException with message: Flexjson will instantiate any protected, private, or public no-arg constructor. I have sources and trying to do something with that, here is the code:
constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
return constructor.newInstance();
Exception is being thrown in clazz.getDeclaredConstructor() due to lacking empty constructor. What is the best approach to find constructor with let's say those signature:
DateTime(long timestamp)?
Have anyone encounter this kind of problem with this library? Maybe you can suggest to use other one. I am using it to serialize objects generated by Google Cloud Endpoints. Maybe I can do that with different approach?
You don't have to change the source code of Flexjson to do this. The way to handle this is to create your own implementation of ObjectFactory and register that for the type you are binding into. From there you can instantiate it however, you desire. It's easiest to subclass BeanObjectFactory and override the method instantiate(). In there you can do whatever you want to create an instance of an object you wish. By subclassing BeanObjectFactory it will take care of binding the individual properties from the JSON into your object using the setter/getter of that object. If your object doesn't support property methods you might find it easier to implement ObjectFactory and manually setting the values on that object from the JSON. There is lots of documentation on the Flexjson website about building ObjectFactories.
Then you can register your ObjectFactory to that data type using:
new JSONDeserializer<SomeObject>()
.use( DateTime.class, new DateTimeObjectFactory() )
.deserialize(json);
In xstream for java, is there a way to deserialize an object by ensuring that it goes thru a specific constructor with parameters?
XStream (or deserialization in general) doesn't call constructors. (Except in the rarely used Pure Java Mode, when it calls the default constructor.)
You need to use the readResolve() method if you want to initialise transient fields.
However you can write your own converter, and then you can do whatever you want. This approach works best if you have one specific class that you want to apply this to.
I'm creating proxies with javassist ProxyFactory. When creating a single proxy all works fine.
However, when I pass a proxied object to the proxying mechanism, it fails with
javassist.bytecode.DuplicateMemberException: duplicate method: setHandler in com.mypackage.Bean_$$_javassist_0_$$_javassist_1
I'm creating the proxies with this:
public Object createProxiedInstance(Object originalInstance) throws Exception {
Class<?> originalClass = instance.getClass();
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(originalClass);
factory.setHandler(new MethodHandler() {..});
Class<T> proxyClass = factory.createClass();
return proxyClass.newInstance();
}
So, how do I create proxies of proxies?
Update: The actual problems is that each proxy implements the ProxyObject which defines setHandler(..) method. So the 2nd proxy is trying to redefine the method, instead of overriding it in the subclass.
The problem was (actually, it's the same with CGLIB - I tried it using commons-proxy) that I should not try to create a proxy class of the proxy class. The second proxy should again be of the original class. So adding the following line resolves the problem:
if (instance instanceof ProxyObject) {
originalClass = originalClass.getSuperclass();
}
And an advice - if you can use some sort of interceptors (like the ones defined in commons-proxy), do it instead of using multiple proxies.
Its a rather late answer but you might still be interested in knowing this:
Javassist proxies are implemented rather naively. In your above code, Javassist will always create a proxy class with the following methods:
A method for any overridable method of the base class
Two methods to (a) get a proxy handler (getHandler) and (b) set a proxy handler (setHandler)
The names of the two latter methods are hardcoded by Javassist and represented by the ProxyObject interface. If you now create a proxy class of a proxy class, Javassist would schedule the creation of ProxyObject's methods twice. Once by the first condition and once by the second condition.
You could avoid this by setting a MethodFilter which specifies to not override the ProxyObject's methods such that javassist would only create the methods by the second condition. However, this would imply that you could not longer set a ProxyObject for the super class proxy without directly accessing the corresponding field via reflection. Therefore, your approach is probably the cleanest.
cglib defines callbacks per class and not per instance such that this problem with cglib is slightly different but results in another conflict.
However, if you want to create proxy classes that do not suffer these shortcomings, you might be interested in my library Byte Buddy which I wrote after getting frustrated working with cglib and javassist when working in corner cases. If you are working with runtime code generation I hope that it might help offer you some flexibility that the other libraries lack.