Search in sources :

Example 6 with ClassLoaderConfigurer

use of org.apache.openejb.classloader.ClassLoaderConfigurer in project tomee by apache.

the class ClassLoaderUtil method createTempClassLoader.

public static URLClassLoader createTempClassLoader(final String appId, final URL[] rawUrls, final ClassLoader parent) {
    String updatedAppId = appId;
    if (appId != null) {
        // here we often get the full path of the app as id where later it is simply the name of the file/dir
        final File file = new File(appId);
        if (file.exists()) {
            updatedAppId = file.getName();
            if (updatedAppId.endsWith(".war") || updatedAppId.endsWith(".ear")) {
                updatedAppId = updatedAppId.substring(0, updatedAppId.length() - ".war".length());
            }
        }
    }
    // from the app
    final ClassLoaderConfigurer configurer1 = QuickJarsTxtParser.parse(new File(appId, "META-INF/" + QuickJarsTxtParser.FILE_NAME));
    final ClassLoaderConfigurer configurer2 = QuickJarsTxtParser.parse(new File(appId, "WEB-INF/" + QuickJarsTxtParser.FILE_NAME));
    // external config
    ClassLoaderConfigurer configurer3 = ClassLoaderUtil.configurer(updatedAppId);
    if (configurer3 == null) {
        // try the complete path
        configurer3 = ClassLoaderUtil.configurer(appId);
    }
    final URL[] urls;
    if (configurer1 == null && configurer2 == null && configurer3 == null) {
        urls = rawUrls;
    } else {
        final CompositeClassLoaderConfigurer configurer = new CompositeClassLoaderConfigurer(configurer1, configurer2, configurer3);
        final Collection<URL> list = new ArrayList<>(Arrays.asList(rawUrls));
        ClassLoaderConfigurer.Helper.configure(list, configurer);
        urls = list.toArray(new URL[list.size()]);
    }
    return new TempClassLoader(createClassLoader(appId, urls, parent));
}
Also used : TempClassLoader(org.apache.openejb.core.TempClassLoader) CompositeClassLoaderConfigurer(org.apache.openejb.classloader.CompositeClassLoaderConfigurer) ArrayList(java.util.ArrayList) ClassLoaderConfigurer(org.apache.openejb.classloader.ClassLoaderConfigurer) CompositeClassLoaderConfigurer(org.apache.openejb.classloader.CompositeClassLoaderConfigurer) JarFile(java.util.jar.JarFile) ZipFile(java.util.zip.ZipFile) File(java.io.File) URL(java.net.URL)

Example 7 with ClassLoaderConfigurer

use of org.apache.openejb.classloader.ClassLoaderConfigurer in project tomee by apache.

the class Assembler method createAppClassLoader.

