All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.ejb.embedded.EJBContainerProviderImpl Maven / Gradle / Ivy

There is a newer version: 7.2024.1.Alpha1
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2009-2016 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.
 */
// Portions Copyright [2019-2021] Payara Foundation and/or affiliates

package org.glassfish.ejb.embedded;

import com.sun.enterprise.deploy.shared.ArchiveFactory;
import com.sun.enterprise.deployment.EjbBundleDescriptor;
import com.sun.enterprise.module.bootstrap.Which;
import com.sun.enterprise.security.EmbeddedSecurity;
import com.sun.enterprise.util.i18n.StringManager;
import com.sun.logging.LogDomains;
import org.glassfish.api.container.Sniffer;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.deployment.common.DeploymentUtils;
import org.glassfish.deployment.common.GenericAnnotationDetector;
import org.glassfish.deployment.common.ModuleDescriptor;
import org.glassfish.ejb.deployment.io.EjbDeploymentDescriptorFile;
import org.glassfish.embeddable.BootstrapProperties;
import org.glassfish.embeddable.GlassFish;
import org.glassfish.embeddable.GlassFishProperties;
import org.glassfish.embeddable.GlassFishRuntime;
import org.glassfish.hk2.api.ServiceLocator;

import jakarta.ejb.EJBException;
import jakarta.ejb.embeddable.EJBContainer;
import jakarta.ejb.spi.EJBContainerProvider;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * GlassFish implementation of the EJBContainerProvider.
 *
 * @author Marina Vatkina
 */
public class EJBContainerProviderImpl implements EJBContainerProvider {

    private static final String GF_PROVIDER_NAME = EJBContainerProviderImpl.class.getName();

    private static final String GF_EJB_EMBEDDED_PROPERTY_START = "org.glassfish.ejb.embedded.";

    protected static final String KEEP_TEMPORARY_FILES = GF_EJB_EMBEDDED_PROPERTY_START + "keep-temporary-files";

    private static final String SKIP_CLIENT_MODULES = GF_EJB_EMBEDDED_PROPERTY_START + "skip-client-modules";
    private static final String GF_INSTALLATION_ROOT = GF_EJB_EMBEDDED_PROPERTY_START + "glassfish.installation.root";
    private static final String GF_INSTANCE_ROOT = GF_EJB_EMBEDDED_PROPERTY_START + "glassfish.instance.root";
    private static final String GF_DOMAIN_FILE = GF_EJB_EMBEDDED_PROPERTY_START + "glassfish.configuration.file";
    private static final String GF_INSTANCE_REUSE = GF_EJB_EMBEDDED_PROPERTY_START + "glassfish.instance.reuse";
    private static final String GF_WEB_HTTP_PORT = GF_EJB_EMBEDDED_PROPERTY_START + "glassfish.web.http.port";

    private static final String WEAVING = "org.glassfish.persistence.embedded.weaving.enabled";

    private static final Attributes.Name ATTRIBUTE_NAME_SKIP = new Attributes.Name("Bundle-SymbolicName");
    private static final String[] KNOWN_PACKAGES =
            {"org.glassfish.", "com.sun.enterprise.", "org.eclipse.", "org.jboss.weld."};
    private static final String[] ATTRIBUTE_VALUES_OK = {"sample", "test"};


    // Use Bundle from another package
    private static final Logger _logger =
            LogDomains.getLogger(EJBContainerProviderImpl.class, LogDomains.EJB_LOGGER);
    private static final StringManager localStrings =
            StringManager.getManager(EJBContainerProviderImpl.class);

    private static final Object lock = new Object();

    private static EJBContainerImpl container;
    private static GlassFishRuntime runtime;
    private static ArchiveFactory archiveFactory;
    private static Class[] ejbAnnotations = null;

    public EJBContainerProviderImpl() {}

