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;
026import com.google.inject.AbstractModule;
027import com.google.inject.Module;
028import com.google.inject.name.Names;
029
030import sun.rmi.registry.RegistryImpl;
031import sun.rmi.server.UnicastRef;
032
033/**
034 * Starts RMI registry.
035 */
036@XmlRootElement(name = "rmiRegistry")
037public class RmiRegistry extends TopLevelService {
038    /**
039     * Port for RMI registry.
040     *
041     * <p>
042     * By default zero, which means any open port will be used. Use {@link RmiRegistryPort} annotation
043     * to inject selected port.
044     * </p>
045     */
046    @XmlElement
047    private int rmiRegistryPort = 0;
048
049    @Override
050    public Module configure() {
051        return new AbstractModule() {
052            @Override
053            protected void configure() {
054                Registry registry;
055                try {
056                    registry = LocateRegistry.createRegistry(rmiRegistryPort);
057                } catch (RemoteException e) {
058                    throw new RuntimeException("Cannot create RMI registry on port: " + rmiRegistryPort, e);
059                }
060                UnicastRef ref = (UnicastRef) ((RegistryImpl)registry).getRef();
061                final int port = ref.getLiveRef().getPort();
062
063                RmiRegistryPort portProvider = new RmiRegistryPort() {
064                    @Override
065                    public int getPort() {
066                        return port;
067                    }
068                };
069
070                if (getId() != null) {
071                    bind(RmiRegistryPort.class).annotatedWith(Names.named(getId())).toInstance(portProvider);
072                } else {
073                    bind(RmiRegistryPort.class).toInstance(portProvider);
074                }
075            }
076        };
077    }
078}