public ClassLoader createAppClassLoader(final AppInfo appInfo) throws OpenEJBException, IOException {
    if ("openejb".equals(appInfo.appId)) {
        return ParentClassLoaderFinder.Helper.get();
    }
    final Set<URL> jars = new HashSet<>();
    for (final EjbJarInfo info : appInfo.ejbJars) {
        if (info.path != null) {
            jars.add(toUrl(info.path));
        }
    }
    for (final ClientInfo info : appInfo.clients) {
        if (info.path != null) {
            jars.add(toUrl(info.path));
        }
    }
    for (final ConnectorInfo info : appInfo.connectors) {
        for (final String jarPath : info.libs) {
            jars.add(toUrl(jarPath));
        }
    }
    for (final String jarPath : appInfo.libs) {
        jars.add(toUrl(jarPath));
    }
    // add openejb-jpa-integration if the jpa provider is in lib/
    if (appInfo.libs.size() > 0) {
        // the test could be enhanced
        try {
            final File jpaIntegrationFile = JarLocation.jarLocation(MakeTxLookup.class);
            final URL url = jpaIntegrationFile.toURI().toURL();
            if (!jars.contains(url)) {
                // could have been done before (webapp enrichment or manually for instance)
                jars.add(url);
            }
        } catch (final RuntimeException re) {
            logger.warning("Unable to find the open-jpa-integration jar");
        }
    }
    final ClassLoaderEnricher component = SystemInstance.get().getComponent(ClassLoaderEnricher.class);
    if (component != null) {
        jars.addAll(Arrays.asList(component.applicationEnrichment()));
    } else {
        logger.warning("Unable to find open-jpa-integration jar");
    }
    // Create the class loader
    final ClassLoader parent = ParentClassLoaderFinder.Helper.get();
    final String prefix;
    if (appInfo.webAppAlone) {
        prefix = "WEB-INF/";
    } else {
        prefix = "META-INF/";
    }
    final ClassLoaderConfigurer configurer1 = QuickJarsTxtParser.parse(new File(appInfo.path, prefix + QuickJarsTxtParser.FILE_NAME));
    final ClassLoaderConfigurer configurer2 = ClassLoaderUtil.configurer(appInfo.appId);
    if (configurer1 != null || configurer2 != null) {
        final ClassLoaderConfigurer configurer = new CompositeClassLoaderConfigurer(configurer1, configurer2);
        ClassLoaderConfigurer.Helper.configure(jars, configurer);
    }
    final URL[] filtered = jars.toArray(new URL[jars.size()]);
    // since we don't really need to create a classloader here when starting from classpath just let skip this step
    if (skipLoaderIfPossible) {
        // TODO: maybe use a boolean to know if all urls comes from the classpath to avoid this validation
        if ("classpath.ear".equals(appInfo.appId)) {
            return parent;
        }
        final Collection<File> urls = new HashSet<>();
        for (final URL url : ClassLoaders.findUrls(parent)) {
            // need to convert it to file since urls can be file:/xxx or jar:file:///xxx
            try {
                urls.add(URLs.toFile(url).getCanonicalFile());
            } catch (final Exception error) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Can't determine url for: " + url.toExternalForm(), error);
                }
            }
        }
        boolean allIsIntheClasspath = true;
        for (final URL url : filtered) {
            try {
                if (!urls.contains(URLs.toFile(url).getCanonicalFile())) {
                    allIsIntheClasspath = false;
                    if (logger.isDebugEnabled()) {
                        logger.debug(url.toExternalForm() + " (" + URLs.toFile(url) + ") is not in the classloader so we'll create a dedicated classloader for this app");
                    }
                    break;
                }
            } catch (final Exception ignored) {
                allIsIntheClasspath = false;
                if (logger.isDebugEnabled()) {
                    logger.debug(url.toExternalForm() + " (" + URLs.toFile(url) + ") is not in the classloader", ignored);
                }
                break;
            }
        }
        if (allIsIntheClasspath) {
            logger.info("Not creating another application classloader for " + appInfo.appId);
            return parent;
        } else if (logger.isDebugEnabled()) {
            logger.debug("Logging all urls from the app since we don't skip the app classloader creation:");
            for (final URL url : filtered) {
                logger.debug(" -> " + url.toExternalForm());
            }
            logger.debug("Logging all urls from the classloader since we don't skip the app classloader creation:");
            for (final File url : urls) {
                logger.debug(" -> " + url.getAbsolutePath());
            }
        }
    }
    logger.info("Creating dedicated application classloader for " + appInfo.appId);
    if (!appInfo.delegateFirst) {
        return ClassLoaderUtil.createClassLoader(appInfo.path, filtered, parent);
    }
    return ClassLoaderUtil.createClassLoaderFirst(appInfo.path, filtered, parent);
}
Also used : CompositeClassLoaderConfigurer(org.apache.openejb.classloader.CompositeClassLoaderConfigurer) ClassLoaderEnricher(org.apache.openejb.component.ClassLoaderEnricher) ClassLoaderConfigurer(org.apache.openejb.classloader.ClassLoaderConfigurer) CompositeClassLoaderConfigurer(org.apache.openejb.classloader.CompositeClassLoaderConfigurer) URL(java.net.URL) InvalidObjectException(java.io.InvalidObjectException) NameAlreadyBoundException(javax.naming.NameAlreadyBoundException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ObjectStreamException(java.io.ObjectStreamException) ResourceAdapterInternalException(javax.resource.spi.ResourceAdapterInternalException) URISyntaxException(java.net.URISyntaxException) UndeployException(org.apache.openejb.UndeployException) DefinitionException(javax.enterprise.inject.spi.DefinitionException) ConstructionException(org.apache.xbean.recipe.ConstructionException) MBeanRegistrationException(javax.management.MBeanRegistrationException) InstanceNotFoundException(javax.management.InstanceNotFoundException) ValidationException(javax.validation.ValidationException) MalformedObjectNameException(javax.management.MalformedObjectNameException) DuplicateDeploymentIdException(org.apache.openejb.DuplicateDeploymentIdException) TimeoutException(java.util.concurrent.TimeoutException) NamingException(javax.naming.NamingException) OpenEJBException(org.apache.openejb.OpenEJBException) DeploymentException(javax.enterprise.inject.spi.DeploymentException) NoSuchApplicationException(org.apache.openejb.NoSuchApplicationException) MalformedURLException(java.net.MalformedURLException) OpenEJBRuntimeException(org.apache.openejb.OpenEJBRuntimeException) OpenEJBRuntimeException(org.apache.openejb.OpenEJBRuntimeException) File(java.io.File) HashSet(java.util.HashSet)

Example 8 with ClassLoaderConfigurer

use of org.apache.openejb.classloader.ClassLoaderConfigurer in project tomee by apache.

the class DeploymentLoader method createAppModule.

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);
                }
            }
        }
        // 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;
    }
}
Also used : OpenEJBException(org.apache.openejb.OpenEJBException) MalformedURLException(java.net.MalformedURLException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) FileUtils(org.apache.openejb.loader.FileUtils) ArrayList(java.util.ArrayList) ClassLoaderConfigurer(org.apache.openejb.classloader.ClassLoaderConfigurer) Properties(java.util.Properties) URL(java.net.URL) LinkedHashMap(java.util.LinkedHashMap) ZipEntry(java.util.zip.ZipEntry) JarEntry(java.util.jar.JarEntry) URLClassLoader(java.net.URLClassLoader) EmptyResourcesClassLoader(org.apache.openejb.core.EmptyResourcesClassLoader) BeforeDeploymentEvent(org.apache.openejb.config.event.BeforeDeploymentEvent) ResourceFinder(org.apache.xbean.finder.ResourceFinder) IOException(java.io.IOException) OpenEJBException(org.apache.openejb.OpenEJBException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) Collection(java.util.Collection) Resources(org.apache.openejb.config.sys.Resources) Module(org.apache.openejb.jee.Module) JarFile(java.util.jar.JarFile) File(java.io.File) Application(org.apache.openejb.jee.Application) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TreeMap(java.util.TreeMap)

