1 Reply Latest reply: Feb 15, 2013 11:01 AM by Jonathan Fuerth RSS

Errai 2.2.0.Final + Spring (RCP service example)

Michal Szymanski Newbie

Im 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.