FileDocCategorySizeDatePackage
VerificationHandler.javaAPI DocGlassfish v2 API22236Fri May 04 22:33:24 BST 2007com.sun.enterprise.tools.verifier

VerificationHandler

public class VerificationHandler extends Object
It is responsible for creating the application descriptor, exploding the archive, creating the application classloader, and invoking the appropriate check managers that load and run the verifier tests.
author
Vikas Awasthi

Fields Summary
private final String
TMPDIR
private SimpleDateFormat
dateFormatter
private String
explodeDir
private com.sun.enterprise.util.LocalStringManagerImpl
smh
private FrameworkContext
frameworkContext
private Logger
logger
private Application
application
private ResultManager
resultManager
private com.sun.enterprise.deployment.archivist.Archivist
archivist
private boolean
isBackend
private List
classPath
private final int
MAX_WINDOWS_PATH_LIMIT
Constructors Summary
public VerificationHandler(FrameworkContext frameworkContext)


      
              
        this.frameworkContext = frameworkContext;
        try {
            initStandalone();
        } catch(IOException ioe) {
            cleanup();
            throw ioe;
        } catch(RuntimeException re) {
            cleanup();
            throw re;
        }
    
public VerificationHandler(FrameworkContext frameworkContext, Application application, com.sun.enterprise.deployment.deploy.shared.AbstractArchive abstractArchive, List classPath)

        this.frameworkContext = frameworkContext;
        init();
        this.application = application;
        this.frameworkContext.setClassPath(classPath);
        this.frameworkContext.setJarFileName(application.getRegistrationName());
        isBackend = true;
        this.frameworkContext.setApplication(application);
        this.frameworkContext.setAbstractArchive(abstractArchive);
    
Methods Summary
private voidcheckAndExplodeArchiveInWindowsPlatform(java.lang.String jarFile)

        if(!System.getProperty("os.name").toLowerCase().startsWith("win"))
            return;
        
        if(!testFileLength(new File(explodeDir))) {
            File tempDir = new File(System.getProperty("home.drive"),"temp");
            if(!tempDir.exists())
                throw new IOException(smh.getLocalString
                        (getClass().getName() + ".exception1","Maximum Path " +
                        "Length exceeded. The application uses long file names " +
                        "which has exceeded maximum allowed path length in windows." +
                        " Please shorten the file names and then continue. Not " +
                        "able to proceed further as [{0}] does not exist",
                        new Object[]{tempDir.getAbsolutePath()}));
            if(!FileUtil.deleteDir(new File(explodeDir))) {
                logger.log(Level.WARNING, 
                            getClass().getName() + ".explodedirdeleteerror", // NOI18N
                            new Object[] {explodeDir});
            }
            explodeDir = tempDir.getAbsolutePath() + File.separator + "exploded" +
                    dateFormatter.format(new Date());
            explodeArchive(new File(jarFile));
            if(!testFileLength(new File(explodeDir)))
                throw new IOException(smh.getLocalString
                        (getClass().getName() + ".exception","Maximum Path Length " +
                        "exceeded. The application uses long file names which has " +
                        "exceeded maximum allowed path length in windows. Please " +
                        "shorten the file names and then continue."));
        }
    
public voidcleanup()

        if(!isBackend && application!=null)
            ((JarClassLoader)application.getClassLoader()).done();
        if(!isBackend &&
            !((new File(frameworkContext.getJarFileName())).isDirectory()))
            FileUtil.deleteDir(new File(explodeDir));
    
private voidcreateApplicationDescriptor()

// the code below is used by the deploytool GUI.            
        PluggableArchivistsHelper defaultArchivists = new PluggableArchivistsHelper();
        defaultArchivists.registerArchivist(new ApplicationArchivist());
        defaultArchivists.registerArchivist(new WebArchivist());
        defaultArchivists.registerArchivist(new EjbArchivist());
        defaultArchivists.registerArchivist(new ConnectorArchivist());
        defaultArchivists.registerArchivist(new AppClientArchivist());
        AbstractArchive abstractArchive =
                new FileArchiveFactory().openArchive(
                        frameworkContext.getExplodedArchivePath());
        frameworkContext.setAbstractArchive(abstractArchive);
        archivist.setPluggableArchivists(defaultArchivists);
        archivist.setXMLValidationLevel("full");
        archivist.setRuntimeXMLValidation(true);
        archivist.setRuntimeXMLValidationLevel("full");
        archivist.setAnnotationProcessingRequested(true);
        archivist.setAnnotationErrorHandler(new VerifierErrorHandler(resultManager));

        String jarName = new File(abstractArchive.getArchiveUri()).getName();
        createApplicationDescriptor0(abstractArchive, jarName);
    
