I'm trying to create CGLib Proxy for java.net.SocketImpl class using code like:
Enhancer e = new Enhancer();
e.setSuperclass(SocketImpl.class);
e.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object socketImplInstance, Method method, Object[] arguments, MethodProxy methodProxy) throws Throwable {
System.out.println("Got call to " + method.getName());
return methodProxy.invokeSuper(socketImplInstance, arguments);
}
});
SocketImpl socketImpl = (SocketImpl)e.create();
Method m = SocketImpl.class.getDeclaredMethod("getSocket");
m.setAccessible(true);
System.out.println("getSocket: " + m.invoke(socketImpl));
m = SocketImpl.class.getDeclaredMethod("getLocalPort");
m.setAccessible(true);
System.out.println("getLocalPort: " + m.invoke(socketImpl));
As a result of this code I get an output:
getSocket: null
Got call to getLocalPort
getLocalPort: 0
We have no "Got call to getSocket", so SocketImpl#getSocket() has not been intercepted. This method differs from SocketImpl#getLocalPort() only by access level - SocketImpl#getLocalPort() is protected, while SocketImpl#getSocket() is package-private. I have the same behavior with other package-private method SocketImpl#getServerSocket().
I tried to reproduce this error with user class (which is abstract according to SocketImpl), but everything works as expected, if we have:
package userpackage;
public abstract class Abstract {
void testMethod() {}
}
package somethingother;
Enhancer e = new Enhancer();
e.setSuperclass(Abstract.class);
e.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object abstractInstance, Method method, Object[] arguments, MethodProxy methodProxy) throws Throwable {
System.out.println("Got call to " + method.getName());
return methodProxy.invokeSuper(abstractInstance, arguments);
}
});
Abstract abstrct = (Abstract)e.create();
Method m = Abstract.class.getDeclaredMethod("testMethod");
m.setAccessible(true);
System.out.println("testMethod: " + m.invoke(abstrct));
We get output:
Got call to testMethod
testMethod: null
Which is totally fine, this package-private method has been intercepted.
Please, can you help me to understand what's going on on this examples and why do we have different behavior. I have only one guess that it can be related to SecurityManager, but in that case, can you point me the specific case why it doesn't work?
I used CGLib 3.1 and 3.2.0 for tests.