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

Glassfish example source code file (UpgradeStartup.java)

This example Glassfish source code file (UpgradeStartup.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

application, arraylist, file, file, inject, inject, inputstream, io, ioexception, j2ee_apps, j2ee_modules, javabean, list, log, logging, net, network, outputstream, string, string

The Glassfish UpgradeStartup.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2010 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 com.sun.enterprise.v3.server;

import com.sun.enterprise.module.bootstrap.ModuleStartup;
import com.sun.enterprise.module.bootstrap.StartupContext;
import com.sun.enterprise.v3.common.DoNothingActionReporter;
import com.sun.enterprise.config.serverbeans.Applications;
import com.sun.enterprise.config.serverbeans.Application;
import com.sun.enterprise.config.serverbeans.Server;
import com.sun.enterprise.config.serverbeans.ServerTags;
import com.sun.enterprise.config.serverbeans.Domain;
import com.sun.enterprise.util.io.FileUtils;
import com.sun.enterprise.util.StringUtils;
import com.sun.enterprise.deploy.shared.ArchiveFactory;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.config.*;
import org.glassfish.api.admin.CommandRunner;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.api.deployment.DeployCommandParameters;
import org.glassfish.api.deployment.archive.ReadableArchive;
import org.glassfish.api.deployment.archive.WritableArchive;
import org.glassfish.api.ActionReport;
import org.glassfish.deployment.common.DeploymentProperties;
import org.glassfish.internal.api.*;

import java.util.*;
import java.util.jar.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.net.URISyntaxException;
import java.net.URI;
import java.io.*;
import java.beans.PropertyVetoException;

/**
 * Very simple ModuleStartup that basically force an immediate shutdown.
 * When start() is invoked, the upgrade of the domain.xml has already been
 * performed.
 * 
 * @author Jerome Dochez
 */
@Service(name="upgrade")
public class UpgradeStartup implements ModuleStartup {

    @Inject
    CommandRunner runner;

    @Inject
    AppServerStartup appservStartup;

    @Inject
    Applications applications;

    @Inject
    ArchiveFactory archiveFactory;

    @Inject 
    ServerEnvironment env;

    @Inject(name= ServerEnvironment.DEFAULT_INSTANCE_NAME)
    Server server;

    @Inject 
    Domain domain;

    @Inject
    CommandRunner commandRunner;

    @Inject(optional=true)
    DomainUpgrade[] upgrades=null;

    // we need to refine, a better logger should be used.
    @Inject
    Logger logger;

    private final static String MODULE_TYPE = "moduleType";

    private final static String J2EE_APPS = "j2ee-apps";
    private final static String J2EE_MODULES = "j2ee-modules";

    private final static String DOMAIN_TARGET = "domain";

    private final static String SIGNATURE_TYPES_PARAM = "-signatureTypes";

    private List<String> sigTypeList = new ArrayList(); 

    public void setStartupContext(StartupContext startupContext) {
        appservStartup.setStartupContext(startupContext);
    }

    // do nothing, just return, at the time the upgrade service has
    // run correctly.
    public void start() {

        // we need to disable all the applications before starting server 
        // so the applications will not get loaded before redeployment
        // store the list of previous enabled applications
        // so we can reset these applications back to enabled after
        // redeployment
        List<Application> enabledApps = new ArrayList();
        List<String> enabledAppNames = new ArrayList();

        for (Application app : domain.getApplications().getApplications()) {
            logger.log(Level.INFO, "app " + app.getName() + " is " + app.getEnabled() + " resulting in " + Boolean.parseBoolean(app.getEnabled()));
            if (Boolean.parseBoolean(app.getEnabled())) {
                logger.log(Level.INFO, "Disabling application " + app.getName());
                enabledApps.add(app);
                enabledAppNames.add(app.getName());
            }
        }

        if (enabledApps.size()>0) {
            try  {
                ConfigSupport.apply(new ConfigCode() {
                    public Object run(ConfigBeanProxy... configBeanProxies) throws PropertyVetoException, TransactionFailure {
                        for (ConfigBeanProxy proxy : configBeanProxies) {
                            Application app = (Application) proxy;
                            app.setEnabled(Boolean.FALSE.toString());
                        }
                        return null;
                    }
                }, enabledApps.toArray(new Application[enabledApps.size()]));
            } catch(TransactionFailure tf) {
                logger.log(Level.SEVERE, "Exception while disabling applications", tf);
                return;
            }
        }

        // start the application server
        appservStartup.start();

        initializeSigTypeList();

        // redeploy all existing applications
        for (Application app : applications.getApplications()) {
            // we don't need to redeploy lifecycle modules
            if (Boolean.valueOf(app.getDeployProperties().getProperty
                (ServerTags.IS_LIFECYCLE))) {
                continue;
            }
            logger.log(Level.INFO, "Redeploy application " + app.getName() + " located at " + app.getLocation());    
            // we let upgrade proceed even if one application 
            // failed to redeploy
            redeployApp(app);
        }

        // re-enables all applications. 
        // we need to use the names in the enabledAppNames to find all
        // the application refs that need to be re-enabled
        // as the previous application collected not longer exist
        // after redeployment
        if (enabledAppNames.size()>0) {
            for (Application app : domain.getApplications().getApplications()) {
                if (enabledAppNames.contains(app.getName())) {
                    logger.log(Level.INFO, "Enabling application " + app.getName());
                    try {
                        ConfigSupport.apply(new SingleConfigCode<Application>() {
                            public Object run(Application param) throws PropertyVetoException, TransactionFailure {
                                if (!Boolean.parseBoolean(param.getEnabled())) {
                                    param.setEnabled(Boolean.TRUE.toString());
                                }
                                return null;
                            }
                        }, app);
                    } catch(TransactionFailure tf) {
                        logger.log(Level.SEVERE, "Exception while disabling applications", tf);
                        return;
                    }
                }
            }
        }

        // clean up leftover directories
        cleanupLeftOverDirectories();

        // stop-the server.
        Logger.getAnonymousLogger().info("Exiting after upgrade");
        try {
            Thread.sleep(3000);
            if (runner!=null) {
                runner.getCommandInvocation("stop-domain", new DoNothingActionReporter()).execute();
            }

        } catch (InterruptedException e) {
            Logger.getAnonymousLogger().log(Level.SEVERE, "Exception while attempting to shutdown after upgrade", e);
        }

    }

    public void stop() {
        appservStartup.stop();
    }

    private void cleanupLeftOverDirectories() {
        // 1. remove applications/j2ee-apps(modules) directory
        File oldJ2eeAppsRepository = new File(
            env.getApplicationRepositoryPath(), J2EE_APPS); 
        FileUtils.whack(oldJ2eeAppsRepository);
        File oldJ2eeModulesRepository = new File(
            env.getApplicationRepositoryPath(), J2EE_MODULES);
        FileUtils.whack(oldJ2eeModulesRepository);

        // 2. remove generated/xml/j2ee-apps(modules) directory
        File oldJ2eeAppsGeneratedXMLDir = new File( 
           env.getApplicationGeneratedXMLPath(), J2EE_APPS);
        FileUtils.whack(oldJ2eeAppsGeneratedXMLDir);
        File oldJ2eeModulesGeneratedXMLDir = new File( 
           env.getApplicationGeneratedXMLPath(), J2EE_MODULES);
        FileUtils.whack(oldJ2eeModulesGeneratedXMLDir);

        // 3. remove generated/ejb/j2ee-apps(modules) directory
        File oldJ2eeAppsEJBStubDir = new File( 
           env.getApplicationEJBStubPath(), J2EE_APPS);
        FileUtils.whack(oldJ2eeAppsEJBStubDir);
        File oldJ2eeModulesEJBStubDir = new File( 
           env.getApplicationEJBStubPath(), J2EE_MODULES);
        FileUtils.whack(oldJ2eeModulesEJBStubDir);

        // 4. clean up generated/jsp/j2ee-apps(modules) directory
        File oldJ2eeAppsJSPCompileDir = new File(
           env.getApplicationCompileJspPath(), J2EE_APPS);
        FileUtils.whack(oldJ2eeAppsJSPCompileDir);
        File oldJ2eeModulesJSPCompileDir = new File(
           env.getApplicationCompileJspPath(), J2EE_MODULES);
        FileUtils.whack(oldJ2eeModulesJSPCompileDir);

        // 5. clean up old system apps policy files
        File policyRootDir = env.getApplicationPolicyFilePath();
        File adminapp = new File(policyRootDir, "adminapp");
        FileUtils.whack(adminapp);
        File admingui = new File(policyRootDir, "admingui");
        FileUtils.whack(admingui);
        File ejbtimer = new File(policyRootDir, "__ejb_container_timer_app");
        FileUtils.whack(ejbtimer);
        File mejbapp = new File(policyRootDir, "MEjbApp");
        FileUtils.whack(mejbapp);
        File wstx = new File(policyRootDir, "WSTXServices");
        FileUtils.whack(wstx);
        File jwsappclient = new File(policyRootDir, "__JWSappclients");
        FileUtils.whack(jwsappclient);
    }

    private boolean redeployApp(Application app) {
        // we don't need to redeploy any v3 type application
        if (app.getModule().size() > 0 ) {
            logger.log(Level.INFO, "Skip redeploying v3 type application " + 
                app.getName());
            return true;
        }

        // populate the params and properties from application element first
        DeployCommandParameters deployParams = app.getDeployParameters(null);

        // for archive deployment, let's repackage the archive and redeploy
        // that way
        // we cannot just directory redeploy the archive deployed apps in
        // v2->v3 upgrade as the repository layout was different in v2 
        // we should not have to repackage for any upgrade from v3 
        if (! Boolean.valueOf(app.getDirectoryDeployed())) {
            File repackagedFile = null;
            try {
                repackagedFile = repackageArchive(app);
            } catch (IOException ioe) {
                logger.log(Level.SEVERE, "Repackaging of application " + app.getName() + " failed: " + ioe.getMessage(), ioe);
                return false;
            }
            if (repackagedFile == null) {
                logger.log(Level.SEVERE, "Repackaging of application " + app.getName() + " failed.");
                return false;
            }
            logger.log(Level.INFO, "Repackaged application " + app.getName()
                + " at " + repackagedFile.getPath()); 
            deployParams.path = repackagedFile;
        }

        deployParams.properties = app.getDeployProperties();
        // remove the marker properties so they don't get carried over 
        // through redeployment
        deployParams.properties.remove(MODULE_TYPE);
        // add the compatibility property so the applications are 
        // upgraded/redeployed in a backward compatible way
        deployParams.properties.setProperty(
            DeploymentProperties.COMPATIBILITY, "v2");
      
        // now override the ones needed for the upgrade
        deployParams.enabled = null;
        deployParams.force = true;
        deployParams.dropandcreatetables = false;
        deployParams.createtables = false;
        deployParams.target = DOMAIN_TARGET;

        ActionReport report = new DoNothingActionReporter();
        commandRunner.getCommandInvocation("deploy", report).parameters(deployParams).execute();

        // should we delete the temp file after we are done
        // it seems it might be useful to keep it around for debugging purpose

        if (report.getActionExitCode().equals(ActionReport.ExitCode.FAILURE)) {
            logger.log(Level.SEVERE, "Redeployment of application " + app.getName() + " failed: " + report.getMessage() + "\nPlease redeploy " + app.getName() + " manually.", report.getFailureCause());
            return false;
        }
        return true;
    }

    private File repackageArchive(Application app) throws IOException {
        URI uri = null;
        try {
            uri = new URI(app.getLocation());
        } catch (URISyntaxException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
        }

        if (uri == null) {
            return null;
        }
        
        Properties appProperties = app.getDeployProperties();
        String moduleType = appProperties.getProperty(MODULE_TYPE);
        String suffix = getSuffixFromType(moduleType);
        if (suffix == null) {
            suffix = ".jar";
        }
        File repositoryDir = new File(uri);

        // get temporary file directory of the system and set targetDir to it
        File tmp = File.createTempFile("upgrade", null);
        String targetParentDir = tmp.getParent();
        tmp.delete();

        if (moduleType.equals(ServerTags.J2EE_APPLICATION)) {
            return repackageApplication(repositoryDir, targetParentDir, suffix);
        } else {
            return repackageStandaloneModule(repositoryDir, targetParentDir, suffix);
        }
    }

    private File repackageApplication(File appDir,
        String targetParentDir, String suffix) throws IOException {
        String appName = appDir.getName();

        ReadableArchive source = archiveFactory.openArchive(appDir);

        File tempEar = new File(targetParentDir, appName + suffix);

        if (tempEar.exists()) {
            tempEar.delete();
        }

        WritableArchive target = archiveFactory.createArchive("jar", tempEar);

        Collection<String> directoryEntries = source.getDirectories();
        List<String> subModuleEntries = new ArrayList();
        List<String> entriesToExclude = new ArrayList();
 
        // first put all the sub module jars to the target archive
        for (String directoryEntry : directoryEntries) {
            if (directoryEntry.endsWith("_jar") || 
                directoryEntry.endsWith("_war") || 
                directoryEntry.endsWith("_rar")) {
                subModuleEntries.add(directoryEntry); 
                File moduleJar = processModule(new File(
                    appDir, directoryEntry), targetParentDir, null);
                OutputStream os = null;
                InputStream is = new BufferedInputStream(
                    new FileInputStream(moduleJar));
                try {
                    os = target.putNextEntry(moduleJar.getName());
                    FileUtils.copy(is, os, moduleJar.length());
                } finally {
                    if (os!=null) {
                        target.closeEntry();
                    }
                    is.close();
                }
            }
        }

        // now find all the entries we should exclude to copy to the target
        // basically all sub module entries should be excluded
        for (String subModuleEntry : subModuleEntries) {
            Enumeration<String> ee = source.entries(subModuleEntry);
            while (ee.hasMoreElements()) {
                String eeEntryName = ee.nextElement();
                entriesToExclude.add(eeEntryName);
            }
        }

        // now copy the rest of the entries
        Enumeration<String> e = source.entries();
        while (e.hasMoreElements()) {
            String entryName = e.nextElement();
            if (! entriesToExclude.contains(entryName)) {
                InputStream sis = source.getEntry(entryName);
                if (isSigFile(entryName)) {
                    logger.log(Level.INFO, "Excluding signature file: " 
                        + entryName + " from repackaged application: " + 
                        appName + "\n");
                    continue;
                }
                if (sis != null) {
                    InputStream is = new BufferedInputStream(sis);
                    OutputStream os = null;
                    try {
                        os = target.putNextEntry(entryName);
                        FileUtils.copy(is, os, source.getEntrySize(entryName));
                    } finally {
                        if (os!=null) {
                            target.closeEntry();
                        }
                        is.close();
                    }
                }
            }
        }

        // last is manifest if existing.
        Manifest m = source.getManifest();
        if (m!=null) {
            processManifest(m, appName);
            OutputStream os  = target.putNextEntry(JarFile.MANIFEST_NAME);
            m.write(os);
            target.closeEntry();
        }

        source.close();
        target.close();
      
        return tempEar;
    }

    private File repackageStandaloneModule(File moduleDirName, 
        String targetParentDir, String suffix) throws IOException {
        return processModule(moduleDirName, targetParentDir, suffix);
    }

    // repackage a module and return it as a jar file
    private File processModule(File moduleDir, String targetParentDir, 
        String suffix) throws IOException {
 
        String moduleName = moduleDir.getName();

        // sub module in ear case 
        if (moduleName.endsWith("_jar") || moduleName.endsWith("_war") || moduleName.endsWith("_rar")) {
            suffix = "." +  moduleName.substring(moduleName.length() - 3);
            moduleName = moduleName.substring(0, moduleName.lastIndexOf('_'));
        }

        ReadableArchive source = archiveFactory.openArchive(moduleDir);

        File tempJar = new File(targetParentDir, moduleName + suffix);

        if (tempJar.exists()) {
            tempJar.delete();
        }

        WritableArchive target = archiveFactory.createArchive("jar", tempJar);

        Enumeration<String> e = source.entries();
        while (e.hasMoreElements()) {
            String entryName = e.nextElement();
            if (isSigFile(entryName)) {
                logger.log(Level.INFO, "Excluding signature file: " 
                    + entryName + " from repackaged module: " + moduleName + 
                    "\n");
                continue;
            }
            InputStream sis = source.getEntry(entryName);
            if (sis != null) {
                InputStream is = new BufferedInputStream(sis);
                OutputStream os = null;
                try {
                    os = target.putNextEntry(entryName);
                    FileUtils.copy(is, os, source.getEntrySize(entryName));
                } finally {
                    if (os!=null) {
                        target.closeEntry();
                    }
                    is.close();
                }
            }
        }

        // last is manifest if existing.
        Manifest m = source.getManifest();
        if (m!=null) {
            processManifest(m, moduleName);
            OutputStream os  = target.putNextEntry(JarFile.MANIFEST_NAME);
            m.write(os);
            target.closeEntry();
        }

        source.close();
        target.close();

        return tempJar;
    }

    private String getSuffixFromType(String moduleType) {
        if (moduleType == null) {
            return null;
        }
        if (moduleType.equals(ServerTags.CONNECTOR_MODULE)) {
            return ".rar"; 
        }
        if (moduleType.equals(ServerTags.EJB_MODULE)) {
            return ".jar"; 
        }
        if (moduleType.equals(ServerTags.WEB_MODULE)) {
            return ".war"; 
        }
        if (moduleType.equals(ServerTags.APPCLIENT_MODULE)) {
            return ".jar"; 
        }
        if (moduleType.equals(ServerTags.J2EE_APPLICATION)) {
            return ".ear"; 
        }
        return null;
    }

    private void initializeSigTypeList() {
        String sigTypesParam = env.getStartupContext().getArguments().getProperty(SIGNATURE_TYPES_PARAM);
        if (sigTypesParam != null) {
            sigTypeList = StringUtils.parseStringList(sigTypesParam, ",");
        }
        sigTypeList.add(".SF");
        sigTypeList.add(".sf");
        sigTypeList.add(".RSA");
        sigTypeList.add(".rsa");
        sigTypeList.add(".DSA");
        sigTypeList.add(".dsa");
        sigTypeList.add(".PGP");
        sigTypeList.add(".pgp");
    }

    private boolean isSigFile(String entryName) {
        for (String sigType : sigTypeList) {
            if (entryName.endsWith(sigType)) {
                return true;
            }
        }
        return false;
    }

    private void processManifest(Manifest m, String moduleName) {
        // remove signature related entries from the file
        Map<String, Attributes> entries = m.getEntries(); 
        Iterator<String> entryKeyItr = entries.keySet().iterator(); 
        while (entryKeyItr.hasNext()) {
            String entryKey = entryKeyItr.next();
            Attributes attr = entries.get(entryKey);
            Iterator attrKeyItr  = attr.keySet().iterator();
            while (attrKeyItr.hasNext()) {
                Object attrKey = attrKeyItr.next();
                if (attrKey instanceof Attributes.Name) {
                    Attributes.Name attrKey2 = (Attributes.Name) attrKey;
                    if (attrKey2.toString().trim().equals("Digest-Algorithms")
                        || attrKey2.toString().indexOf("-Digest") != -1) {
                        logger.log(Level.INFO, "Removing signature attribute " 
                            + attrKey2 + " from manifest in "  + 
                            moduleName + "\n");
                        attrKeyItr.remove();
                    }
                }
            }
            if (attr.size() == 0) {
                entryKeyItr.remove();
            }
        }
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish UpgradeStartup.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.