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

org.glassfish.ejb.startup.EjbDeployer Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2006-2014 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 [2016-2020] [Payara Foundation and/or its affiliates]

package org.glassfish.ejb.startup;

import java.security.SecureRandom;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.inject.Inject;
import javax.inject.Provider;

import org.glassfish.api.deployment.DeployCommandParameters;
import org.glassfish.api.deployment.DeploymentContext;
import org.glassfish.api.deployment.MetaData;
import org.glassfish.api.deployment.OpsParams;
import org.glassfish.api.event.EventListener;
import org.glassfish.api.event.Events;
import org.glassfish.api.invocation.RegisteredComponentInvocationHandler;
import org.glassfish.deployment.common.DeploymentException;
import org.glassfish.deployment.common.DeploymentProperties;
import org.glassfish.deployment.common.DeploymentUtils;
import org.glassfish.ejb.deployment.descriptor.EjbBundleDescriptorImpl;
import org.glassfish.ejb.deployment.descriptor.EjbDescriptor;
import org.glassfish.ejb.security.application.EJBSecurityManager;
import org.glassfish.ejb.security.application.EjbSecurityProbeProvider;
import org.glassfish.ejb.security.factory.EJBSecurityManagerFactory;
import org.glassfish.ejb.spi.CMPDeployer;
import org.glassfish.ejb.spi.CMPService;
import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.internal.api.ServerContext;
import org.glassfish.internal.data.ApplicationInfo;
import org.glassfish.internal.data.EngineRef;
import org.glassfish.internal.data.ProgressTracker;
import org.glassfish.internal.deployment.Deployment;
import org.glassfish.internal.deployment.ExtendedDeploymentContext;
import org.glassfish.javaee.core.deployment.JavaEEDeployer;
import org.jvnet.hk2.annotations.Service;

import com.sun.ejb.codegen.StaticRmiStubGenerator;
import com.sun.ejb.containers.EJBTimerService;
import com.sun.ejb.containers.EjbContainerUtilImpl;
import com.sun.enterprise.config.serverbeans.Cluster;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.container.common.spi.util.ComponentEnvManager;
import com.sun.enterprise.deployment.Application;
import com.sun.enterprise.deployment.WebBundleDescriptor;
import com.sun.enterprise.module.bootstrap.StartupContext;
import com.sun.enterprise.security.PolicyLoader;
import com.sun.enterprise.security.ee.SecurityUtil;
import com.sun.enterprise.security.util.IASSecurityException;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.logging.LogDomains;

import fish.payara.enterprise.config.serverbeans.DeploymentGroup;

/**
 * Ejb module deployer.
 *
 */
@Service
public class EjbDeployer extends JavaEEDeployer implements PostConstruct, EventListener {

    @Inject
    protected ServerContext serverContext;

    @Inject
    protected Domain domain;

    @Inject
    protected PolicyLoader policyLoader;

    @Inject
    protected EJBSecurityManagerFactory ejbSecManagerFactory;

    @Inject
    private ComponentEnvManager compEnvManager;

    @Inject
    private Events events;

    @Inject
    StartupContext startupContext;

    private Object lock = new Object();
    private volatile CMPDeployer cmpDeployer = null;

    private static SecureRandom random = new SecureRandom();

    // Property used to persist unique id across server restart.
    static final String APP_UNIQUE_ID_PROP = "org.glassfish.ejb.container.application_unique_id";
    static final String IS_TIMEOUT_APP_PROP = "org.glassfish.ejb.container.is_timeout_application";

    private AtomicLong uniqueIdCounter;

    private static final Logger _logger = LogDomains.getLogger(EjbDeployer.class, LogDomains.EJB_LOGGER, false);

    private static final LocalStringManagerImpl localStrings = new LocalStringManagerImpl(EjbDeployer.class);

    private final EjbSecurityProbeProvider probeProvider = new EjbSecurityProbeProvider();

    @Inject
    Provider registeredComponentInvocationHandlerProvider;

    @Inject
    Provider cmpServiceProvider;