Example 9 with ClassLoaderConfigurer

use of org.apache.openejb.classloader.ClassLoaderConfigurer in project tomee by apache.

the class DeploymentLoader method createWebModule.

public WebModule createWebModule(final String appId, final String warPath, final ClassLoader parentClassLoader, final String contextRoot, final String moduleName, final ExternalConfiguration config) throws OpenEJBException {
    File warFile = new File(warPath);
    if (!warFile.isDirectory()) {
        warFile = unpack(warFile);
    }
    // read web.xml file
    final Map<String, URL> descriptors;
    try {
        descriptors = getWebDescriptors(warFile);
    } catch (final IOException e) {
        throw new OpenEJBException("Unable to collect descriptors in web module: " + contextRoot, e);
    }
    final WebApp webApp;
    final URL webXmlUrl = descriptors.get("web.xml");
    if (webXmlUrl != null) {
        webApp = ReadDescriptors.readWebApp(webXmlUrl);
    } else {
        // no web.xml webapp - possible since Servlet 3.0
        webApp = new WebApp();
    }
    // determine war class path
    ensureContainerUrls();
    final List<URL> webUrls = new ArrayList<>(containerUrls);
    final SystemInstance systemInstance = SystemInstance.get();
    // add these urls first to ensure we load classes from here first
    final String externalRepos = systemInstance.getProperty("tomee." + warFile.getName().replace(".war", "") + ".externalRepositories");
    List<URL> externalUrls = null;
    if (externalRepos != null) {
        externalUrls = new ArrayList<>();
        for (final String additional : externalRepos.split(",")) {
            final String trim = additional.trim();
            if (!trim.isEmpty()) {
                try {
                    externalUrls.add(new File(trim).toURI().toURL());
                } catch (final MalformedURLException e) {
                    LOGGER.error(e.getMessage());
                }
            }
        }
        webUrls.addAll(externalUrls);
    }
    final Map<String, URL[]> urls = getWebappUrlsAndRars(warFile);
    webUrls.addAll(Arrays.asList(urls.get(URLS_KEY)));
    final List<URL> addedUrls = new ArrayList<>();
    for (final URL url : urls.get(RAR_URLS_KEY)) {
        // eager unpack to be able to use it in classloader
        final File[] files = unpack(URLs.toFile(url)).listFiles();
        if (files != null) {
            for (final File f : files) {
                if (f.getName().endsWith(".jar")) {
                    try {
                        addedUrls.add(f.toURI().toURL());
                    } catch (final MalformedURLException e) {
                        LOGGER.warning("War path bad: " + f.getAbsolutePath(), e);
                    }
                }
            }
        }
    }
    webUrls.addAll(addedUrls);
    // context.xml can define some additional libraries
    if (config != null) {
        // we don't test all !=null inline to show that config will get extra params in the future and that it is hierarchic
        if (config.getClasspath() != null && config.getClasspath().length > 0) {
            final Set<URL> contextXmlUrls = new LinkedHashSet<>();
            for (final String location : config.getClasspath()) {
                try {
                    webUrls.add(new File(location).toURI().toURL());
                } catch (final MalformedURLException e) {
                    throw new IllegalArgumentException(e);
                }
            }
            webUrls.addAll(contextXmlUrls);
        }
    }
    final ClassLoaderConfigurer configurer = QuickJarsTxtParser.parse(new File(warFile, "WEB-INF/" + QuickJarsTxtParser.FILE_NAME));
    if (configurer != null) {
        ClassLoaderConfigurer.Helper.configure(webUrls, configurer);
    }
    final URL[] webUrlsArray = webUrls.toArray(new URL[webUrls.size()]);
    // in TomEE this is done in init hook since we don't manage tomee webapp classloader
    // so here is not the best idea for tomee
    // if we want to manage it in a generic way
    // simply add a boolean shared between tomcat and openejb world
    // to know if we should fire it or not
    systemInstance.fireEvent(new BeforeDeploymentEvent(webUrlsArray, parentClassLoader));
    final ClassLoader warClassLoader = ClassLoaderUtil.createTempClassLoader(appId, webUrlsArray, parentClassLoader);
    // create web module
    final List<URL> scannableUrls = filterWebappUrls(webUrlsArray, config == null ? null : config.customerFilter, descriptors.get(NewLoaderLogic.EXCLUSION_FILE));
    // executable war will add war in scannable urls, we don't want it since it will surely contain tomee, cxf, ...
    if (Boolean.parseBoolean(systemInstance.getProperty("openejb.core.skip-war-in-loader", "true"))) {
        File archive = warFile;
        if (!archive.getName().endsWith(".war")) {
            archive = new File(warFile.getParentFile(), warFile.getName() + ".war");
            final String unpackDir = systemInstance.getProperty("tomee.unpack.dir");
            if (unpackDir != null && !archive.isFile()) {
                try {
                    archive = new File(systemInstance.getBase().getDirectory(unpackDir, false), warFile.getName());
                } catch (final IOException e) {
                // no-op
                }
            }
        }
        if (archive.isFile()) {
            try {
                scannableUrls.remove(archive.toURI().toURL());
            } catch (final MalformedURLException e) {
            // no-op
            }
        }
    }
    if (externalUrls != null) {
        for (final URL url : externalUrls) {
            if (scannableUrls.contains(url)) {
                scannableUrls.remove(url);
                scannableUrls.add(0, url);
            }
        }
    }
    SystemInstance.get().fireEvent(new EnhanceScannableUrlsEvent(scannableUrls));
    final WebModule webModule = new WebModule(webApp, contextRoot, warClassLoader, warFile.getAbsolutePath(), moduleName);
    webModule.setUrls(webUrls);
    webModule.setAddedUrls(addedUrls);
    webModule.setRarUrls(Arrays.asList(urls.get(RAR_URLS_KEY)));
    webModule.setScannableUrls(scannableUrls);
    webModule.setDefaultContextPath(webApp.getDefaultContextPath());
    webModule.getAltDDs().putAll(descriptors);
    webModule.getWatchedResources().add(warPath);
    webModule.getWatchedResources().add(warFile.getAbsolutePath());
    if (webXmlUrl != null && "file".equals(webXmlUrl.getProtocol())) {
        webModule.getWatchedResources().add(URLs.toFilePath(webXmlUrl));
    }
    // If webModule object is loaded by ejbModule or persitenceModule, no need to load tag libraries, web service and JSF related staffs.
    addTagLibraries(webModule);
    // load webservices descriptor
    addWebservices(webModule);
    // load faces configuration files
    addFacesConfigs(webModule);
    addBeansXmls(webModule);
    return webModule;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) OpenEJBException(org.apache.openejb.OpenEJBException) MalformedURLException(java.net.MalformedURLException) EnhanceScannableUrlsEvent(org.apache.openejb.config.event.EnhanceScannableUrlsEvent) ArrayList(java.util.ArrayList) IOException(java.io.IOException) ClassLoaderConfigurer(org.apache.openejb.classloader.ClassLoaderConfigurer) URL(java.net.URL) SystemInstance(org.apache.openejb.loader.SystemInstance) URLClassLoader(java.net.URLClassLoader) EmptyResourcesClassLoader(org.apache.openejb.core.EmptyResourcesClassLoader) JarFile(java.util.jar.JarFile) File(java.io.File) BeforeDeploymentEvent(org.apache.openejb.config.event.BeforeDeploymentEvent) WebApp(org.apache.openejb.jee.WebApp)

Aggregations

ClassLoaderConfigurer (org.apache.openejb.classloader.ClassLoaderConfigurer)9 File (java.io.File)8 URL (java.net.URL)7 IOException (java.io.IOException)5 ArrayList (java.util.ArrayList)5 CompositeClassLoaderConfigurer (org.apache.openejb.classloader.CompositeClassLoaderConfigurer)5 MalformedURLException (java.net.MalformedURLException)4 URLClassLoader (java.net.URLClassLoader)4 JarFile (java.util.jar.JarFile)4 HashMap (java.util.HashMap)3 OpenEJBException (org.apache.openejb.OpenEJBException)3 EmptyResourcesClassLoader (org.apache.openejb.core.EmptyResourcesClassLoader)3 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 Properties (java.util.Properties)2 BeforeDeploymentEvent (org.apache.openejb.config.event.BeforeDeploymentEvent)2 InvalidObjectException (java.io.InvalidObjectException)1 ObjectStreamException (java.io.ObjectStreamException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1