alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (Server.java)

This example Glassfish source code file (Server.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

arraylist, arraylist, builder, container, container, embeddedfilesystem, glassfish, io, lifecycleexception, list, log, logging, server, server, string, string, t, util

The Glassfish Server.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2009-2011 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.internal.embedded;

import com.sun.hk2.component.ExistingSingletonInhabitant;
import org.glassfish.api.container.Sniffer;
import org.glassfish.embeddable.*;
import org.jvnet.hk2.annotations.Contract;
import org.jvnet.hk2.component.Habitat;
import org.jvnet.hk2.component.Inhabitant;
import org.jvnet.hk2.component.Inhabitants;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;



/**
 * Instances of server are embedded application servers, capable of attaching various containers
 * (entities running users applications).
 *
 * @author Jerome Dochez
 */
@Contract
public class Server {

    /**
     * Builder for creating embedded server instance. Builder can be used to configure
     * the logger, the verbosity and the embedded file system which acts as a
     * virtual file system to the embedded server instance.
     */
    public static class Builder {
        final String serverName;
        boolean loggerEnabled;
        boolean verbose;
        File loggerFile;
        EmbeddedFileSystem fileSystem;
        int jmxPort = 0;

        /**
         * Creates an unconfigured instance. The habitat will be obtained
         * by scanning the inhabitants files using this class's classloader
         *
         * @param id the server name
         */
        public Builder(String id) {
            this.serverName = id;
        }

        /**
         * Enables or disables the logger for this server
         *
         * @param enabled true to enable, false to disable
         * @return this instance
         */
        public Builder logger(boolean enabled) {
            loggerEnabled = enabled;
            return this;
        }

        /**
         * Sets the log file location
         *
         * @param f a valid file location
         * @return this instance
         */
        public Builder logFile(File f) {
            loggerFile = f;
            return this;
        }

        /**
         * Turns on of off the verbose flag.
         *
         * @param b true to turn on, false to turn off
         * @return this instance
         */
        public Builder verbose(boolean b) {
            this.verbose = b;
            return this;
        }

        /**
         * Set the jmx port number. Also enables the jmx connector. This applies
         * only when the default configuration is being used.
         * 
         * @param portNumber jmx port number.
         * @return this instance
         */
        public Builder jmxPort(int portNumber) {
            this.jmxPort = portNumber;
            return this;
        }

        /**
         * Sets the embedded file system for the application server, used to locate
         * important files or directories used through the server lifetime.
         *
         * @param fileSystem a virtual filesystem
         * @return this instance
         */
        public Builder embeddedFileSystem(EmbeddedFileSystem fileSystem) {
            this.fileSystem = fileSystem;
            return this;
        }
        /**
         * Uses this builder's name to create or return an existing embedded
         * server instance.
         * The embedded server will be using the configured parameters
         * of this builder. If no embedded file system is used, the embedded instance will use
         * a temporary instance root with a default basic configuration. That temporary instance
         * root will be deleted once the server is shutdown.
         *
         * @return the configured server instance
         */
        public Server build() {
            return build(null);
        }

        /**
         * Uses this builder's name to create or return an existing embedded
         * server instance.
         * The embedded server will be using the configured parameters
         * of this builder. If no embedded file system is used, the embedded instance will use
         * a temporary instance root with a default basic configuration. That temporary instance
         * root will be deleted once the server is shutdown.
         *
         * @param properties extra creation properties
         *
         * @return the configured server instance
         */
        public Server build(Properties properties) {
            synchronized(servers) {
                if (!servers.containsKey(serverName)) {
                    Server s = new Server(this, properties);
                    servers.put(serverName, s);
                    return s;
                }
                throw new IllegalStateException("An embedded server of this name already exists");
            }
        }
    }

    private final static class ContainerStatus {

        int status=0;

        private void started() { status=1; }
        private void stopped() { status=0; }
        private boolean isStopped() {
            return status==0;
        }
        private boolean isStarted() {
            return status==1;
        }
    }

    private final static class Container {
        private final EmbeddedContainer container;
        boolean started;

        private Container(EmbeddedContainer container) {
            this.container = container;
        }
        
    }

    private final static Map<String, Server> servers = new HashMap();

    private final String serverName;
    private final boolean loggerEnabled;
    private final boolean verbose;
    private final File loggerFile;
    private final int jmxPort;
    private final ContainerStatus status = new ContainerStatus();
    private final Inhabitant<EmbeddedFileSystem> fileSystem;
    private final Habitat habitat;
    private final List<Container> containers = new ArrayList();
    private final GlassFish glassfish;
    private static GlassFishRuntime glassfishRuntime;

    private static final Logger logger = Logger.getAnonymousLogger();

    private void setBootstrapProperties(BootstrapProperties props, EmbeddedFileSystem fs) {
        props.setProperty("GlassFish_Platform", "Static");
        if (fs != null) {
            String instanceRoot = fs.instanceRoot != null ? fs.instanceRoot.getAbsolutePath() : null;
            String installRoot = fs.installRoot != null ? fs.installRoot.getAbsolutePath() : instanceRoot;
            if (installRoot != null) {
                props.setInstallRoot(installRoot);
            }
        }
    }

    private void setGlassFishProperties(GlassFishProperties props, EmbeddedFileSystem fs) {
        props.setProperty("-type", "EMBEDDED");
        props.setProperty("org.glassfish.persistence.embedded.weaving.enabled", "false");
        if (fs != null) {
            String instanceRoot = fs.instanceRoot != null ? fs.instanceRoot.getAbsolutePath() : null;
            if (instanceRoot != null) {
                props.setInstanceRoot(fs.instanceRoot.getAbsolutePath());
            }
            if (fs.configFile != null) {
                props.setConfigFileURI(fs.configFile.toURI().toString());
            }
            if (fs.autoDelete) {
                props.setProperty("org.glassfish.embeddable.autoDelete", "true");
            }
        }
        // TODO :: Support modification of jmxPort
    }
    
    private Server(Builder builder, Properties properties) {
        serverName = builder.serverName;
        loggerEnabled = builder.loggerEnabled;
        verbose = builder.verbose;
        loggerFile = builder.loggerFile;
        jmxPort = builder.jmxPort;

        try {
            if(properties == null) {
                properties = new Properties();
            }
            EmbeddedFileSystem fs = builder.fileSystem;
            BootstrapProperties bootstrapProps = new BootstrapProperties(properties);
            setBootstrapProperties(bootstrapProps, fs);
            glassfishRuntime = GlassFishRuntime.bootstrap(bootstrapProps, getClass().getClassLoader());

            GlassFishProperties gfProps = new GlassFishProperties(properties);
            setGlassFishProperties(gfProps, fs);
            glassfish = glassfishRuntime.newGlassFish(gfProps);
            glassfish.start();
            
            if(fs == null) {
                EmbeddedFileSystem.Builder fsBuilder = new EmbeddedFileSystem.Builder();
                fsBuilder.autoDelete(true);
                fs = fsBuilder.build();
            }
            
            // Add the neccessary inhabitants.
            habitat = glassfish.getService(Habitat.class);
            habitat.add(Inhabitants.create(this));
            fileSystem = new ExistingSingletonInhabitant<EmbeddedFileSystem>(fs);
            habitat.addIndex(fileSystem, EmbeddedFileSystem.class.getName(), null);
            
            logger.logp(Level.FINER, "Server", "<init>", "Created GlassFish = {0}, " +
                    "GlassFish Status = {1}", new Object[]{glassfish, glassfish.getStatus()});
        } catch (Throwable ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * Returns the list of existing embedded instances
     *
     * @return list of the instanciated embedded instances.
     */
    public static List<String> getServerNames() {
        List<String> names = new ArrayList();
        names.addAll(servers.keySet());
        return names;
    }

    /**
     * Returns the embedded server instance of a particular name
     *
     * @param name requested server name
     * @return a server instance if it exists, null otherwise
     */
    public static Server getServer(String name) {
        return servers.get(name);
    }

    // todo : have the same name, and make it clear we use the type string().

    /**
     * Get the embedded container configuration for a container type.
     * @param type the container type (e.g. Type.ejb)
     * @return the embedded configuration for this container
     */
    public ContainerBuilder<EmbeddedContainer> createConfig(ContainerBuilder.Type type) {
        return createConfig(type.toString());
    }

    /**
     * Get the embedded container builder for a container type identified by its
     * name.
     * @param name the container name, which is the name used on the @Service annotation
     * @return the embedded builder for this container
     */
    @SuppressWarnings("unchecked")
    public ContainerBuilder<EmbeddedContainer> createConfig(String name) {
        return habitat.getComponent(ContainerBuilder.class, name);
    }

    /**
     * Get an embedded container configuration. The type of the expected
     * configuration is passed to the method and is not necessarily known to
     * the glassfish embedded API. This type of configuration is used for
     * extensions which are not defined by the core glassfish project.
     *
     * The API stability of the interfaces returned by this method is outside the
     * scope of the glassfish-api stability contract, it's a private contract
     * between the provider of that configuration and the user.
     *
     * @param configType the type of the embedded container configuration
     * @param <T> type of the embedded container
     * @return the configuration to configure a container of type <T>
     */
    public <T extends ContainerBuilder T createConfig(Class configType) {
        return habitat.getComponent(configType);        
    }

    /**
     * Adds a container of a particular type using the default operating
     * configuration for the container.
     *
     * @param type type of the container to be added (like web, ejb).
     * @throws IllegalStateException if the container is already started.
     */
    public synchronized void addContainer(final ContainerBuilder.Type type) {

        if (status.isStarted()) {
            throw new IllegalStateException("Cannot add container to a started embedded instance");
        }
        containers.add(new Container(new EmbeddedContainer() {

            final List<Container> delegates = new ArrayList();
            final ArrayList<Sniffer> sniffers = new ArrayList();

            public List<Sniffer> getSniffers() {
                synchronized(sniffers) {
                    if (sniffers.isEmpty()) {
                        if (type == ContainerBuilder.Type.all) {
                            for (final ContainerBuilder.Type t : ContainerBuilder.Type.values()) {
                                if (t!=ContainerBuilder.Type.all) {
                                    delegates.add(getContainerFor(t));
                                }
                            }
                        } else {
                            delegates.add(getContainerFor(type));
                        }
                    }
                    for (Container c : delegates) {
                        sniffers.addAll(c.container.getSniffers());
                    }
                }
                return sniffers;
            }

            public void bind(Port port, String protocol)  {
                for (Container delegate : delegates) {
                    delegate.container.bind(port, protocol);
                }
            }

            private Container getContainerFor(final ContainerBuilder.Type type) {
                ContainerBuilder b = createConfig(type);
                if (b!=null) {
                    return new Container(b.create(Server.this));
                } else {
                    return new Container(new EmbeddedContainer() {

                        public List<Sniffer> getSniffers() {
                            List<Sniffer> sniffers = new ArrayList();
                            Sniffer s = habitat.getComponent(Sniffer.class, type.toString());
                            if (s!=null) {
                                sniffers.add(s);
                            }
                            return sniffers;
                        }

                        public void bind(Port port, String protocol) {

                        }

                        public void start() throws LifecycleException {

                        }

                        public void stop() throws LifecycleException {

                        }

                    });
                }
            }

            public void start() throws LifecycleException {
                for (Container c : delegates) {
                    if (!c.started) {
                        c.container.start();
                        c.started=true;
                    }
                }
            }

            public void stop() throws LifecycleException {
                for (Container c : delegates) {
                    if (c.started) {
                        c.container.stop();
                        c.started=false;
                    }
                }

            }

        }));
    }



    // todo : clarify that adding containers after the server is created is illegal
    // todo : makes the return of those APIs return void.

    /**
     * Adds a container to this server.
     *
     * Using the configuration instance for the container of type <T>,
     * creating the container from that configuration and finally adding the
     * container instance to the list of managed containers
     *
     * @param info the configuration for the container
     * @param <T> type of the container
     * @return instance of the container <T>
     * @throws IllegalStateException if the container is already started.
     */
    public synchronized <T extends EmbeddedContainer> T addContainer(ContainerBuilder info) {
        if (status.isStarted()) {
            throw new IllegalStateException("Cannot add containers to an already started embedded instance");
        }
        T container = info.create(this);
        if (container!=null && containers.add(new Container(container))) {
            return container;
        }
        return null;

    }


    /**
     * Returns a list of the currently managed containers
     *
     * @return the containers list
     */
    public Collection<EmbeddedContainer> getContainers() {
        ArrayList<EmbeddedContainer> copy = new ArrayList();
        for (Container c : containers) {
            copy.add(c.container);
        }
        return copy;        
    }

    /**
     * Creates a port to attach to embedded containers. Ports can be attached to many
     * embedded containers and some containers may accept more than one port.
     *
     * @param portNumber port number for this port
     * @return a new port abstraction.
     * @throws IOException if the port cannot be opened.
     */
    public Port createPort(int portNumber) throws IOException {
        Ports ports = habitat.getComponent(Ports.class);
        return ports.createPort(portNumber);
    }

    /**
     * Returns the configured habitat for this server.
     *
     * @return the habitat
     */
    public Habitat getHabitat() {
        return habitat;
    }

    /**
     * Returns the server name, as specified in {@link Server.Builder#Builder(String)}
     *
     * @return container name
     */
    public String getName(){
        return serverName;
    }

    /**
     * Returns the embedded file system used to run this embedded instance.
     *
     * @return embedded file system used by this instance
     */
    public EmbeddedFileSystem getFileSystem() {
        return fileSystem.get();
    }

    /**
     * Starts the embedded server, opening ports, and running the startup
     * services.
     *
     * @throws LifecycleException if the server cannot be started propertly
     */
    public synchronized void start() throws LifecycleException {
        if(glassfish != null) {
            try {
                if (glassfish.getStatus() != GlassFish.Status.STARTED) {
                    glassfish.start();
                }
            } catch (GlassFishException e) {
                throw new LifecycleException(e); // TODO(Sahoo): Proper Exception Handling
            }
            logger.finer("GlassFish has been started");
        }
    }

    /**
     * stops the embedded server instance, any deployed application will be stopped
     * ports will be closed and shutdown services will be ran.
     * EmbeddedFileSystem will be released, meaning that any managed directory will
     * be deleted rendering the EmbeddedFileSystem unusable.
     *
     * @throws LifecycleException if the server cannot shuts down properly
     */
    public synchronized void stop() throws LifecycleException {
        try {
            if (glassfish != null) {
                glassfish.stop();
                logger.finer("GlassFish has been stopped");
            }
            if (glassfishRuntime != null) {
                glassfishRuntime.shutdown();
                logger.finer("GlassFishruntime has been shutdown");
            }
        } catch (Exception ex) {
            logger.log(Level.WARNING, ex.getMessage(), ex);
        } finally {
            synchronized(servers) {
                servers.remove(serverName);
            }
            fileSystem.get().preDestroy();
        }
    }

    /**
     * Returns the embedded deployer implementation, can be used to
     * generically deploy applications to the embedded server.
     *
     * @return embedded deployer
     */
    public EmbeddedDeployer getDeployer() {
        return habitat.getByContract(EmbeddedDeployer.class);
    }


}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish Server.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.