    @Inject
    Provider cmpDeployerProvider;

    /**
     * Constructor
     */
    public EjbDeployer() {
        // Seed a counter used for ejb application unique id generation.
        uniqueIdCounter = new AtomicLong(System.currentTimeMillis());
    }

    @Override
    public void postConstruct() {
        Properties arguments = startupContext.getArguments();
        if (arguments != null) {
            boolean isUpgrade = Boolean.valueOf(arguments.getProperty("-upgrade"));
            if (isUpgrade) {
                // we don't want to register this listener for the upgrade
                // start up
                return;
            }
        }

        events.register(this);
    }

    @Override
    public MetaData getMetaData() {
        return new MetaData(false, new Class[] { EjbBundleDescriptorImpl.class }, new Class[] { Application.class });
    }

    @Override
    public boolean prepare(DeploymentContext dc) {
        EjbBundleDescriptorImpl ejbBundle = dc.getModuleMetaData(EjbBundleDescriptorImpl.class);

        if (ejbBundle == null) {
            String errMsg = localStrings.getLocalString("context.contains.no.ejb", "DeploymentContext does not contain any EJB", dc.getSourceDir());
            throw new RuntimeException(errMsg);
        }

        // Get application-level properties (*not* module-level)
        Properties appProps = dc.getAppProps();

        long uniqueAppId;

        if (!appProps.containsKey(APP_UNIQUE_ID_PROP)) {

            // This is the first time load is being called for any ejb module in an
            // application, so generate the unique id.

            uniqueAppId = getNextEjbAppUniqueId();
            appProps.setProperty(APP_UNIQUE_ID_PROP, uniqueAppId + "");
        } else {
            uniqueAppId = Long.parseLong(appProps.getProperty(APP_UNIQUE_ID_PROP));
        }

        OpsParams params = dc.getCommandParameters(OpsParams.class);
        if (params.origin.isDeploy()) {
            // KEEP_STATE is saved to AppProps in EjbApplication.stop
            String keepStateVal = (String) dc.getAppProps().get(EjbApplication.KEEP_STATE);
            if (keepStateVal != null) {
                // save KEEP_STATE to Application so subsequent to make it available
                // to subsequent deploy-related methods.
                ejbBundle.getApplication().setKeepStateResolved(keepStateVal);
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "EjbDeployer.prepare set keepstate to {0} for application.", ejbBundle.getApplication().getKeepStateResolved());
                }
            }
        }

        Application app = ejbBundle.getApplication();

        if (!app.isUniqueIdSet()) {
            // This will set the unique id for all EJB components in the application.
            // If there are multiple ejb modules in the app, we'll only call it once
            // for the first ejb module load(). All the old
            // .xml processing for unique-id in the sun-* descriptors is removed so
            // this is the only place where Application.setUniqueId() should be called.
            app.setUniqueId(uniqueAppId);
        }

        return super.prepare(dc);
    }

    @Override
    public EjbApplication load(EjbContainerStarter containerStarter, DeploymentContext dc) {
        super.load(containerStarter, dc);

        if (_logger.isLoggable(Level.FINE)) {
            _logger.log(Level.FINE, "EjbDeployer Loading app from: {0}", dc.getSourceDir());
        }
        // Register the EjbSecurityComponentInvocationHandler

        RegisteredComponentInvocationHandler handler = habitat.getService(RegisteredComponentInvocationHandler.class, "ejbSecurityCIH");
        handler.register();

        EjbBundleDescriptorImpl ejbBundle = dc.getModuleMetaData(EjbBundleDescriptorImpl.class);

        if (ejbBundle == null) {
            throw new RuntimeException("Unable to load EJB module.  DeploymentContext does not contain any EJB "
                    + " Check archive to ensure correct packaging for " + dc.getSourceDir());
        }

        ejbBundle.setClassLoader(dc.getClassLoader());
        ejbBundle.setupDataStructuresForRuntime();

        if (ejbBundle.containsCMPEntity()) {
            CMPService cmpService = cmpServiceProvider.get();
            if (cmpService == null) {
                throw new RuntimeException("CMP Module is not available");
            } else if (!cmpService.isReady()) {
                throw new RuntimeException("CMP Module is not initialized");
            }
        }

        EjbApplication ejbApp = new EjbApplication(ejbBundle, dc, dc.getClassLoader(), habitat);

        try {
            compEnvManager.bindToComponentNamespace(ejbBundle);

            // If within .war, also bind dependencies declared by web application. There is
            // a single naming environment for the entire .war module. Yhis is necessary
            // in order for eagerly initialized ejb components to have visibility to all the
            // dependencies b/c the web container does not bind to the component namespace until
            // its start phase, which comes after the ejb start phase.
            Object rootDesc = ejbBundle.getModuleDescriptor().getDescriptor();
            if ((rootDesc != ejbBundle) && (rootDesc instanceof WebBundleDescriptor)) {
                WebBundleDescriptor webBundle = (WebBundleDescriptor) rootDesc;
                compEnvManager.bindToComponentNamespace(webBundle);
            }

        } catch (Exception e) {
            throw new RuntimeException("Exception registering ejb bundle level resources", e);
        }

        ejbApp.loadContainers(dc);

        return ejbApp;
    }

    public void unload(EjbApplication ejbApplication, DeploymentContext dc) {

        EjbBundleDescriptorImpl ejbBundle = ejbApplication.getEjbBundleDescriptor();

        try {
            compEnvManager.unbindFromComponentNamespace(ejbBundle);
        } catch (Exception e) {
            _logger.log(Level.WARNING, "Error unbinding ejb bundle " + ejbBundle.getModuleName() + " dependency namespace", e);
        }

        if (ejbBundle.containsCMPEntity()) {
            initCMPDeployer();
            if (cmpDeployer != null) {
                cmpDeployer.unload(ejbBundle.getClassLoader());
            }
        }

        // All the other work is done in EjbApplication.

    }

    /**
     * Clean any files and artifacts that were created during the execution of the prepare method.
     *
     * @param dc deployment context
     */
    public void clean(DeploymentContext dc) {
        // Both undeploy and shutdown scenarios are
        // handled directly in EjbApplication.shutdown.

        // But CMP drop tables should be handled here.

        OpsParams params = dc.getCommandParameters(OpsParams.class);
        if ((params.origin.isUndeploy() || params.origin.isDeploy()) && isDas()) {

            // If CMP beans are present, cmpDeployer should've been initialized in unload()
            if (cmpDeployer != null) {
                cmpDeployer.clean(dc);
            }

            Properties appProps = dc.getAppProps();
            String uniqueAppId = appProps.getProperty(APP_UNIQUE_ID_PROP);
            try {
                if (getTimeoutStatusFromApplicationInfo(params.name()) && uniqueAppId != null) {
                    EJBTimerService persistentTimerService = null;
                    EJBTimerService nonPersistentTimerService = null;
                    boolean tsInitialized = false;
                    ProgressTracker tracker = dc.getTransientAppMetaData(ExtendedDeploymentContext.TRACKER, ProgressTracker.class);
                    if (tracker == null || !tracker.get("initialized", EngineRef.class).isEmpty()) {
                        if (EJBTimerService.isPersistentTimerServiceLoaded()) {
                            persistentTimerService = EJBTimerService.getPersistentTimerService();
                        }
                        if (EJBTimerService.isNonPersistentTimerServiceLoaded()) {
                            nonPersistentTimerService = EJBTimerService.getNonPersistentTimerService();
                        }
                        tsInitialized = true;
                    }
                    if (_logger.isLoggable(Level.FINE)) {
                        _logger.log(Level.FINE, "EjbDeployer APP ID of a Timeout App? {0}", uniqueAppId);
                        _logger.log(Level.FINE, "EjbDeployer Persistent TimerService: {0}", persistentTimerService);
                        _logger.log(Level.FINE, "EjbDeployer Non-Persistent TimerService: {0}", nonPersistentTimerService);
                    }

                    if (tsInitialized) {
                        if (persistentTimerService == null) {
                            _logger.log(Level.FINE,
                                    "EJB Persistent Timer Service is not available. Persistent Timers for application with id {0} will not be deleted",
                                    uniqueAppId);
                        } else {
                            if (getKeepStateFromApplicationInfo(params.name())) {
                                _logger.log(Level.INFO, "Persistent Timers will not be destroyed since keepstate is true for application {0}", params.name());
                            } else {
                                persistentTimerService.destroyAllTimers(Long.parseLong(uniqueAppId));
                            }
                        }
                        if (nonPersistentTimerService == null) {
                            _logger.log(Level.FINE,
                                    "EJB Non-Persistent Timer Service is not available. Non-Persistent Timers for application with id {0} will not be deleted",
                                    uniqueAppId);
                        } else {
                            nonPersistentTimerService.destroyAllTimers(Long.parseLong(uniqueAppId));
                        }
                    }
                }
            } catch (Exception e) {
                _logger.log(Level.WARNING, "Failed to delete timers for application with id " + uniqueAppId, e);
            }
        }

        // Security related cleanup is to be done for the undeploy event
        if (params.origin.isUndeploy() || params.origin.isDeploy() || params.origin.isLoad()) {

            // Removing EjbSecurityManager for undeploy case
            String appName = params.name();
            String[] contextIds = ejbSecManagerFactory.getContextsForApp(appName, false);
            if (contextIds != null) {
                for (String contextId : contextIds) {
                    try {
                        // TODO:appName is not correct, we need the module name
                        // from the descriptor.
                        probeProvider.policyDestructionStartedEvent(contextId);
                        SecurityUtil.removePolicy(contextId);
                        probeProvider.policyDestructionEndedEvent(contextId);
                        probeProvider.policyDestructionEvent(contextId);
                    } catch (IASSecurityException ex) {
                        _logger.log(Level.WARNING, "Error removing the policy file " + "for application " + appName + " " + ex);
                    }

                    List managers = ejbSecManagerFactory.getManagers(contextId, false);
                    if (managers != null) {
                        for (EJBSecurityManager manager : managers) {
                            manager.destroy();
                        }
                    }
                }
            }
            // Removing the RoleMapper
            SecurityUtil.removeRoleMapper(dc);
        }
    }

    /**
     * Use this method to generate any ejb-related artifacts for the module
     */
    @Override
    protected void generateArtifacts(DeploymentContext dc) throws DeploymentException {

        OpsParams params = dc.getCommandParameters(OpsParams.class);
        if (!(params.origin.isDeploy() && isDas())) {
            // Generate artifacts only when being deployed on DAS
            return;
        }

        EjbBundleDescriptorImpl bundle = dc.getModuleMetaData(EjbBundleDescriptorImpl.class);

        DeployCommandParameters dcp = dc.getCommandParameters(DeployCommandParameters.class);
        boolean generateRmicStubs = dcp.generatermistubs;
        dc.addTransientAppMetaData(CMPDeployer.MODULE_CLASSPATH, getModuleClassPath(dc));
        if (generateRmicStubs) {
            StaticRmiStubGenerator staticStubGenerator = new StaticRmiStubGenerator(habitat);
            try {
                staticStubGenerator.ejbc(dc);
            } catch (Exception e) {
                throw new DeploymentException("Static RMI-IIOP Stub Generation exception for " + dc.getSourceDir(), e);
            }
        }

        if (bundle == null || !bundle.containsCMPEntity()) {
            // bundle WAS null in a war file where we do not support CMPs
            return;
        }

        initCMPDeployer();
        if (cmpDeployer == null) {
            throw new DeploymentException("No CMP Deployer is available to deploy this module");
        }
        cmpDeployer.deploy(dc);

    }

    @Override
    public void event(Event event) {
        if (event.is(Deployment.APPLICATION_PREPARED) && isDas()) {
            ExtendedDeploymentContext context = (ExtendedDeploymentContext) event.hook();
            OpsParams opsparams = context.getCommandParameters(OpsParams.class);
            DeployCommandParameters dcp = context.getCommandParameters(DeployCommandParameters.class);

            ApplicationInfo appInfo = appRegistry.get(opsparams.name());
            Application app = appInfo.getMetaData(Application.class);
            if (app == null) {
                // Not a Java EE application
                return;
            }

            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE,
                        "EjbDeployer in APPLICATION_PREPARED for origin: " + opsparams.origin + ", target: " + dcp.target + ", name: " + opsparams.name());
            }

            boolean createTimers = true;
            // target could be null for internal apps such as wstx-services or admin console
            boolean isDeploymentGroup = dcp.target == null ? false : domain.getDeploymentGroupNamed(dcp.target) != null;
            boolean isDeployment = opsparams.origin.isDeploy() || opsparams.origin.isCreateAppRef();
            boolean isDirectTarget = env.getInstanceName().equals(dcp.target);
            // Create timers on DAS only if this condition is not met
            if (!isDeployment || isDirectTarget) {
                // Create them on deploy for a cluster or create-application-ref (the latter will
                // check if it's the 1st ref being added or a subsequent one (timers with this unique id are present
                // or not)
                // Otherwise, timers will be created by the BaseContainer if it's a single instance deploy
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "EjbDeployer ... will only set the timeout application flag if any");
                }
                // But is-timed-app needs to be set in AppInfo in any case
                createTimers = false;
            }
            if (isDeploymentGroup) {
                _logger.log(Level.WARNING, "Deployment targets deployment group {0}, it is assumed that timer "+
                        "service configuration is consistent accross all members of the group", dcp.target);
            }

            String target = dcp.target;
            if (createTimers && dcp.isredeploy != null && dcp.isredeploy && DeploymentUtils.isDomainTarget(target)) {
                List targets = (List) context.getTransientAppMetaData(DeploymentProperties.PREVIOUS_TARGETS, List.class);
                for (String ref : targets) {
                    target = ref;
                    if (domain.getClusterNamed(target) != null || domain.getDeploymentGroupNamed(target) != null) {
                        break; // prefer cluster target
                    }
                }
            }

            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "EjbDeployer using target for event as " + target);
            }

            boolean isTimedApp = false;
            for (EjbBundleDescriptorImpl ejbBundle : app.getBundleDescriptors(EjbBundleDescriptorImpl.class)) {
                if (checkEjbBundleForTimers(ejbBundle, createTimers, target)) {
                    isTimedApp = true;
                }
            }

            if (isTimedApp && (opsparams.origin.isDeploy() || opsparams.origin.isLoad())) {
                // Mark application as a timeout application, so that the clean() call removes the timers.
                appInfo.addTransientAppMetaData(IS_TIMEOUT_APP_PROP, Boolean.TRUE);
            }
        }
    }

    private boolean checkEjbBundleForTimers(EjbBundleDescriptorImpl ejbBundle, boolean createTimers, String target) {
        boolean result = false;
        if (ejbBundle != null) {
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "EjbDeployer.checkEjbBundleForTimers in BUNDLE: " + ejbBundle.getName());
            }

            for (EjbDescriptor ejbDescriptor : ejbBundle.getEjbs()) {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "EjbDeployer.checkEjbBundleForTimers in EJB: " + ejbDescriptor.getName());
                }

                if (ejbDescriptor.isTimedObject()) {
                    result = true;
                    if (createTimers && !DeploymentUtils.isDomainTarget(target)) {
                        createAutomaticPersistentTimersForEJB(ejbDescriptor, target);
                    }
                }
            }
        }
        return result;
    }

    /**
     * Start EJB Timer Service and create automatic timers for this EJB in this target
     */
    private void createAutomaticPersistentTimersForEJB(EjbDescriptor ejbDescriptor, String target) {
        try {
            // Start EJB Timer Service if it wasn't started yet. On DAS the first start will create the timer table.
            EJBTimerService timerService = EJBTimerService.getEJBTimerService(target);
            if (_logger.isLoggable(Level.FINE)) {
                _logger.log(Level.FINE, "EjbDeployer BEAN ID? " + ejbDescriptor.getUniqueId());
                _logger.log(Level.FINE, "EjbDeployer TimerService: " + timerService);
            }

            if (timerService != null) {
                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "EjbDeployer - calling timerService.createSchedules for " + ejbDescriptor.getUniqueId());
                }
                timerService.createSchedulesOnServer(ejbDescriptor, getOwnerId(target));

                if (_logger.isLoggable(Level.FINE)) {
                    _logger.log(Level.FINE, "EjbDeployer Done With BEAN ID: " + ejbDescriptor.getUniqueId());
                }
            } else {
                throw new RuntimeException("EJB Timer Service is not available");
            }

        } catch (Exception e) {
            throw new DeploymentException("Failed to create automatic timers for " + ejbDescriptor.getName(), e);
        }
    }

    private String getOwnerId(String target) {
        // If target is a cluster or deployment group replace it with the instance
        List instances = Collections.EMPTY_LIST;
        Cluster cluster = domain.getClusterNamed(target);
        if (cluster != null) {
            instances = cluster.getInstances();
        } else {
            DeploymentGroup dg = domain.getDeploymentGroupNamed(target);
            if (dg != null) {
                instances = dg.getInstances();
            } else {
                return target;
            }
        }

        // Try a random instance in a cluster
        int useInstance = random.nextInt(instances.size());
        Server s0 = instances.get(useInstance);
        if (s0.isRunning()) {
            return s0.getName();
        } else {
            // Pick the first running instead
            for (Server s : instances) {
                if (s.isRunning()) {
                    return s.getName();
                }
            }
        }
        // If none of the instances is running, return a random instance in a
        // cluster
        return s0.getName();

    }

    private long getNextEjbAppUniqueId() {
        long next = uniqueIdCounter.incrementAndGet();

        // This number represents the base unique id for each ejb application.
        // It is used to generate an id for each ejb component that is
        // guaranteed to be unique across all the applications deployed to a
        // particular stand-alone server instance or DAS.
        //
        // The unique id is 64 bits, with the low-order 16 bits zeroed out.
        // Component ids are selected from these low-order bits, allowing a
        // maximum of 2^16 EJB components per application.
        //
        // The initial number is seeded from System.currentTimeMillis() the
        // first time this class is instantiated after a server start.
        // Since this epoch value is relative to 1970, even after left-shifting
        // 16 bits, the number of remaining milliseconds won't run out until
        // the year 10889. This scheme also assumes that for the lifetime
        // of the JVM for a given server, there aren't more individual
        // ejb application deployments than elapsed milliseconds, since the
        // next time the server starts it will simply seed from
        // currentTimeMillis() again rather than remembering the largest unique
        // id that was used the last time the server ran.

        return next << 16;
    }

    private void initCMPDeployer() {
        if (cmpDeployer == null) {
            synchronized (lock) {
                cmpDeployer = cmpDeployerProvider.get();
            }
        }
    }

    /**
     * Embedded is a single-instance like DAS
     */
    private boolean isDas() {
        return EjbContainerUtilImpl.getInstance().isDas();
    }

    private boolean getKeepStateFromApplicationInfo(String appName) {
        return getBooleanStateFromApplicationInfo(EjbApplication.KEEP_STATE, appName);
    }

    private boolean getBooleanStateFromApplicationInfo(String flag, String appName) {
        ApplicationInfo appInfo = appRegistry.get(appName);
        if (appInfo == null) {
            // appInfo can be null when running EjbDeployer.clean after a failed deploy
            return false;
        }
        Boolean rc = appInfo.getTransientAppMetaData(flag, Boolean.class);
        return (rc == null ? false : rc);
    }

    private boolean getTimeoutStatusFromApplicationInfo(String appName) {
        return getBooleanStateFromApplicationInfo(IS_TIMEOUT_APP_PROP, appName);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy