Java.lang.reflect.Proxy Wenn ein anderer Proxy vom Aufruf zurückgegeben wird, führt dies bei der Zuweisung zu ClassCastException

So spiele ich mit Geotools und dachte, ich würde eine ihrer Datenzugriffsklassen vertreten und nachverfolgen, wie sie in ihrem Code verwendet wurde.

Ich habe einen dynamischen Proxy verschlüsselt und eine FeatureSource (Schnittstelle) darin eingebunden, und alles verlief reibungslos. Dann wollte ich mir auch einige der transitiven Objekte ansehen, die von der featureSource zurückgegeben werden, da eine FeatureSource hauptsächlich eine FeatureCollection zurückgibt (FeatureSource entspricht einer SQL-DataSource und eine FeatureCollection einer SQL-Anweisung).

in meinem Aufrufhandler habe ich den Aufruf gerade an das zugrunde liegende Objekt weitergeleitet und dabei die Zielklasse / Methode / Argumente und das Ergebnis ausgegeben. Bei Aufrufen, die eine FeatureCollection (eine andere Schnittstelle) zurückgaben, habe ich dieses Objekt in meinen Proxy eingeschlossen ( die gleiche Klasse, aber eine neue Instanz, sollte das keine Rolle spielen?) und gab sie zurück. BAM! Classcast-Ausnahme:

java.lang.ClassCastException: $Proxy5 cannot be cast to org.geotools.feature.FeatureCollection  
    at $Proxy4.getFeatures(Unknown Source)  
    at MyClass.myTestMethod(MyClass.java:295)  

die Vorwahl:

FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = ... // create the FS
featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) FeatureSourceProxy.newInstance(featureSource, features);
featureSource.getBounds();// ok
featureSource.getSupportedHints();// ok

DefaultQuery query1 = new DefaultQuery(DefaultQuery.ALL);
FeatureCollection<SimpleFeatureType, SimpleFeature> results = featureSource.getFeatures(query1); //<- explosion here

der Proxy:

public class FeatureSourceProxy  implements java.lang.reflect.InvocationHandler {

private Object target;
private List<SimpleFeature> features;

public static Object newInstance(Object obj, List<SimpleFeature> features) {
return java.lang.reflect.Proxy.newProxyInstance(
    obj.getClass().getClassLoader(), 
    obj.getClass().getInterfaces(), 
    new FeatureSourceProxy(obj, features)
);
}

private FeatureSourceProxy(Object obj, List<SimpleFeature> features) {
this.target = obj;
this.features = features;
}

public Object invoke(Object proxy, Method m, Object[] args)throws Throwable{
Object result = null;
try {
    if("getFeatures".equals(m.getName())){ 
        result = interceptGetFeatures(m, args);
    }
    else{
        result = m.invoke(target, args);
    }
} 
catch (Exception e) {
    throw new RuntimeException("unexpected invocation exception: " +  e.getMessage(), e);
} 
return result;
}

private Object interceptGetFeatures(Method m, Object[] args) throws Exception{
    return newInstance(m.invoke(target, args), features);
}

}

Ist es möglich, Proxys von Interfaces dynamisch zurückzugebenvo eine Proxy-Schnittstelle oder mache ich etwas falsch? Prost

Antworten auf die Frage(2)

Ihre Antwort auf die Frage