Spring Remoting - RmiServiceExporter

by GarciaPL on Saturday 22 November 2014

I would like to present you very quick cheat sheet about how implement RMI (Remote Method Invocation) [3] which performs the object-oriented equivalent of RPC in Spring using RmiServiceExporter [1] (used to expose RMI interface) and RmiProxyFactoryBean [2] (used to consume RMI interface).

First of all, you must create some interface which will be used to expose your methods [4]

public interface IUser {
        UserDTO retrieveUserById(Long userId);
        UserDTO register(UserDTO user) throws RegisterException;
}

Next provide some implementation for interface IUser in the form of class [5]

public class UserManager implements IUser {
    private IUserDao userDao;
 
    @Transactional(propagation = Propagation.REQUIRED, readOnly = true, rollbackFor = Exception.class)
    public UserDTO retrieveUserById(Long userId) {
        return userDao.retrieveUserById(userId);
    }
 
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
    public UserDTO register(final UserDTO user) throws AVValidationException {
 
        if (user == null) {
            throw new IllegalArgumentException("Wrong params. user cannot be NULL");
        }
 
        return userDao.register(user);
    }
 
    public IUserDao getUserDao() {
        return userDao;
    }
 
    public void setUserDao(final IUserDao userDao) {
        this.userDao = userDao;
    }
}
And of course you must provide XML Bean definition [6].
Next in your XML with Beans you should export RMI using RmiServiceExporter [7].
Now you can use this RMI exposed under service name called JSUserManager after providing definition in XML Bean [8].
Please do not forget about initialization your RMI like below [9].
    private void run() {
        logger.info("creating ctx...");
        final AbstractApplicationContext ctx;
        try {
            ctx = new ClassPathXmlApplicationContext(
                    "/garciapl-service-rmi-ctx.xml"
            );
            logger.info("ctx created; registering shutdown hook");
            ctx.registerShutdownHook();
 
            logger.info("Starting up the application.  Stand by... ;)");
 
            logger.info("Creating MP service...");
            ctx.getBean("userManagerRMI");
 
        } catch (Throwable e) {
            logger.fatal("exception caught during initialization: ", e);
            System.exit(-1);
        }
        logger.info("app is up and running");
 
        synchronized (this) {
            try {
                wait();
            } catch (InterruptedException e) {
                logger.error("wait interrupted", e);
            }
        }
        logger.info("Exiting...");
        System.exit(0);
    }

Reference : [1] Spring Docs - RmiServiceExporter [2] Spring Docs - RmiProxyFactoryBean [3] Oracle Docs - RMI [4] Pastebin - RMI Interface [5] Pastebin - Interface implementation [6] Pastebin - Interface implementation XML Bean [7] Pastebin - RmiServiceExporter [8] Pastebin - RmiProxyFactoryBean [9] Pastebin - Register RMI