private voidcreateApplicationDescriptor0(com.sun.enterprise.deployment.deploy.shared.AbstractArchive abstractArchive, java.lang.String jarName)
This method populates the missing information in Application object that is already created in {@link #explodeArchive(java.io.File)}.

param
abstractArchive
param
jarName
throws
IOException
throws
SAXParseException

        if (archivist.getModuleType()==ModuleType.EAR) {
                ClassLoader classLoader = getEarClassLoader(application);
                application.setClassLoader(classLoader);
                archivist.setClassLoader(classLoader);
                archivist.setHandleRuntimeInfo(!frameworkContext.isPortabilityMode());
                archivist.readPersistenceDeploymentDescriptors(abstractArchive, application);
                ((ApplicationArchivist) archivist).readModulesDescriptors(application, abstractArchive);
                if(!frameworkContext.isPortabilityMode()) {
                    // this recurssively reads runtime DD for all the modules.
                    archivist.readRuntimeDeploymentDescriptor(abstractArchive, application);
                }
                application.setRegistrationName(jarName);
        } else {
            ClassLoader classLoader = getModuleClassLoader(archivist.getModuleType());
            archivist.setClassLoader(classLoader);
            application = ApplicationArchivist.openArchive(jarName,
                                                    archivist,
                                                    abstractArchive,
                                                    !frameworkContext.isPortabilityMode());
            application.setClassLoader(classLoader);
        }
    
private java.lang.ClassLoadercreateClassLoaderFromPath(java.util.List classPath)

        if(!frameworkContext.isPortabilityMode()) {
            classPath.addAll(0, this.classPath);
            frameworkContext.setClassPath(classPath);
        } else {
            String as_lib_root = System.getProperty("com.sun.aas.installRoot")+
                                                    File.separator+
                                                    "lib"+ // NOI18N
                                                    File.separator;
            classPath.add(as_lib_root + "javaee.jar"); // NOI18N
        }

        JarClassLoader jcl = new JarClassLoader();
        // toURI().toURL() takes care of all the escape characters in the 
        // absolutePath. The toURI() method encodes all escape characters. Since
        // EJBClassLoader does not decode these urls here only toURL() is used.
        // Once this issue is fixed in EJBClassloader we can change it to 
        // toURI().toURL()
        for (String path : classPath) 
            jcl.appendURL(new File(path));
        return jcl;
    
private voidexplodeArchive(java.io.File archiveFile)

        if (archiveFile.isDirectory()) {
            frameworkContext.setExplodedArchivePath(
                    archiveFile.getAbsolutePath());
            return;
        }

        String appName = FileUtils.makeFriendlyFileNameNoExtension(
                archiveFile.getName());
        File appDir = new File(new File(explodeDir), appName);
        frameworkContext.setExplodedArchivePath(appDir.getAbsolutePath());

        try {
            ModuleType moduleType = archivist.getModuleType();
            if(ModuleType.EAR.equals(moduleType)) { // EAR file
                // Explode the archive and create a descriptor. This is
                // not complete at this point. It will be filled with all info later.
                application = J2EEModuleExploder.explodeEar(archiveFile, appDir);
            } else if ( ModuleType.EJB.equals(moduleType) ||
                    ModuleType.CAR.equals(moduleType) ||
                    ModuleType.RAR.equals(moduleType) ||
                    ModuleType.WAR.equals(moduleType) ) {
                J2EEModuleExploder.explodeJar(archiveFile, appDir);
            } else
                throw new FileNotFoundException(
                        "Deployment descriptor not found in " +
                        archiveFile.getName());
        } catch (Exception e) {
            IOException ioe = new IOException(e.getMessage());
            ioe.initCause(e);
            throw ioe;
        }
    
private java.lang.ClassLoadergetEarClassLoader(Application dummyApp)

        List<String> classPath = EJBClassPathUtils.getApplicationClassPath(dummyApp, 
                                        frameworkContext.getExplodedArchivePath());
        return createClassLoaderFromPath(classPath);
    
private java.lang.ClassLoadergetModuleClassLoader(javax.enterprise.deploy.shared.ModuleType type)

        String moduleRoot = frameworkContext.getExplodedArchivePath();
        List<String> classPath = EJBClassPathUtils.getModuleClassPath(type, moduleRoot, moduleRoot);
        return createClassLoaderFromPath(classPath);
    
private voidinit()
common initialization method for the call from backend and standalone invocation.

        frameworkContext.setResultManager(resultManager = new ResultManager());
        try {
            APIRepository.Initialize(
                    frameworkContext.getConfigDirStr() + File.separator +
                    "standard-apis.xml"); // NOI18N
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    
private voidinitStandalone()
initialization done for standalone verifier invocation.

throws
IOException

        init();
        logger.log(Level.FINE, getClass().getName() + ".debug.startingLoadJar");
        if (!frameworkContext.isPortabilityMode()) {
            String as_config_dir =
                    System.getProperty("com.sun.aas.installRoot")+File.separator+"config";
            classPath = PELaunch.getServerClassPath(as_config_dir,
                                                    frameworkContext.getDomainDir());
        }

        // initialize /tmp/* directories
        initVerifierTmpDirs();
        String jarFile = frameworkContext.getJarFileName();
        //We must call OptionalPkgDependency.satisfyOptionalPackageDependencies() before explodeArchive,
        //because inside this call, the list of installed optional packages in the system gets initialised.
        //That list is then used inside optionalPackageDependencyLogic() code.
        //It looks to be a bug as ideally this kind of dependency should be taken care of inside
        //OptionalPkgDependency class itself.
        //But any way, we don't have a choice but to make this work around in our code.
        OptionalPkgDependency.satisfyOptionalPackageDependencies();
        archivist = ArchivistFactory.getArchivistForArchive(new File(jarFile));
        if(archivist == null) {
            throw new RuntimeException(
                    smh.getLocalString(getClass().getName() + ".notAJavaEEArchive", // NOI18N
                    "[ {0} ] is not a valid Java EE archive", // NOI18N
                            new Object[]{jarFile}));
        }
        explodeArchive(new File(jarFile));
        checkAndExplodeArchiveInWindowsPlatform(jarFile);
        Descriptor.setBoundsChecking(false);

        try {
            createApplicationDescriptor();
        } catch (IOException e) {
            log("Problem in creating application descriptor", e);
            throw e;
        } catch (SAXParseException se) {
            log("Problem in parsing the xml file. For " +
                    se.getLocalizedMessage() +
                    ", error at line " +
                    se.getLineNumber() +
                    ", column " +
                    se.getColumnNumber(), se);
            IOException ioe = new IOException();
            ioe.initCause(se);
            throw ioe;
        }
        ((Descriptor) application).visit(new ApplicationValidator());
    
private booleaninitVerifierTmpDirs()

        // Make sure we can create the directory appservResultDir
        File test = new File(explodeDir);
        if (!test.isDirectory() && !test.getAbsoluteFile().mkdirs()) {
            logger.log(Level.SEVERE, getClass().getName() +
                    ".explodedircreateerror", test.getAbsolutePath()); // NOI18N
            throw new IOException(smh.getLocalString(getClass().getName()
                    + ".explodedircreateerror", test.getAbsolutePath())); // NOI18N
        }
        return true;
    
private voidlog(java.lang.String message, java.lang.Exception e)
This method is used to log exception messges in the error vector of ResultManager object.

param
message
param
e

        if (message == null) message = "";
        LogRecord logRecord = new LogRecord(Level.SEVERE, message);
        logRecord.setThrown(e);
        frameworkContext.getResultManager().log(logRecord);
    
private voidrunVerifier(BaseVerifier baseVerifier)

        try {
            baseVerifier.verify();
        } catch (Exception e) {
            log("Problem in running tests for :" +
                    baseVerifier.getDescriptor().getName(),
                    e);
        }
    
private booleantestFileLength(java.io.File file)
Maximum allowed path length in windows is 248. Return false if any exploded file exceeds this length.

        if(file.getAbsolutePath().length() > MAX_WINDOWS_PATH_LIMIT) {
            logger.log(Level.WARNING, 
                        getClass().getName() + ".maxlength.exceeded", // NOI18N
                        new Object[] {file.getAbsolutePath(), 
                                      file.getAbsolutePath().length(), 
                                      MAX_WINDOWS_PATH_LIMIT});
            return false;
        } else if(file.getCanonicalPath().length() > MAX_WINDOWS_PATH_LIMIT) {
            // absolute paths may have ~1. Since windows behave strangely  
            // both absolute path and canonical path are used
            logger.log(Level.WARNING, 
                        getClass().getName() + ".maxlength.exceeded", // NOI18N
                        new Object[] {file.getCanonicalPath(), 
                                      file.getCanonicalPath().length(), 
                                      MAX_WINDOWS_PATH_LIMIT});
            return false;
        }
        
        if(!file.isDirectory())
            return true;
        
        for (File file1 : file.listFiles()) 
            if(!testFileLength(file1))
                return false;
        return true;
    
public ResultManagerverifyArchive()

 // should we throw exception here
        if(!application.isVirtual()) { // don't run app tests for standalone module
            runVerifier(new ApplicationVerifier(frameworkContext, application));
        }

        for (Iterator itr = application.getEjbBundleDescriptors().iterator();
             itr.hasNext();) {
            EjbBundleDescriptor ejbd = (EjbBundleDescriptor) itr.next();
            runVerifier(new EjbVerifier(frameworkContext, ejbd));
        }

        for (Iterator itr = application.getWebBundleDescriptors().iterator();
             itr.hasNext();) {
            WebBundleDescriptor webd = (WebBundleDescriptor) itr.next();
            runVerifier(new WebVerifier(frameworkContext, webd));
        }

        for (Iterator itr = application.getApplicationClientDescriptors()
                .iterator();
             itr.hasNext();) {
            ApplicationClientDescriptor appClientDescriptor =
                                    (ApplicationClientDescriptor) itr.next();
            runVerifier(new AppClientVerifier(frameworkContext,appClientDescriptor));
        }

        for (Iterator itr = application.getRarDescriptors().iterator();
             itr.hasNext();) {
            ConnectorDescriptor cond = (ConnectorDescriptor) itr.next();
            runVerifier(new ConnectorVerifier(frameworkContext, cond));
        }
        
        return resultManager;