001/*
002 * Copyright 2013 Atteo.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.atteo.moonshine.jmx;
017
018import java.rmi.RemoteException;
019import java.rmi.registry.LocateRegistry;
020import java.rmi.registry.Registry;
021
022import javax.xml.bind.annotation.XmlElement;
023import javax.xml.bind.annotation.XmlRootElement;
024
025import org.atteo.moonshine.TopLevelService;
026
027import com.google.inject.AbstractModule;
028import com.google.inject.Module;
029import com.google.inject.name.Names;
030
031import sun.rmi.registry.RegistryImpl;
032import sun.rmi.server.UnicastRef;
033
034/**
035 * Starts RMI registry.
036 */
037@XmlRootElement(name = "rmiRegistry")
038public class RmiRegistry extends TopLevelService {
039    /**
040     * Port for RMI registry.
041     *
042     * <p>
043     * By default zero, which means any open port will be used. Use {@link RmiRegistryPort} annotation
044     * to inject selected port.
045     * </p>
046     */
047    @XmlElement
048    private int rmiRegistryPort = 0;
049
050    @Override
051    public Module configure() {
052        return new AbstractModule() {
053            @Override
054            protected void configure() {
055                Registry registry;
056                try {
057                    registry = LocateRegistry.createRegistry(rmiRegistryPort);
058                } catch (RemoteException e) {
059                    throw new RuntimeException("Cannot create RMI registry on port: " + rmiRegistryPort, e);
060                }
061                UnicastRef ref = (UnicastRef) ((RegistryImpl)registry).getRef();
062                final int port = ref.getLiveRef().getPort();
063
064                RmiRegistryPort portProvider = new RmiRegistryPort() {
065                    @Override
066                    public int getPort() {
067                        return port;
068                    }
069                };
070
071                if (getId() != null) {
072                    bind(RmiRegistryPort.class).annotatedWith(Names.named(getId())).toInstance(portProvider);
073                } else {
074                    bind(RmiRegistryPort.class).toInstance(portProvider);
075                }
076            }
077        };
078    }
079}