protected AppModule createAppModule()

in container/openejb-core/src/main/java/org/apache/openejb/config/DeploymentLoader.java [379:694]


    protected AppModule createAppModule(final File jarFile, final String jarPath) throws OpenEJBException {
        File appDir = unpack(jarFile);
        try {
            appDir = appDir.getCanonicalFile();
        } catch (final IOException e) {
            throw new OpenEJBException("Invalid application directory " + appDir.getAbsolutePath());
        }

        final URL appUrl = getFileUrl(appDir);

        final String appId = appDir.getAbsolutePath();
        final ClassLoader tmpClassLoader = ClassLoaderUtil.createTempClassLoader(appId, new URL[]{appUrl}, getOpenEJBClassLoader());

        final ResourceFinder finder = new ResourceFinder("", tmpClassLoader, appUrl);
        final Map<String, URL> appDescriptors = getDescriptors(finder);

        try {

            //
            // Find all the modules using either the application xml or by searching for all .jar, .war and .rar files.
            //

            final Map<String, URL> ejbModules = new LinkedHashMap<>();
            final Map<String, URL> clientModules = new LinkedHashMap<>();
            final Map<String, URL> resouceModules = new LinkedHashMap<>();
            final Map<String, URL> webModules = new LinkedHashMap<>();
            final Map<String, String> webContextRoots = new LinkedHashMap<>();

            final URL applicationXmlUrl = appDescriptors.get("application.xml");
            final List<URL> extraLibs = new ArrayList<>();

            final Application application;
            if (applicationXmlUrl != null) {

                application = unmarshal(applicationXmlUrl);
                for (final Module module : application.getModule()) {
                    try {
                        if (module.getEjb() != null) {
                            final URL url = finder.find(module.getEjb().trim());
                            ejbModules.put(module.getEjb(), url);
                        } else if (module.getJava() != null) {
                            final URL url = finder.find(module.getJava().trim());
                            clientModules.put(module.getJava(), url);
                            extraLibs.add(url);
                        } else if (module.getConnector() != null) {
                            final URL url = finder.find(module.getConnector().trim());
                            resouceModules.put(module.getConnector(), url);
                        } else if (module.getWeb() != null) {
                            final URL url = finder.find(module.getWeb().getWebUri().trim());
                            webModules.put(module.getWeb().getWebUri(), url);
                            webContextRoots.put(module.getWeb().getWebUri(), module.getWeb().getContextRoot());
                        }
                    } catch (final IOException e) {
                        throw new OpenEJBException("Invalid path to module " + e.getMessage(), e);
                    }
                }
            } else {
                application = new Application();
                final HashMap<String, URL> files = new HashMap<>();
                scanDir(appDir, files, "", false);
                files.remove("META-INF/MANIFEST.MF");

                // todo we should also filter URLs here using DeploymentsResolver.loadFromClasspath

                createApplicationFromFiles(appId, tmpClassLoader, ejbModules, clientModules, resouceModules, webModules, files);
            }

            final ClassLoaderConfigurer configurer = QuickJarsTxtParser.parse(new File(appDir, "META-INF/" + QuickJarsTxtParser.FILE_NAME));
            final Collection<URL> jarsXmlLib = new ArrayList<>();
            if (configurer != null) {
                for (final URL url : configurer.additionalURLs()) {
                    try {
                        detectAndAddModuleToApplication(appId, tmpClassLoader,
                            ejbModules, clientModules, resouceModules, webModules,
                            new ImmutablePair<>(URLs.toFile(url).getAbsolutePath(), url));
                    } catch (final Exception e) {
                        jarsXmlLib.add(url);
                    }
                }
            }

            //
            // Create a class loader for the application
            //

            // lib/*
            if (application.getLibraryDirectory() == null) {
                application.setLibraryDirectory("lib/");
            } else {
                final String dir = application.getLibraryDirectory();
                if (!dir.endsWith("/")) {
                    application.setLibraryDirectory(dir + "/");
                }
            }

            try {
                final Map<String, URL> libs = finder.getResourcesMap(application.getLibraryDirectory());
                extraLibs.addAll(libs.values());
            } catch (final IOException e) {
                LOGGER.warning("Cannot load libs from '" + application.getLibraryDirectory() + "' : " + e.getMessage(), e);
            }

            // APP-INF/lib/*
            try {
                final Map<String, URL> libs = finder.getResourcesMap("APP-INF/lib/");
                extraLibs.addAll(libs.values());
            } catch (final IOException e) {
                LOGGER.warning("Cannot load libs from 'APP-INF/lib/' : " + e.getMessage(), e);
            }

            // META-INF/lib/*
            try {
                final Map<String, URL> libs = finder.getResourcesMap("META-INF/lib/");
                extraLibs.addAll(libs.values());
            } catch (final IOException e) {
                LOGGER.warning("Cannot load libs from 'META-INF/lib/' : " + e.getMessage(), e);
            }

            // All jars nested in the Resource Adapter
            final HashMap<String, URL> rarLibs = new HashMap<>();
            for (final Map.Entry<String, URL> entry : resouceModules.entrySet()) {
                try {
                    // unpack the resource adapter archive
                    File rarFile = URLs.toFile(entry.getValue());
                    rarFile = unpack(rarFile);
                    entry.setValue(rarFile.toURI().toURL());

                    scanDir(appDir, rarLibs, "");
                } catch (final MalformedURLException e) {
                    throw new OpenEJBException("Malformed URL to app. " + e.getMessage(), e);
                }
            }
            for (final Iterator<Map.Entry<String, URL>> iterator = rarLibs.entrySet().iterator(); iterator.hasNext(); ) {
                // remove all non jars from the rarLibs
                final Map.Entry<String, URL> fileEntry = iterator.next();
                if (!fileEntry.getKey().endsWith(".jar")) {
                    continue;
                }
                iterator.remove();
            }

            final List<URL> classPath = new ArrayList<>();
            classPath.addAll(ejbModules.values());
            classPath.addAll(clientModules.values());
            classPath.addAll(rarLibs.values());
            classPath.addAll(extraLibs);
            classPath.addAll(jarsXmlLib);
            final URL[] urls = classPath.toArray(new URL[classPath.size()]);

            SystemInstance.get().fireEvent(new BeforeDeploymentEvent(urls));

            final ClassLoader appClassLoader = ClassLoaderUtil.createTempClassLoader(appId, urls, getOpenEJBClassLoader());

            //
            // Create the AppModule and all nested module objects
            //

            final AppModule appModule = new AppModule(appClassLoader, appId, application, false);
            appModule.getAdditionalLibraries().addAll(extraLibs);
            appModule.getAltDDs().putAll(appDescriptors);
            appModule.getWatchedResources().add(appId);
            if (applicationXmlUrl != null) {
                appModule.getWatchedResources().add(URLs.toFilePath(applicationXmlUrl));
            }
            if (appDescriptors.containsKey(RESOURCES_XML)) {
                final Map<String, Object> altDd = new HashMap<>(appDescriptors);
                ReadDescriptors.readResourcesXml(new org.apache.openejb.config.Module(false) {
                    @Override
                    public Map<String, Object> getAltDDs() {
                        return altDd;
                    }

                    @Override
                    public void initResources(final Resources resources) {
                        appModule.getContainers().addAll(resources.getContainer());
                        appModule.getResources().addAll(resources.getResource());
                        appModule.getServices().addAll(resources.getService());
                    }
                });
            }

            // EJB modules
            for (final Map.Entry<String, URL> stringURLEntry : ejbModules.entrySet()) {
                try {
                    URL ejbUrl = stringURLEntry.getValue();
                    // we should try to use a reference to the temp classloader
                    if (ClassLoaderUtil.isUrlCached(appModule.getJarLocation(), ejbUrl)) {
                        try {
                            ejbUrl = ClassLoaderUtil.getUrlCachedName(appModule.getJarLocation(), ejbUrl).toURI().toURL();

                        } catch (final MalformedURLException ignore) {
                            // no-op
                        }
                    }
                    final File ejbFile = URLs.toFile(ejbUrl);
                    final String absolutePath = ejbFile.getAbsolutePath();

                    final EjbModule ejbModule = createEjbModule(ejbUrl, absolutePath, appClassLoader);
                    appModule.getEjbModules().add(ejbModule);
                } catch (final OpenEJBException e) {
                    LOGGER.error("Unable to load EJBs from EAR: " + appId + ", module: " + stringURLEntry.getKey() + ". Exception: " + e.getMessage(), e);
                }
            }

            // Application Client Modules
            for (final Map.Entry<String, URL> stringURLEntry : clientModules.entrySet()) {
                try {
                    URL clientUrl = stringURLEntry.getValue();
                    // we should try to use a reference to the temp classloader
                    if (ClassLoaderUtil.isUrlCached(appModule.getJarLocation(), clientUrl)) {
                        try {
                            clientUrl = ClassLoaderUtil.getUrlCachedName(appModule.getJarLocation(), clientUrl).toURI().toURL();

                        } catch (final MalformedURLException ignore) {
                            // no-op
                        }
                    }
                    final File clientFile = URLs.toFile(clientUrl);
                    final String absolutePath = clientFile.getAbsolutePath();

                    final ClientModule clientModule = createClientModule(clientUrl, absolutePath, appClassLoader, null);

                    appModule.getClientModules().add(clientModule);
                } catch (final Exception e) {
                    LOGGER.error("Unable to load App Client from EAR: " + appId + ", module: " + stringURLEntry.getKey() + ". Exception: " + e.getMessage(), e);
                }
            }

            // Resource modules
            for (final Map.Entry<String, URL> stringURLEntry : resouceModules.entrySet()) {
                try {
                    URL rarUrl = stringURLEntry.getValue();
                    // we should try to use a reference to the temp classloader
                    if (ClassLoaderUtil.isUrlCached(appModule.getJarLocation(), rarUrl)) {
                        try {
                            rarUrl = ClassLoaderUtil.getUrlCachedName(appModule.getJarLocation(), rarUrl).toURI().toURL();

                        } catch (final MalformedURLException ignore) {
                            // no-op
                        }
                    }
                    final ConnectorModule connectorModule = createConnectorModule(appId, URLs.toFilePath(rarUrl), appClassLoader, stringURLEntry.getKey());
                    if (connectorModule != null) {
                        appModule.getConnectorModules().add(connectorModule);
                    }
                } catch (final OpenEJBException e) {
                    LOGGER.error("Unable to load RAR: " + appId + ", module: " + stringURLEntry.getKey() + ". Exception: " + e.getMessage(), e);
                }
            }

            // Web modules
            for (final Map.Entry<String, URL> stringURLEntry : webModules.entrySet()) {
                try {
                    final URL warUrl = stringURLEntry.getValue();
                    addWebModule(appModule, warUrl, appClassLoader, webContextRoots.get(stringURLEntry.getKey()), null);
                } catch (final OpenEJBException e) {
                    LOGGER.error("Unable to load WAR: " + appId + ", module: " + stringURLEntry.getKey() + ". Exception: " + e.getMessage(), e);
                }
            }


            addBeansXmls(appModule);

            // Persistence Units
            final Properties p = new Properties();
            p.put(appModule.getModuleId(), appModule.getJarLocation());
            final FileUtils base = new FileUtils(appModule.getModuleId(), appModule.getModuleId(), p);
            final List<URL> filteredUrls = new ArrayList<>();
            DeploymentsResolver.loadFromClasspath(base, filteredUrls, appModule.getClassLoader());
            addPersistenceUnits(appModule, filteredUrls.toArray(new URL[filteredUrls.size()]));

            final Object pXmls = appModule.getAltDDs().get("persistence.xml");

            for (final WebModule webModule : appModule.getWebModules()) {
                final List<URL> foundRootUrls = new ArrayList<>();
                final List<URL> scannableUrls = webModule.getScannableUrls();
                for (final URL url : scannableUrls) {
                    if (!addPersistenceUnits(appModule, url).isEmpty()) {
                        foundRootUrls.add(url);
                    }
                }

                if (pXmls != null && Collection.class.isInstance(pXmls)) {
                    final File webapp = webModule.getFile();
                    if (webapp == null) {
                        continue;
                    }
                    final String webappAbsolutePath = webapp.getAbsolutePath();

                    final Collection<URL> list = Collection.class.cast(pXmls);
                    for (final URL url : list) {
                        try {
                            final File file = URLs.toFile(url);
                            if (file.getAbsolutePath().startsWith(webappAbsolutePath)) {
                                foundRootUrls.add(url);
                            }
                        } catch (final IllegalArgumentException iae) {
                            // no-op
                        }
                    }
                }

                webModule.getAltDDs().put(EAR_WEBAPP_PERSISTENCE_XML_JARS, foundRootUrls);
            }

            for (final DeploymentModule module : appModule.getDeploymentModule()) {
                module.setStandaloneModule(false);
            }

            return appModule;

        } catch (final OpenEJBException e) {
            LOGGER.error("Unable to load EAR: " + jarPath, e);
            throw e;
        }
    }