    public EJBContainer createEJBContainer(Map properties) throws EJBException {
        if (properties == null || properties.get(EJBContainer.PROVIDER) == null ||
                properties.get(EJBContainer.PROVIDER).equals(GF_PROVIDER_NAME)) {

            if (container != null && container.isOpen()) {
                throw new EJBException(localStrings.getString(
                        "ejb.embedded.exception_exists_container"));
            }

            boolean ok = false;
            Locations l = getLocations(properties);
            try {
                createContainer(properties, l);
                Set modules = addModules(properties, l);
                if (!DeploymentElement.hasEJBModule(modules)) {
                    _logger.log(Level.SEVERE, "ejb.embedded.no_modules_found");
                } else {
                    container.deploy(properties, modules);
                }
                ok = true;
                return container;
            } catch (EJBException e) {
                throw e;
            } catch (Throwable t) {
                _logger.log(Level.SEVERE, "ejb.embedded.exception_instantiating", t);
                throw new EJBException(t.getMessage());
            } finally {
                if (!ok && container != null) {
                    try {
                        _logger.info("[EJBContainerProviderImpl] Cleaning up on failure ...");
                        container.close();
                    } catch (Throwable t1) {
                        _logger.info("[EJBContainerProviderImpl] Error cleaning up..." + t1);
                    }
                    container = null;
                }
            }
        }

        return null; // not this provider
    }

    private Locations createContainer(Map properties, Locations l) throws EJBException {
        synchronized(lock) {
            // if (container == null || !container.isOpen()) {
            try {
                if (runtime != null) {
                    runtime.shutdown(); // dispose of the old one
                }

                BootstrapProperties bootstrapProperties = new BootstrapProperties();

                // Propagate non EJB embeddable container properties into GlassFishProperties
                Properties newProps = new Properties();
                if (properties != null) {
                    copyUserProperties(properties, newProps);
                }

                // Disable weaving if it is not spesified
                if (newProps.getProperty(WEAVING) == null) {
                    newProps.setProperty(WEAVING, "false");
                }

                GlassFishProperties glassFishProperties = new GlassFishProperties(newProps);
                if (Boolean.getBoolean(KEEP_TEMPORARY_FILES)) {
                    glassFishProperties.setProperty("org.glassfish.embeddable.autoDelete", "false"); // set autodelete to false.
                    glassFishProperties.setConfigFileReadOnly(false); // make sure the domain.xml is written back.
                }

                if (l.installed_root != null && l.instance_root != null) {
                    // Real install
                    _logger.info("[EJBContainerProviderImpl] Using installation location " + l.installed_root.getCanonicalPath());
                    bootstrapProperties.setInstallRoot(l.installed_root.getCanonicalPath());
                }
                if (l.instance_root != null && l.reuse_instance_location) {
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.fine("[EJBContainerProviderImpl] Reusing instance location at: " + l.instance_root);
                    }
                    _logger.info("[EJBContainerProviderImpl] Using instance location: " + l.instance_root.getCanonicalPath());
                    glassFishProperties.setInstanceRoot(l.instance_root.getCanonicalPath());
                } else if (l.domain_file != null) {
                    _logger.info("[EJBContainerProviderImpl] Using config file location: " + l.domain_file.toURI().toString());
                    glassFishProperties.setConfigFileURI(l.domain_file.toURI().toString());
                }
                addWebContainerIfRequested(properties, glassFishProperties);

                runtime = GlassFishRuntime.bootstrap(bootstrapProperties);
                _logger.info("[EJBContainerProviderImpl] Using runtime class: " + runtime.getClass());
                GlassFish server = runtime.newGlassFish(glassFishProperties);
                if (l.instance_root != null && !l.reuse_instance_location) {
                    // XXX Start the server to get the services
                    server.start();
                    EmbeddedSecurity es = server.getService(EmbeddedSecurity.class);
                    ServiceLocator habitat = server.getService(ServiceLocator.class);

                    server.stop();

                    // If we are running from an existing install, copy over security files to the temp instance
                    if (es != null) {
                        es.copyConfigFiles(habitat, l.instance_root, l.domain_file);
                    }
                }

                // server is started in EJBContainerImpl constructor
                container = new EJBContainerImpl(server);

                validateInstanceDirectory();

                archiveFactory = server.getService(ArchiveFactory.class);

                Sniffer sniffer = server.getService(Sniffer.class, "Ejb");
                ejbAnnotations = sniffer.getAnnotationTypes();
            } catch (Exception e) {
                try {
                    if (container != null) {
                        container.stop();
                    }
                } catch (Exception e0) {
                    _logger.log(Level.SEVERE, e0.getMessage(), e0);
                }
                container = null;
                throw new EJBException(e);
            }
            // }
        }

