As mentioned in several comments in https://jira.springsource.org/browse/SOCIAL-268, the problem here is still a matter of Google App Engine not properly handling serialization and deserialization of JDK proxies. Making the aforementioned classes implement Serializable won't fix anything because those types are never serialized; only the proxy is serialized.
Although this remains a bug in GAE, there is a work around: Create a non-JDK proxy for those types and wire them instead of the actual type.
For example, I have the following class:
Code:
public class ConnectionFactoryLocatorPseudoProxy implements ConnectionFactoryLocator, Serializable, BeanFactoryAware {
private BeanFactory beanFactory;
private final String targetBeanName;
public ConnectionFactoryLocatorPseudoProxy(String targetBeanName) {
this.targetBeanName = targetBeanName;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public <A> ConnectionFactory<A> getConnectionFactory(Class<A> apiType) {
return getTargetBean().getConnectionFactory(apiType);
}
@Override
public ConnectionFactory<?> getConnectionFactory(String providerId) {
return getTargetBean().getConnectionFactory(providerId);
}
@Override
public Set<String> registeredProviderIds() {
return getTargetBean().registeredProviderIds();
}
private ConnectionFactoryLocator getTargetBean() {
return (ConnectionFactoryLocator) beanFactory.getBean(targetBeanName);
}
}
And I've wired it in SocialConfig.java like this:
Code:
@Bean
public ConnectionFactoryLocator connectionFactoryLocator() {
return new ConnectionFactoryLocatorPseudoProxy("connectionFactoryLocatorTarget");
}
@Bean
public ConnectionFactoryLocator connectionFactoryLocatorTarget() {
ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();
registry.addConnectionFactory(new TwitterConnectionFactory(environment.getProperty("twitter.consumerKey"),
environment.getProperty("twitter.consumerSecret")));
registry.addConnectionFactory(new FacebookConnectionFactory(environment.getProperty("facebook.clientId"),
environment.getProperty("facebook.clientSecret")));
return registry;
}
Thus the proxy gets wired everywhere it's needed instead of the actual ConnectionFactoryLocator.
Likewise, I have a similar proxy and config for the UsersConnectionRepository bean.
Admittedly, this is a very simplistic approach and was done quickly just to prove that it would work in Google App Engine. There's a lot that could be done to make the proxy class more elegant. But it does represent a workaround for the bug in GAE.