Errai 2.2.0.Final + Spring (RCP service example)
wendro Feb 7, 2013 5:40 PMIm used to spring over server side and I was unable to rewrite my apps to guice. I made myself a helper class which registers rcp services which are spring (3.1.3) beans to errai bus (2.2.0.Final).
@Component public class ErraiApplicationListener implements ApplicationListener<ContextRefreshedEvent> { @InjectLogger Logger logger; boolean initialized = false; public void onApplicationEvent(ContextRefreshedEvent event) { if(!initialized) { logger.info("Collecting beans..."); final List<Pair<Class<?>, Object>> beans = new ArrayList<Pair<Class<?>, Object>>(); for(Object type : event.getApplicationContext().getBeansWithAnnotation(org.jboss.errai.bus.server.annotations.Service.class).values()) { for(Class<?> intf : type.getClass().getInterfaces()) { if(intf.isAnnotationPresent(org.jboss.errai.bus.server.annotations.Remote.class)) { logger.info("Found " + type.getClass().getName() + " bean with remote " + intf.getName() + "."); beans.add(new Pair<Class<?>, Object>(intf, type)); } } } logger.info("Collected " + beans.size() + " beans."); ErraiServiceSingleton.registerInitCallback(new ErraiServiceSingleton.ErraiInitCallback() { @Override public void onInit(ErraiService service) { logger.info("Registering " + beans.size() + " beans."); for(Pair<Class<?>, Object> pair : beans) { logger.info("Registering " + pair.getSecond().getClass().getName() + " bean with remote " + pair.getFirst().getName() + "."); register(service, pair.getFirst(), pair.getSecond()); } logger.info("Registered."); } }); } } /** * Method produced based on @link{org.jboss.errai.bus.server.service.ServiceProcessor}. * * @param service * @param remoteIntf * @param type */ private void register(ErraiService service, final Class<?> remoteIntf, final Object svc) { final ServerMessageBus bus = ErraiServiceSingleton.getService().getBus(); final ErraiServiceConfiguratorImpl config = (ErraiServiceConfiguratorImpl) ErraiServiceSingleton.getService().getConfiguration(); final Map<String, MessageCallback> epts = new HashMap<String, MessageCallback>(); // beware of classloading issues. better reflect on the actual instance for (Class<?> intf : svc.getClass().getInterfaces()) { for (final Method method : intf.getMethods()) { if (RebindUtils.isMethodInInterface(remoteIntf, method)) { epts.put(RebindUtils.createCallSignature(intf, method), new ConversationalEndpointCallback( new ServiceInstanceProvider() { @Override public Object get(Message message) { return svc; } }, method, bus)); } } } bus.subscribe(remoteIntf.getName() + ":RPC", new RemoteServiceCallback(epts)); // note: this method just exists because we want // AbstractRemoteCallBuilder to be package private. DefaultRemoteCallBuilder.setProxyFactory(Assert.notNull(new ProxyFactory() { @Override public <T> T getRemoteProxy(Class<T> proxyType) { throw new RuntimeException("There is not yet an available Errai RPC implementation for the server-side environment."); } })); } }
Add this class to project where component scan will catch it. Then just add interface and service bean as you would with regular errai.
import org.jboss.errai.bus.server.annotations.Remote; @Remote public interface WorkflowService { // ... }
import org.jboss.errai.bus.server.annotations.Service; @Component @Service public class WorkflowServiceImpl implements WorkflowService { @Autowired InternalCommonBean common; // ... }
Maybe someone will enjoy cheers...
If u leave me some I will start participating more.