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.