        return l;
    }

    /**
     * Adds EJB modules for the property in the properties Map or if such property
     * is not specified, from the System classpath. Also adds library references.
     */
    private Set addModules(Map properties, Locations l) {
        Set modules = new HashSet();
        Object obj = (properties == null)? null : properties.get(EJBContainer.MODULES);
        boolean skip_module_with_main_class = getBooleanProperty(properties, SKIP_CLIENT_MODULES);
        Map moduleNames = new HashMap();

        // Check EJBContainer.MODULES setting first - it can have an explicit set of files
        if (obj != null) {
            // Check module names first
            if (obj instanceof String) {
                moduleNames.put((String)obj, false);
            } else if (obj instanceof String[]) {
                String[] arr = (String[])obj;
                for (String s : arr) {
                    moduleNames.put(s, false);
                }
            } else if (obj instanceof File) {
                addModule(l, modules, moduleNames, (File)obj);
            } else if (obj instanceof File[]) {
                File[] arr = (File[])obj;
                for (File f : arr) {
                    addModule(l, modules, moduleNames, f);
                }
            }
        }

        if (modules.isEmpty()) {
            // No file is specified - load from the classpath
            String path = System.getProperty("java.class.path");
            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("[EJBContainerProviderImpl] Looking for EJB modules in classpath: " + path);
            }
            String[] entries = path.split(File.pathSeparator);
            for (String s0 : entries) {
                addModule(l, modules, moduleNames, new File(s0), skip_module_with_main_class);
            }

            if (!moduleNames.isEmpty()) {
                StringBuilder sb = new StringBuilder();
                for (Map.Entry entry : moduleNames.entrySet()) {
                    if (!entry.getValue()) {
                        sb.append(entry.getKey()).append(", ");
                    }
                }
                int ln = sb.length();
                if (ln > 0) {
                    // Errors found. Trim the constructed string
                    throw new EJBException("Modules: [" + sb.substring(0, ln-2) + "] do not match an entry in the classpath");
                }
            }
        }

        return modules;
    }

    /**
     * @returns DeploymentElement if this file represents an EJB module or a library.
     * Returns null if it's an EJB module which name is not present in the list of requested
     * module names.
     */
    private DeploymentElement getRequestedEJBModuleOrLibrary(File file, Map moduleNames)
            throws Exception {
        DeploymentElement result = null;
        String fileName = file.getName();
        if (_logger.isLoggable(Level.FINE)) {
            _logger.fine("... Testing ... " + fileName);
        }
        ReadableArchive archive = null;
        InputStream is = null;
        try {
            boolean isEJBModule = false;
            String moduleName = DeploymentUtils.getDefaultEEName(fileName);
            archive = archiveFactory.openArchive(file);
            is = getDeploymentDescriptor(archive);
            if (is != null) {
                isEJBModule = true;
                EjbDeploymentDescriptorFile eddf =
                        new EjbDeploymentDescriptorFile();
                eddf.setXMLValidation(false);
                EjbBundleDescriptor bundleDesc =  (EjbBundleDescriptor) eddf.read(is);
                ModuleDescriptor moduleDesc = bundleDesc.getModuleDescriptor();
                moduleDesc.setArchiveUri(fileName);
                moduleName = moduleDesc.getModuleName();
            } else {
                GenericAnnotationDetector detector =
                    new GenericAnnotationDetector(ejbAnnotations);
                isEJBModule = detector.hasAnnotationInArchive(archive);
            }

            if (_logger.isLoggable(Level.FINE)) {
                _logger.fine("... is EJB module: " + isEJBModule);
                if (isEJBModule) {
                    _logger.fine("... is Requested EJB module [" + moduleName + "]: "
                            + (moduleNames.isEmpty() || moduleNames.containsKey(moduleName)));
                }
            }

            if (!isEJBModule || moduleNames.isEmpty()) {
                result = new DeploymentElement(file, isEJBModule, moduleName);
            } else if (moduleNames.containsKey(moduleName) && !moduleNames.get(moduleName)) {
                // Is a requested EJB module and was not found already
                result = new DeploymentElement(file, isEJBModule, moduleName);
                moduleNames.put(moduleName, true);
            }

            return result;
        } finally {
            if (archive != null)
                archive.close();
            if (is != null)
                is.close();
        }
    }

    /**
     * Adds an a DeploymentElement to the Set of modules if it represents an EJB module or a library.
     */
    private void addModule(Locations l, Set modules, Map moduleNames, File f) {
        addModule(l, modules, moduleNames, f, false);
    }

    /**
     * Adds an a DeploymentElement to the Set of modules if it represents an EJB module or a library.
     * If skip_module_with_main_class is true, ignore the module that contains Main-Class attribute
     * in its manifest file
     */
    private void addModule(Locations l, Set modules, Map moduleNames, File f,
            boolean skip_module_with_main_class) {
        try {
            if (f.exists() && !skipJar(f, l, skip_module_with_main_class)) {

                DeploymentElement de = getRequestedEJBModuleOrLibrary(f, moduleNames);
                if (de != null) {
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.fine("... Added " + ((de.isEJBModule())? "EJB Module" : "library") +
                                " .... " + de.getElement().getName());
                    }
                    modules.add(de);
                }
            }
        } catch (Exception ioe) {
            _logger.log(Level.FINE, "ejb.embedded.io_exception", ioe);
            // skip it
        }
    }

    /**
     * @returns true if this jar is either a GlassFish module jar or one
     * of the other known implementation modules.
     */
    private boolean skipJar(File file, Locations l, boolean skip_module_with_main_class) throws Exception {
        if (file.isDirectory() ) {
            if (!skip_module_with_main_class) {
                // Nothing to check
                return false;
            }
            File m_file = new File(file, "META-INF/MANIFEST.MF");
            if (!m_file.exists()) {
                return false;
            }
            InputStream is = null;
            try {
                is = new FileInputStream(m_file);
                if(containsMainClass(new Manifest(is))) {
                    // Ignore dirs with a Manifest file with a Main-Class attribute
                    _logger.info("... skipping entry with a Manifest file with a Main-Class attribute: " + file.getName());
                    return true;
                } else {
                    return false;
                }
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException ex) {
                        _logger.log(Level.FINE, "Exception while closing Manifest file under "
                                + file + ": ", ex);
                    }
                }
            }
        }

        // Skip jars in the install modules directory
        if (l.modules_dir != null &&
                l.modules_dir.equals(file.getAbsoluteFile().getParentFile().getAbsolutePath())) {
            _logger.info("... skipping module: " + file.getName());
            return true;
        }

        JarFile jf = null;
        try {
            jf = new JarFile(file);
            Manifest m = jf.getManifest();
            if (m != null) {
                if (skip_module_with_main_class && containsMainClass(m)) {
                    // Ignore jars with a Main-Class attribute
                    _logger.info("... skipping entry with a Manifest file with a Main-Class attribute: " + file.getName());
                    return true;
                }

                java.util.jar.Attributes attributes = m.getMainAttributes();
                String value = attributes.getValue(ATTRIBUTE_NAME_SKIP);
                if (value != null) {
                    for (String skipValue : KNOWN_PACKAGES) {
                        if (value.startsWith(skipValue)) {
                            for (String okValue : ATTRIBUTE_VALUES_OK) {
                                // value starts with one of the KNOWN_PACKAGES but contains an okValue further down
                                if (value.indexOf(okValue) > 0) {
                                    // Still OK
                                    return false;
                                }
                            }
                            // Not OK - skip it
                            _logger.info("... skipping entry with a Manifest file with a special attribute: " + file.getName());
                            return true;
                        }
                    }
                }
            }
        } finally {
            if (jf != null) {
                try {
                    jf.close();
                } catch (IOException ex) {
                    _logger.log(Level.FINE, "Exception while closing JarFile "
                            + jf.getName() + ": ", ex);
                }
            }
        }

        return false;
    }

    /**
     * Create a File object from the location and report an error
     * if such file does not exist.
     * Returns null if such file does not exist.
     */
    private File getValidFile(String location, String msg_key) {
        File f = new File(location);
        if (!f.exists()) {
            _logger.log(Level.WARNING, msg_key, location);
            f = null;
        }
        return f;
    }

    /**
     * Returns true if the Manifest file contains Main-Class attribute
     */
    private boolean containsMainClass(Manifest m) {
        if (m != null) {
            java.util.jar.Attributes attributes = m.getMainAttributes();
            String value = attributes.getValue(Attributes.Name.MAIN_CLASS);
            return (value != null && value.length() > 0);
        }

        return false;
    }


    /**
     * Create File objects corresponding to instance root and domain.xml location.
     */
    private Locations getLocations(Map properties) throws EJBException {
        String installed_root_location = null;
        String instance_root_location = null;
        String domain_file_location = null;
        File installed_root = null;
        File instance_root = null;
        File domain_file = null;
        boolean reuse_instance_location = false;

        if (properties != null) {
            // Check if anything is set
            installed_root_location = (String) properties.get(GF_INSTALLATION_ROOT);
            instance_root_location = (String) properties.get(GF_INSTANCE_ROOT);
            domain_file_location = (String) properties.get(GF_DOMAIN_FILE);
            reuse_instance_location = getBooleanProperty(properties, GF_INSTANCE_REUSE);
        }

        if (installed_root_location == null) {
            // Try to calculate installation location relative to
            // the jar that contains this class
            try {
                installed_root_location = Which.jarFile(getClass()).
                        getParentFile().getParentFile().getAbsolutePath();
            } catch (Exception e) {
                _logger.log(Level.SEVERE, "ejb.embedded.cannot_determine_installation_location");
                _logger.log(Level.FINE, e.getMessage(), e);
            }
        }

        if (_logger.isLoggable(Level.FINE)) {
            _logger.fine("[EJBContainerProviderImpl] installed_root_location : " + installed_root_location);
        }
        if (installed_root_location != null) {
            installed_root = getValidFile(installed_root_location, "ejb.embedded.installation_location_not_exists");
            if (installed_root != null) {
                if (instance_root_location == null) {
                    // Calculate location for the domain relative to GF install
                    instance_root_location = installed_root_location
                            + File.separatorChar + "domains"
                            + File.separatorChar + "domain1";
                }

                if (_logger.isLoggable(Level.FINE)) {
                    _logger.fine("[EJBContainerProviderImpl] instance_root_location: " + instance_root_location);
                }
                instance_root = getValidFile(instance_root_location, "ejb.embedded.instance_location_not_exists");
            }
        }
        if (instance_root != null && domain_file_location == null) {
            // Calculate location for the domain.xml relative to GF instance
            domain_file_location = instance_root_location
                    + File.separatorChar + "config"
                    + File.separatorChar + "domain.xml";
        }

        if (_logger.isLoggable(Level.FINE)) {
            _logger.fine("[EJBContainerProviderImpl] domain_file_location : " + domain_file_location);
        }

        if (domain_file_location != null) {
            domain_file = getValidFile(domain_file_location, "ejb.embedded.configuration_file_location_not_exists");
            if (domain_file != null) {
                if (!reuse_instance_location) {
                    File temp_domain_file = null;
                    try {
                        DomainXmlTransformer dxf = new DomainXmlTransformer(domain_file, _logger);
                        boolean keep_ports = (properties == null)? false : ((properties.get(GF_WEB_HTTP_PORT) == null)? false : true);
                        temp_domain_file = dxf.transform(keep_ports);
                    } catch (Exception e) {
                        throw new EJBException(localStrings.getString(
                                "ejb.embedded.exception_creating_temporary_domain_xml_file"), e);
                    }

                    if (temp_domain_file != null) {
                        domain_file = temp_domain_file;
                    } else {
                        throw new EJBException(localStrings.getString(
                                "ejb.embedded.failed_create_temporary_domain_xml_file"));
                    }
                }
            }
        }
        return new Locations(installed_root, instance_root, domain_file, reuse_instance_location);
    }

    private InputStream getDeploymentDescriptor(ReadableArchive archive) throws IOException {
        InputStream dd = archive.getEntry("META-INF/ejb-jar.xml");
        if (dd == null) {
            // Try EJB in a .war file as well
            dd = archive.getEntry("WEB-INF/ejb-jar.xml");
        }
        return dd;
    }

    private void addWebContainerIfRequested(Map properties, GlassFishProperties props) throws EJBException {
        String http_port = (properties == null)? null : (String)properties.get(GF_WEB_HTTP_PORT);
        if (http_port != null) {

            int port = 8080;
            try {
                port = Integer.parseInt(http_port);
            } catch (NumberFormatException e) {
                System.err.println("Using port 8080");
            }
            props.setPort("http-listener-1", port);
        }
    }

    /**
     * Copy user specified properties into a Proprties object that will be used
     * to create GlassFishProperties.
     */
    private void copyUserProperties(Map properties, Properties props) {
        for (Map.Entry entry : properties.entrySet()) {
            Object key = entry.getKey();
            if (key instanceof String) {
                String sk = (String) key;
                if (!sk.startsWith(GF_EJB_EMBEDDED_PROPERTY_START)) {
                    for (String prefix : KNOWN_PACKAGES) {
                        if (sk.startsWith(prefix)) {
                            Object value = entry.getValue();
                            if (value instanceof String) {
                                props.setProperty(sk, (String)value);
                            } else {
                                props.setProperty(sk, value.toString());
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * Returns boolean value whether the original type is String or Boolean
     */
    private boolean getBooleanProperty(Map properties, String key) {
        boolean result = false;
        if (properties != null) {
            Object value = properties.get(key);
            if (value != null) {
                if (value instanceof String) {
                    result = Boolean.valueOf((String)value);
                } else {
                    try {
                        result = (Boolean) value;
                    } catch (Exception e) {}
                }
            }
        }

        return result;
    }

    /**
     * Verifies that instance directory exists and not empty
     */
    private void validateInstanceDirectory() {
        // Verify that the instance was created properly
        File instance_directory = new File(System.getProperty("com.sun.aas.instanceRoot"));
        if (!instance_directory.exists()) {
            throw new IllegalStateException("Unexpected ERROR: Instance directory " + instance_directory + " does not exist");
        } else if (!instance_directory.isDirectory()) {
            throw new IllegalStateException("Unexpected ERROR: Instance directory " + instance_directory + " is not a directory");
        }

        File[] files = instance_directory.listFiles();
        if (files == null || files.length == 0) {
            throw new IllegalStateException("Unexpected ERROR: Instance directory " + instance_directory + " is empty");
        }
    }

    private static class Locations {
        final File installed_root;
        final File instance_root;
        final File domain_file;
        final String modules_dir;
        final boolean reuse_instance_location;

        Locations (File installed_root, File instance_root, File domain_file, boolean reuse_instance_location) {
            this.installed_root  = installed_root;
            this.instance_root  = instance_root;
            this.domain_file  = domain_file;
            if (installed_root != null) {
                modules_dir = (new File(installed_root, "modules")).getAbsolutePath();
            } else {
                modules_dir = null;
            }
            this.reuse_instance_location  = reuse_instance_location;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy