Search in sources :

Example 1 with URLClassLoaderFirst

use of org.apache.openejb.util.classloader.URLClassLoaderFirst in project tomee by apache.

the class OpenEJBArchiveProcessor method createModule.

public static AppModule createModule(final Archive<?> archive, final TestClass testClass, final Closeables closeables) {
    final Class<?> javaClass;
    if (testClass != null) {
        javaClass = testClass.getJavaClass();
    } else {
        javaClass = null;
    }
    final ClassLoader parent;
    if (javaClass == null) {
        parent = Thread.currentThread().getContextClassLoader();
    } else {
        parent = javaClass.getClassLoader();
    }
    final List<URL> additionalPaths = new ArrayList<>();
    CompositeArchive scannedArchive = null;
    final Map<URL, List<String>> earMap = new HashMap<>();
    final Map<String, Object> altDD = new HashMap<>();
    final List<Archive> earLibsArchives = new ArrayList<>();
    final CompositeBeans earBeans = new CompositeBeans();
    final boolean isEar = EnterpriseArchive.class.isInstance(archive);
    final boolean isWebApp = WebArchive.class.isInstance(archive);
    final String prefix = isWebApp ? WEB_INF : META_INF;
    if (isEar || isWebApp) {
        final Map<ArchivePath, Node> jars = archive.getContent(new IncludeRegExpPaths(isEar ? "/.*\\.jar" : "/WEB-INF/lib/.*\\.jar"));
        scannedArchive = analyzeLibs(parent, additionalPaths, earMap, earLibsArchives, earBeans, jars, altDD);
    }
    final URL[] urls = additionalPaths.toArray(new URL[additionalPaths.size()]);
    final URLClassLoaderFirst swParent = new URLClassLoaderFirst(urls, parent);
    closeables.add(swParent);
    if (!isEar) {
        earLibsArchives.add(archive);
    }
    final SWClassLoader loader = new SWClassLoader(swParent, earLibsArchives.toArray(new Archive<?>[earLibsArchives.size()]));
    closeables.add(loader);
    final URLClassLoader tempClassLoader = ClassLoaderUtil.createTempClassLoader(loader);
    closeables.add(tempClassLoader);
    final AppModule appModule = new AppModule(loader, archive.getName());
    if (WEB_INF.equals(prefix)) {
        appModule.setDelegateFirst(false);
        appModule.setStandloneWebModule();
        final WebModule webModule = new WebModule(createWebApp(archive), contextRoot(archive.getName()), loader, "", appModule.getModuleId());
        webModule.setUrls(additionalPaths);
        appModule.getWebModules().add(webModule);
    } else if (isEar) {
        // mainly for CDI TCKs
        final FinderFactory.OpenEJBAnnotationFinder earLibFinder = new FinderFactory.OpenEJBAnnotationFinder(new SimpleWebappAggregatedArchive(tempClassLoader, scannedArchive, earMap));
        appModule.setEarLibFinder(earLibFinder);
        final EjbModule earCdiModule = new EjbModule(appModule.getClassLoader(), DeploymentLoader.EAR_SCOPED_CDI_BEANS + appModule.getModuleId(), new EjbJar(), new OpenejbJar());
        earCdiModule.setBeans(earBeans);
        earCdiModule.setFinder(earLibFinder);
        final EjbJar ejbJar;
        final AssetSource ejbJarXml = AssetSource.class.isInstance(altDD.get(EJB_JAR_XML)) ? AssetSource.class.cast(altDD.get(EJB_JAR_XML)) : null;
        if (ejbJarXml != null) {
            try {
                ejbJar = ReadDescriptors.readEjbJar(ejbJarXml.get());
            } catch (final Exception e) {
                throw new OpenEJBRuntimeException(e);
            }
        } else {
            ejbJar = new EjbJar();
        }
        // EmptyEjbJar would prevent to add scanned EJBs but this is *here* an aggregator so we need to be able to do so
        earCdiModule.setEjbJar(ejbJar);
        appModule.getEjbModules().add(earCdiModule);
        for (final Map.Entry<ArchivePath, Node> node : archive.getContent(new IncludeRegExpPaths("/.*\\.war")).entrySet()) {
            final Asset asset = node.getValue().getAsset();
            if (ArchiveAsset.class.isInstance(asset)) {
                final Archive<?> webArchive = ArchiveAsset.class.cast(asset).getArchive();
                if (WebArchive.class.isInstance(webArchive)) {
                    final Map<String, Object> webAltDD = new HashMap<>();
                    final Node beansXml = findBeansXml(webArchive, WEB_INF);
                    final List<URL> webappAdditionalPaths = new LinkedList<>();
                    final CompositeBeans webAppBeansXml = new CompositeBeans();
                    final List<Archive> webAppArchives = new LinkedList<Archive>();
                    final Map<URL, List<String>> webAppClassesByUrl = new HashMap<URL, List<String>>();
                    final CompositeArchive webAppArchive = analyzeLibs(parent, webappAdditionalPaths, webAppClassesByUrl, webAppArchives, webAppBeansXml, webArchive.getContent(new IncludeRegExpPaths("/WEB-INF/lib/.*\\.jar")), webAltDD);
                    webAppArchives.add(webArchive);
                    final SWClassLoader webLoader = new SWClassLoader(parent, webAppArchives.toArray(new Archive<?>[webAppArchives.size()]));
                    closeables.add(webLoader);
                    final FinderFactory.OpenEJBAnnotationFinder finder = new FinderFactory.OpenEJBAnnotationFinder(finderArchive(beansXml, webArchive, webLoader, webAppArchive, webAppClassesByUrl, webAppBeansXml));
                    final String contextRoot = contextRoot(webArchive.getName());
                    final WebModule webModule = new WebModule(createWebApp(webArchive), contextRoot, webLoader, "", appModule.getModuleId() + "_" + contextRoot);
                    webModule.setUrls(Collections.<URL>emptyList());
                    webModule.setScannableUrls(Collections.<URL>emptyList());
                    webModule.setFinder(finder);
                    final EjbJar webEjbJar = createEjbJar(prefix, webArchive);
                    final EjbModule ejbModule = new EjbModule(webLoader, webModule.getModuleId(), null, webEjbJar, new OpenejbJar());
                    ejbModule.setBeans(webAppBeansXml);
                    ejbModule.getAltDDs().putAll(webAltDD);
                    ejbModule.getAltDDs().put("beans.xml", webAppBeansXml);
                    ejbModule.setFinder(finder);
                    ejbModule.setClassLoader(webLoader);
                    ejbModule.setWebapp(true);
                    appModule.getEjbModules().add(ejbModule);
                    appModule.getWebModules().add(webModule);
                    addPersistenceXml(archive, WEB_INF, appModule);
                    addOpenEJbJarXml(archive, WEB_INF, ejbModule);
                    addValidationXml(archive, WEB_INF, new HashMap<String, Object>(), ejbModule);
                    addResourcesXml(archive, WEB_INF, ejbModule);
                    addEnvEntries(archive, WEB_INF, appModule, ejbModule);
                }
            }
        }
    }
    if (isEar) {
        // adding the test class as lib class can break test if tested against the web part of the ear
        addTestClassAsManagedBean(javaClass, tempClassLoader, appModule);
        return appModule;
    }
    // add the test as a managed bean to be able to inject into it easily
    final Map<String, Object> testDD;
    if (javaClass != null) {
        final EjbModule testEjbModule = addTestClassAsManagedBean(javaClass, tempClassLoader, appModule);
        testDD = testEjbModule.getAltDDs();
    } else {
        // ignore
        testDD = new HashMap<>();
    }
    final EjbJar ejbJar = createEjbJar(prefix, archive);
    if (ejbJar.getModuleName() == null) {
        final String name = archive.getName();
        if (name.endsWith("ar") && name.length() > 4) {
            ejbJar.setModuleName(name.substring(0, name.length() - ".jar".length()));
        } else {
            ejbJar.setModuleName(name);
        }
    }
    final EjbModule ejbModule = new EjbModule(ejbJar);
    ejbModule.setClassLoader(tempClassLoader);
    final Node beansXml = findBeansXml(archive, prefix);
    final FinderFactory.OpenEJBAnnotationFinder finder = new FinderFactory.OpenEJBAnnotationFinder(finderArchive(beansXml, archive, loader, scannedArchive, earMap, earBeans));
    ejbModule.setFinder(finder);
    ejbModule.setBeans(earBeans);
    ejbModule.getAltDDs().put("beans.xml", earBeans);
    if (appModule.isWebapp()) {
        // war
        appModule.getWebModules().iterator().next().setFinder(ejbModule.getFinder());
    }
    appModule.getEjbModules().add(ejbModule);
    addPersistenceXml(archive, prefix, appModule);
    addOpenEJbJarXml(archive, prefix, ejbModule);
    addValidationXml(archive, prefix, testDD, ejbModule);
    addResourcesXml(archive, prefix, ejbModule);
    addEnvEntries(archive, prefix, appModule, ejbModule);
    if (!appModule.isWebapp()) {
        appModule.getAdditionalLibraries().addAll(additionalPaths);
    }
    if (archive.getName().endsWith(".jar")) {
        // otherwise global naming will be broken
        appModule.setStandloneWebModule();
    }
    return appModule;
}
Also used : URLClassLoaderFirst(org.apache.openejb.util.classloader.URLClassLoaderFirst) FilteredArchive(org.apache.xbean.finder.archive.FilteredArchive) ClassesArchive(org.apache.xbean.finder.archive.ClassesArchive) EnterpriseArchive(org.jboss.shrinkwrap.api.spec.EnterpriseArchive) WebappAggregatedArchive(org.apache.openejb.config.WebappAggregatedArchive) WebArchive(org.jboss.shrinkwrap.api.spec.WebArchive) JarArchive(org.apache.xbean.finder.archive.JarArchive) Archive(org.jboss.shrinkwrap.api.Archive) CompositeArchive(org.apache.xbean.finder.archive.CompositeArchive) AppModule(org.apache.openejb.config.AppModule) HashMap(java.util.HashMap) Node(org.jboss.shrinkwrap.api.Node) ArrayList(java.util.ArrayList) EjbModule(org.apache.openejb.config.EjbModule) URL(java.net.URL) ArchivePath(org.jboss.shrinkwrap.api.ArchivePath) OpenejbJar(org.apache.openejb.jee.oejb3.OpenejbJar) URLClassLoader(java.net.URLClassLoader) Asset(org.jboss.shrinkwrap.api.asset.Asset) FileAsset(org.jboss.shrinkwrap.api.asset.FileAsset) ClassLoaderAsset(org.jboss.shrinkwrap.api.asset.ClassLoaderAsset) ArchiveAsset(org.jboss.shrinkwrap.api.asset.ArchiveAsset) UrlAsset(org.jboss.shrinkwrap.api.asset.UrlAsset) Arrays.asList(java.util.Arrays.asList) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) IncludeRegExpPaths(org.jboss.shrinkwrap.impl.base.filter.IncludeRegExpPaths) EjbJar(org.apache.openejb.jee.EjbJar) CompositeBeans(org.apache.openejb.cdi.CompositeBeans) WebArchive(org.jboss.shrinkwrap.api.spec.WebArchive) ArchiveAsset(org.jboss.shrinkwrap.api.asset.ArchiveAsset) WebModule(org.apache.openejb.config.WebModule) FinderFactory(org.apache.openejb.config.FinderFactory) OpenEJBException(org.apache.openejb.OpenEJBException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) OpenEJBRuntimeException(org.apache.openejb.OpenEJBRuntimeException) OpenEJBRuntimeException(org.apache.openejb.OpenEJBRuntimeException) CompositeArchive(org.apache.xbean.finder.archive.CompositeArchive) URLClassLoader(java.net.URLClassLoader) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with URLClassLoaderFirst

use of org.apache.openejb.util.classloader.URLClassLoaderFirst in project tomee by apache.

the class Assembler method doCreateResource.

private Object doCreateResource(final Collection<ServiceInfo> infos, final ResourceInfo serviceInfo) throws OpenEJBException {
    // do it early otherwise we can loose it
    final String skipPropertiesFallback = (String) serviceInfo.properties.remove("SkipPropertiesFallback");
    final ObjectRecipe serviceRecipe = createRecipe(infos, serviceInfo);
    final boolean properties = PropertiesFactory.class.getName().equals(serviceInfo.className);
    if ("false".equalsIgnoreCase(serviceInfo.properties.getProperty("SkipImplicitAttributes", "false")) && !properties) {
        serviceRecipe.setProperty("transactionManager", transactionManager);
        serviceRecipe.setProperty("ServiceId", serviceInfo.id);
    }
    serviceInfo.properties.remove("SkipImplicitAttributes");
    // if custom instance allow to skip properties fallback to avoid to set unexpectedly it - connectionProps of DBs
    final AtomicReference<Properties> injectedProperties = new AtomicReference<>();
    if (!"true".equalsIgnoreCase(skipPropertiesFallback)) {
        serviceRecipe.setProperty("properties", new UnsetPropertiesRecipe() {

            @Override
            protected Object internalCreate(final Type expectedType, final boolean lazyRefAllowed) throws ConstructionException {
                final Map<String, Object> original = serviceRecipe.getUnsetProperties();
                final Properties properties = new SuperProperties() {

                    @Override
                    public Object remove(final Object key) {
                        // avoid to log them then
                        original.remove(key);
                        return super.remove(key);
                    }
                }.caseInsensitive(// keep our nice case insensitive feature
                true);
                for (final Map.Entry<String, Object> entry : original.entrySet()) {
                    properties.put(entry.getKey(), entry.getValue());
                }
                injectedProperties.set(properties);
                return properties;
            }
        });
    } else {
        // this is not the best fallback we have but since it is super limited it is acceptable
        final Map<String, Object> unsetProperties = serviceRecipe.getUnsetProperties();
        injectedProperties.set(new Properties() {

            @Override
            public String getProperty(final String key) {
                final Object obj = unsetProperties.get(key);
                return String.class.isInstance(obj) ? String.valueOf(obj) : null;
            }

            @Override
            public Set<String> stringPropertyNames() {
                return unsetProperties.keySet();
            }

            @Override
            public Set<Object> keySet() {
                // noinspection unchecked
                return Set.class.cast(unsetProperties.keySet());
            }

            @Override
            public synchronized boolean containsKey(final Object key) {
                return getProperty(String.valueOf(key)) != null;
            }
        });
    }
    if (serviceInfo.types.contains("DataSource") || serviceInfo.types.contains(DataSource.class.getName())) {
        final Properties props = PropertyPlaceHolderHelper.simpleHolds(serviceInfo.properties);
        if (serviceInfo.properties.containsKey("Definition")) {
            final Object encoding = serviceInfo.properties.remove("DefinitionEncoding");
            try {
                // we catch classcast etc..., if it fails it is not important
                final InputStream is = new ByteArrayInputStream(serviceInfo.properties.getProperty("Definition").getBytes(encoding != null ? encoding.toString() : "ISO-8859-1"));
                final Properties p = new SuperProperties();
                IO.readProperties(is, p);
                for (final Entry<Object, Object> entry : p.entrySet()) {
                    final String key = entry.getKey().toString();
                    if (!props.containsKey(key) && !(key.equalsIgnoreCase("url") && props.containsKey("JdbcUrl"))) {
                        // with @DataSource we can get both, see org.apache.openejb.config.ConvertDataSourceDefinitions.rawDefinition()
                        props.put(key, entry.getValue());
                    }
                }
            } catch (final Exception e) {
            // ignored
            }
        }
        serviceRecipe.setProperty("Definition", PropertiesHelper.propertiesToString(props));
    }
    // else: any other kind of resource relying on it? shouldnt be
    replaceResourceAdapterProperty(serviceRecipe);
    ClassLoader loader = Thread.currentThread().getContextClassLoader();
    boolean customLoader = false;
    try {
        if (serviceInfo.classpath != null && serviceInfo.classpath.length > 0) {
            final URL[] urls = new URL[serviceInfo.classpath.length];
            for (int i = 0; i < serviceInfo.classpath.length; i++) {
                urls[i] = serviceInfo.classpath[i].toURL();
            }
            loader = new URLClassLoaderFirst(urls, loader);
            customLoader = true;
            serviceRecipe.setProperty("OpenEJBResourceClasspath", "true");
        }
    } catch (final MalformedURLException e) {
        throw new OpenEJBException("Unable to create a classloader for " + serviceInfo.id, e);
    }
    if (!customLoader && serviceInfo.classpathAPI != null) {
        throw new IllegalArgumentException("custom-api provided but not classpath used for " + serviceInfo.id);
    }
    Object service = serviceRecipe.create(loader);
    if (customLoader) {
        final Collection<Class<?>> apis;
        if (serviceInfo.classpathAPI == null) {
            apis = new ArrayList<>(Arrays.asList(service.getClass().getInterfaces()));
        } else {
            final String[] split = serviceInfo.classpathAPI.split(" *, *");
            apis = new ArrayList<>(split.length);
            final ClassLoader apiLoader = Thread.currentThread().getContextClassLoader();
            for (final String fqn : split) {
                try {
                    apis.add(apiLoader.loadClass(fqn));
                } catch (final ClassNotFoundException e) {
                    throw new IllegalArgumentException(fqn + " not usable as API for " + serviceInfo.id, e);
                }
            }
        }
        if (apis.size() - (apis.contains(Serializable.class) ? 1 : 0) - (apis.contains(Externalizable.class) ? 1 : 0) > 0) {
            service = Proxy.newProxyInstance(loader, apis.toArray(new Class<?>[apis.size()]), new ClassLoaderAwareHandler(null, service, loader));
        }
    // else proxy would be useless
    }
    serviceInfo.unsetProperties = injectedProperties.get();
    // Java Connector spec ResourceAdapters and ManagedConnectionFactories need special activation
    if (service instanceof ResourceAdapter) {
        final ResourceAdapter resourceAdapter = (ResourceAdapter) service;
        // Create a thead pool for work manager
        final int threadPoolSize = getIntProperty(serviceInfo.properties, "threadPoolSize", 30);
        final Executor threadPool;
        if (threadPoolSize <= 0) {
            logger.warning("Thread pool for '" + serviceInfo.id + "' is (unbounded), consider setting a size using: " + serviceInfo.id + ".QueueSize=[size]");
            threadPool = Executors.newCachedThreadPool(new DaemonThreadFactory(serviceInfo.id + "-worker-"));
        } else {
            threadPool = new ExecutorBuilder().size(threadPoolSize).prefix(serviceInfo.id).threadFactory(new DaemonThreadFactory(serviceInfo.id + "-worker-")).build(new Options(serviceInfo.properties, SystemInstance.get().getOptions()));
            logger.info("Thread pool size for '" + serviceInfo.id + "' is (" + threadPoolSize + ")");
        }
        // WorkManager: the resource adapter can use this to dispatch messages or perform tasks
        final WorkManager workManager;
        if (GeronimoTransactionManager.class.isInstance(transactionManager)) {
            final GeronimoTransactionManager geronimoTransactionManager = (GeronimoTransactionManager) transactionManager;
            final TransactionContextHandler txWorkContextHandler = new TransactionContextHandler(geronimoTransactionManager);
            // use id as default realm name if realm is not specified in service properties
            final String securityRealmName = getStringProperty(serviceInfo.properties, "realm", serviceInfo.id);
            final SecurityContextHandler securityContextHandler = new SecurityContextHandler(securityRealmName);
            final HintsContextHandler hintsContextHandler = new HintsContextHandler();
            final Collection<WorkContextHandler> workContextHandlers = new ArrayList<>();
            workContextHandlers.add(txWorkContextHandler);
            workContextHandlers.add(securityContextHandler);
            workContextHandlers.add(hintsContextHandler);
            workManager = new GeronimoWorkManager(threadPool, threadPool, threadPool, workContextHandlers);
        } else {
            workManager = new SimpleWorkManager(threadPool);
        }
        // BootstrapContext: wraps the WorkMananger and XATerminator
        final BootstrapContext bootstrapContext;
        if (transactionManager instanceof GeronimoTransactionManager) {
            bootstrapContext = new GeronimoBootstrapContext(GeronimoWorkManager.class.cast(workManager), (GeronimoTransactionManager) transactionManager, (GeronimoTransactionManager) transactionManager);
        } else if (transactionManager instanceof XATerminator) {
            bootstrapContext = new SimpleBootstrapContext(workManager, (XATerminator) transactionManager);
        } else {
            bootstrapContext = new SimpleBootstrapContext(workManager);
        }
        // start the resource adapter
        try {
            logger.debug("createResource.startingResourceAdapter", serviceInfo.id, service.getClass().getName());
            resourceAdapter.start(bootstrapContext);
        } catch (final ResourceAdapterInternalException e) {
            throw new OpenEJBException(e);
        }
        final Map<String, Object> unset = serviceRecipe.getUnsetProperties();
        unset.remove("threadPoolSize");
        logUnusedProperties(unset, serviceInfo);
        registerAsMBean(serviceInfo.id, "ResourceAdapter", resourceAdapter);
        service = new ResourceAdapterReference(resourceAdapter, threadPool, OPENEJB_RESOURCE_JNDI_PREFIX + serviceInfo.id);
    } else if (service instanceof ManagedConnectionFactory) {
        final ManagedConnectionFactory managedConnectionFactory = (ManagedConnectionFactory) service;
        // connection manager is constructed via a recipe so we automatically expose all cmf properties
        final ObjectRecipe connectionManagerRecipe = new ObjectRecipe(GeronimoConnectionManagerFactory.class, "create");
        connectionManagerRecipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
        connectionManagerRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
        connectionManagerRecipe.setAllProperties(serviceInfo.properties);
        connectionManagerRecipe.setProperty("name", serviceInfo.id);
        connectionManagerRecipe.setProperty("mcf", managedConnectionFactory);
        // standard properties
        connectionManagerRecipe.setProperty("transactionManager", transactionManager);
        ClassLoader classLoader = loader;
        if (classLoader == null) {
            classLoader = getClass().getClassLoader();
        }
        if (classLoader == null) {
            classLoader = ClassLoader.getSystemClassLoader();
        }
        connectionManagerRecipe.setProperty("classLoader", classLoader);
        logger.getChildLogger("service").info("createResource.createConnectionManager", serviceInfo.id, service.getClass().getName());
        // create the connection manager
        final ConnectionManager connectionManager = (ConnectionManager) connectionManagerRecipe.create();
        String txSupport = "xa";
        try {
            txSupport = (String) connectionManagerRecipe.getProperty("transactionSupport");
        } catch (Exception e) {
        // ignore
        }
        if (txSupport == null || txSupport.trim().length() == 0) {
            txSupport = "xa";
        }
        if (connectionManager == null) {
            throw new OpenEJBRuntimeException(messages.format("assembler.invalidConnectionManager", serviceInfo.id));
        }
        final Map<String, Object> unsetA = serviceRecipe.getUnsetProperties();
        final Map<String, Object> unsetB = connectionManagerRecipe.getUnsetProperties();
        final Map<String, Object> unset = new HashMap<>();
        for (final Entry<String, Object> entry : unsetA.entrySet()) {
            if (unsetB.containsKey(entry.getKey())) {
                unset.put(entry.getKey(), entry.getValue());
            }
        }
        // service becomes a ConnectorReference which merges connection manager and mcf
        service = new ConnectorReference(connectionManager, managedConnectionFactory);
        // init cm if needed
        final Object eagerInit = unset.remove("eagerInit");
        if (eagerInit != null && eagerInit instanceof String && "true".equalsIgnoreCase((String) eagerInit) && connectionManager instanceof AbstractConnectionManager) {
            try {
                ((AbstractConnectionManager) connectionManager).doStart();
                try {
                    final Object cf = managedConnectionFactory.createConnectionFactory(connectionManager);
                    if (cf instanceof ConnectionFactory) {
                        final Connection connection = ((ConnectionFactory) cf).getConnection();
                        connection.getMetaData();
                        connection.close();
                    }
                } catch (final Exception e) {
                // no-op: just to force eager init of pool
                }
            } catch (final Exception e) {
                logger.warning("Can't start connection manager", e);
            }
        }
        logUnusedProperties(unset, serviceInfo);
    } else if (service instanceof DataSource) {
        ClassLoader classLoader = loader;
        if (classLoader == null) {
            classLoader = getClass().getClassLoader();
        }
        final ImportSql importer = new ImportSql(classLoader, serviceInfo.id, (DataSource) service);
        if (importer.hasSomethingToImport()) {
            importer.doImport();
        }
        final ObjectRecipe recipe = DataSourceFactory.forgetRecipe(service, serviceRecipe);
        if (recipe != serviceRecipe || !serviceInfo.properties.containsKey("XaDataSource")) {
            logUnusedProperties(recipe, serviceInfo);
        }
        // else logged on xadatasource itself
        final Properties prop = serviceInfo.properties;
        String url = prop.getProperty("JdbcUrl", prop.getProperty("url"));
        if (url == null) {
            url = prop.getProperty("jdbcUrl");
        }
        if (url == null) {
            logger.debug("Unable to find url for " + serviceInfo.id + " will not monitor it");
        } else {
            final String host = extractHost(url);
            if (host != null) {
                remoteResourceMonitor.addHost(host);
                remoteResourceMonitor.registerIfNot();
            }
        }
    } else if (!Properties.class.isInstance(service)) {
        if (serviceInfo.unsetProperties == null || isTemplatizedResource(serviceInfo)) {
            logUnusedProperties(serviceRecipe, serviceInfo);
        }
        // else wait post construct
        registerAsMBean(serviceInfo.id, "Resource", service);
    }
    final ResourceCreated event = new ResourceCreated(service, serviceInfo.id);
    SystemInstance.get().fireEvent(event);
    return event.getReplacement() == null ? service : event.getReplacement();
}
Also used : URLClassLoaderFirst(org.apache.openejb.util.classloader.URLClassLoaderFirst) OpenEJBException(org.apache.openejb.OpenEJBException) MalformedURLException(java.net.MalformedURLException) Serializable(java.io.Serializable) GeronimoBootstrapContext(org.apache.geronimo.connector.GeronimoBootstrapContext) TransactionContextHandler(org.apache.geronimo.connector.work.TransactionContextHandler) ArrayList(java.util.ArrayList) GeronimoWorkManager(org.apache.geronimo.connector.work.GeronimoWorkManager) SuperProperties(org.apache.openejb.util.SuperProperties) ExecutorBuilder(org.apache.openejb.util.ExecutorBuilder) AbstractConnectionManager(org.apache.geronimo.connector.outbound.AbstractConnectionManager) ConnectionManager(javax.resource.spi.ConnectionManager) ObjectRecipe(org.apache.xbean.recipe.ObjectRecipe) SimpleWorkManager(org.apache.openejb.core.transaction.SimpleWorkManager) WorkManager(javax.resource.spi.work.WorkManager) GeronimoWorkManager(org.apache.geronimo.connector.work.GeronimoWorkManager) ResourceAdapter(javax.resource.spi.ResourceAdapter) SecurityContextHandler(org.apache.openejb.core.security.SecurityContextHandler) UnsetPropertiesRecipe(org.apache.xbean.recipe.UnsetPropertiesRecipe) GeronimoConnectionManagerFactory(org.apache.openejb.resource.GeronimoConnectionManagerFactory) DataSource(javax.sql.DataSource) OpenEJBRuntimeException(org.apache.openejb.OpenEJBRuntimeException) HintsContextHandler(org.apache.geronimo.connector.work.HintsContextHandler) SimpleBootstrapContext(org.apache.openejb.core.transaction.SimpleBootstrapContext) ByteArrayInputStream(java.io.ByteArrayInputStream) PropertiesFactory(org.apache.openejb.resource.PropertiesFactory) Map(java.util.Map) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap) ConnectorReference(org.apache.openejb.core.ConnectorReference) Options(org.apache.openejb.loader.Options) XATerminator(javax.resource.spi.XATerminator) HashSet(java.util.HashSet) Set(java.util.Set) UrlSet(org.apache.xbean.finder.UrlSet) ClassLoaderAwareHandler(org.apache.openejb.util.classloader.ClassLoaderAwareHandler) DaemonThreadFactory(org.apache.openejb.util.DaemonThreadFactory) SimpleWorkManager(org.apache.openejb.core.transaction.SimpleWorkManager) SimpleBootstrapContext(org.apache.openejb.core.transaction.SimpleBootstrapContext) GeronimoBootstrapContext(org.apache.geronimo.connector.GeronimoBootstrapContext) BootstrapContext(javax.resource.spi.BootstrapContext) AbstractConnectionManager(org.apache.geronimo.connector.outbound.AbstractConnectionManager) SuperProperties(org.apache.openejb.util.SuperProperties) Properties(java.util.Properties) URL(java.net.URL) Entry(java.util.Map.Entry) ManagedConnectionFactory(javax.resource.spi.ManagedConnectionFactory) ConnectionFactory(javax.resource.cci.ConnectionFactory) Executor(java.util.concurrent.Executor) GeronimoTransactionManager(org.apache.geronimo.transaction.manager.GeronimoTransactionManager) ResourceCreated(org.apache.openejb.assembler.classic.event.ResourceCreated) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Connection(javax.resource.cci.Connection) AtomicReference(java.util.concurrent.atomic.AtomicReference) ResourceAdapterInternalException(javax.resource.spi.ResourceAdapterInternalException) 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) BeanType(org.apache.openejb.BeanType) Type(java.lang.reflect.Type) TransactionType(org.apache.openejb.core.transaction.TransactionType) ManagedConnectionFactory(javax.resource.spi.ManagedConnectionFactory) ConstructionException(org.apache.xbean.recipe.ConstructionException) WorkContextHandler(org.apache.geronimo.connector.work.WorkContextHandler)

Example 3 with URLClassLoaderFirst

use of org.apache.openejb.util.classloader.URLClassLoaderFirst in project tomee by apache.

the class ConfigurationFactory method toConfigDeclaration.

public static Object toConfigDeclaration(final String id, final URI uri) throws OpenEJBException {
    final String serviceType;
    try {
        serviceType = uri.getHost();
        final Object object;
        try {
            object = JaxbOpenejb.create(serviceType);
        } catch (final Exception e) {
            throw new OpenEJBException("Invalid URI '" + uri + "'. " + e.getMessage());
        }
        final Map<String, String> map;
        try {
            map = URISupport.parseParamters(uri);
        } catch (final URISyntaxException e) {
            throw new OpenEJBException("Unable to parse URI parameters '" + uri + "'. URISyntaxException: " + e.getMessage());
        }
        if (object instanceof AbstractService) {
            final AbstractService service = (AbstractService) object;
            service.setId(id);
            service.setType(map.remove("type"));
            service.setProvider(map.remove("provider"));
            service.setClassName(map.remove("class-name"));
            service.setConstructor(map.remove("constructor"));
            service.setFactoryName(map.remove("factory-name"));
            service.setPropertiesProvider(map.remove("properties-provider"));
            service.setTemplate(map.remove("template"));
            final String cp = map.remove("classpath");
            if (null != cp) {
                service.setClasspath(cp);
            }
            service.setClasspathAPI(map.remove("classpath-api"));
            if (object instanceof Resource) {
                final Resource resource = Resource.class.cast(object);
                final String aliases = map.remove("aliases");
                if (aliases != null) {
                    resource.getAliases().addAll(Arrays.asList(aliases.split(",")));
                }
                final String depOn = map.remove("depends-on");
                if (depOn != null) {
                    resource.getDependsOn().addAll(Arrays.asList(depOn.split(",")));
                }
                resource.setPostConstruct(map.remove("post-construct"));
                resource.setPreDestroy(map.remove("pre-destroy"));
            }
            service.getProperties().putAll(map);
        } else if (object instanceof Deployments) {
            final Deployments deployments = (Deployments) object;
            deployments.setDir(map.remove("dir"));
            deployments.setFile(map.remove("jar"));
            final String cp = map.remove("classpath");
            if (cp != null) {
                final String[] paths = cp.split(File.pathSeparator);
                final List<URL> urls = new ArrayList<>();
                for (final String path : paths) {
                    final Set<String> values = ProvisioningUtil.realLocation(PropertyPlaceHolderHelper.value(path));
                    for (final String v : values) {
                        urls.add(new File(v).toURI().normalize().toURL());
                    }
                }
                deployments.setClasspath(new URLClassLoaderFirst(urls.toArray(new URL[urls.size()]), ParentClassLoaderFinder.Helper.get()));
            }
        } else if (SystemProperty.class.isInstance(object)) {
            final SystemProperty sp = SystemProperty.class.cast(object);
            sp.setName(map.remove("name"));
            sp.setValue(map.remove("value"));
        }
        return object;
    } catch (final Exception e) {
        throw new OpenEJBException("Error declaring service '" + id + "'. Unable to create Service definition from URI '" + uri.toString() + "'", e);
    }
}
Also used : OpenEJBException(org.apache.openejb.OpenEJBException) URLClassLoaderFirst(org.apache.openejb.util.classloader.URLClassLoaderFirst) Set(java.util.Set) HashSet(java.util.HashSet) Resource(org.apache.openejb.config.sys.Resource) AdditionalDeployments(org.apache.openejb.config.sys.AdditionalDeployments) Deployments(org.apache.openejb.config.sys.Deployments) URISyntaxException(java.net.URISyntaxException) AbstractService(org.apache.openejb.config.sys.AbstractService) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) OpenEJBException(org.apache.openejb.OpenEJBException) MalformedURLException(java.net.MalformedURLException) URL(java.net.URL) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) File(java.io.File)

Example 4 with URLClassLoaderFirst

use of org.apache.openejb.util.classloader.URLClassLoaderFirst in project tomee by apache.

the class DeployTimeEnhancer method enhance.

public void enhance(@Observes final BeforeDeploymentEvent event) {
    if (enhancerMethod == null) {
        LOGGER.debug("OpenJPA is not available so no deploy-time enhancement will be done");
        return;
    }
    // find persistence.xml
    final Map<String, List<String>> classesByPXml = new HashMap<>();
    // for fake classloader
    final List<URL> usedUrls = new ArrayList<>();
    for (final URL url : event.getUrls()) {
        final File file = URLs.toFile(url);
        if (file.isDirectory()) {
            final String pXmls = getWarPersistenceXml(url);
            if (pXmls != null) {
                feed(classesByPXml, pXmls);
            }
            usedUrls.add(url);
        } else if (file.getName().endsWith(".jar")) {
            try (JarFile jar = new JarFile(file)) {
                final ZipEntry entry = jar.getEntry(META_INF_PERSISTENCE_XML);
                if (entry != null) {
                    final String path = file.getAbsolutePath();
                    final File unpacked = new File(path.substring(0, path.length() - 4) + TMP_ENHANCEMENT_SUFFIX);
                    JarExtractor.extract(file, unpacked);
                    // replace jar by folder url since otherwise enhancement doesn't work
                    usedUrls.add(unpacked.toURI().toURL());
                    feed(classesByPXml, new File(unpacked, META_INF_PERSISTENCE_XML).getAbsolutePath());
                } else {
                    usedUrls.add(url);
                }
            } catch (final IOException e) {
            // ignored
            }
        // no-op
        } else {
            usedUrls.add(url);
        }
    }
    // enhancement
    final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
    final ClassLoader fakeClassLoader = new URLClassLoaderFirst(usedUrls.toArray(new URL[usedUrls.size()]), event.getParentClassLoader());
    LOGGER.info("Enhancing url(s): " + usedUrls);
    Thread.currentThread().setContextClassLoader(fakeClassLoader);
    try {
        for (final Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
            final Properties opts = new Properties();
            opts.setProperty(PROPERTIES_FILE_PROP, entry.getKey());
            final Object optsArg;
            try {
                optsArg = optionsConstructor.newInstance(opts);
            } catch (final Exception e) {
                LOGGER.debug("can't create options for enhancing");
                return;
            }
            final String[] args = toFilePaths(entry.getValue());
            LOGGER.info("Enhancing: " + Arrays.asList(args));
            try {
                enhancerMethod.invoke(null, args, optsArg);
            } catch (final Exception e) {
                LOGGER.warning("can't enhanced at deploy-time entities", e);
            }
        }
    } finally {
        Thread.currentThread().setContextClassLoader(tccl);
        usedUrls.clear();
    }
    // clean up extracted jars and replace jar to keep consistent classloading
    for (final Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) {
        final List<String> values = entry.getValue();
        for (final String rawPath : values) {
            if (rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX + "/") || rawPath.endsWith(TMP_ENHANCEMENT_SUFFIX)) {
                final File dir = new File(rawPath);
                final File file = new File(rawPath.substring(0, rawPath.length() - TMP_ENHANCEMENT_SUFFIX.length() - 1) + ".jar");
                if (file.exists()) {
                    String name = dir.getName();
                    name = name.substring(0, name.length() - TMP_ENHANCEMENT_SUFFIX.length()) + ".jar";
                    final File target = new File(dir.getParentFile(), name);
                    try {
                        // override existing jar otherwise classloading is broken in tomee
                        Files.delete(file);
                        JarCreator.jarDir(dir, target);
                    } catch (final IOException e) {
                        LOGGER.error("can't repackage enhanced jar file " + file.getName());
                    }
                    Files.delete(dir);
                }
            }
        }
        values.clear();
    }
    classesByPXml.clear();
}
Also used : URLClassLoaderFirst(org.apache.openejb.util.classloader.URLClassLoaderFirst) HashMap(java.util.HashMap) ZipEntry(java.util.zip.ZipEntry) ArrayList(java.util.ArrayList) IOException(java.io.IOException) JarFile(java.util.jar.JarFile) Properties(java.util.Properties) URL(java.net.URL) IOException(java.io.IOException) SAXException(org.xml.sax.SAXException) ArrayList(java.util.ArrayList) List(java.util.List) JarFile(java.util.jar.JarFile) File(java.io.File) HashMap(java.util.HashMap) Map(java.util.Map)

Example 5 with URLClassLoaderFirst

use of org.apache.openejb.util.classloader.URLClassLoaderFirst in project tomee by apache.

the class TomEEWebappClassLoader method loadClass.

@Override
public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
    if ("org.apache.openejb.hibernate.OpenEJBJtaPlatform".equals(name) || "org.apache.openejb.jpa.integration.hibernate.PrefixNamingStrategy".equals(name) || "org.apache.openejb.jpa.integration.eclipselink.PrefixSessionCustomizer".equals(name) || "org.apache.openejb.jpa.integration.eclipselink.OpenEJBServerPlatform".equals(name) || "org.apache.openejb.jpa.integration.eclipselink.OpenEJBServerPlatform$OpenEJBJTATransactionController".equals(name) || "org.apache.openejb.eclipselink.JTATransactionController".equals(name) || "org.apache.tomee.mojarra.TomEEInjectionProvider".equals(name)) {
        // don't load them from system classloader (breaks all in embedded mode and no sense in other cases)
        synchronized (this) {
            final ClassLoader old = getJavaseClassLoader();
            setJavaseClassLoader(NoClassClassLoader.INSTANCE);
            delegate = false;
            try {
                return super.loadClass(name, resolve);
            } finally {
                setJavaseClassLoader(old);
                setDelegate(originalDelegate);
            }
        }
    }
    // avoid to redefine classes from server in this classloader is it not already loaded
    if (URLClassLoaderFirst.shouldDelegateToTheContainer(this, name) || shouldForceLoadFromTheContainer(name)) {
        // dynamic validation handling overriding
        try {
            // we could use containerClassLoader but this is server loader so cut it even more
            return OpenEJB.class.getClassLoader().loadClass(name);
        } catch (final ClassNotFoundException e) {
            synchronized (this) {
                return super.loadClass(name, resolve);
            }
        } catch (final NoClassDefFoundError ncdfe) {
            synchronized (this) {
                return super.loadClass(name, resolve);
            }
        }
    } else if (name.startsWith("javax.faces.") || name.startsWith("org.apache.webbeans.jsf")) {
        synchronized (this) {
            delegate = false;
            try {
                return super.loadClass(name, resolve);
            } finally {
                setDelegate(originalDelegate);
            }
        }
    }
    synchronized (this) {
        // TODO: rework it to avoid it and get aligned on Java 7 classloaders (but not a big issue)
        if (isEar) {
            final boolean filter = filter(name, true);
            // will be called again by super.loadClass() so cache it
            filterTempCache.put(name, filter);
            if (!filter) {
                if (URLClassLoaderFirst.class.isInstance(getInternalParent())) {
                    // true
                    final URLClassLoaderFirst urlClassLoaderFirst = URLClassLoaderFirst.class.cast(getInternalParent());
                    Class<?> c = urlClassLoaderFirst.findAlreadyLoadedClass(name);
                    if (c != null) {
                        return c;
                    }
                    c = urlClassLoaderFirst.loadInternal(name, resolve);
                    if (c != null) {
                        return c;
                    }
                }
                return loadWithDelegate(getResource(name.replace('.', '/') + CLASS_EXTENSION) == null, resolve, name);
            }
        }
        return super.loadClass(name, resolve);
    }
}
Also used : URLClassLoaderFirst(org.apache.openejb.util.classloader.URLClassLoaderFirst) ParallelWebappClassLoader(org.apache.catalina.loader.ParallelWebappClassLoader) OpenEJB(org.apache.openejb.OpenEJB)

Aggregations

URLClassLoaderFirst (org.apache.openejb.util.classloader.URLClassLoaderFirst)5 IOException (java.io.IOException)4 URL (java.net.URL)4 ArrayList (java.util.ArrayList)4 MalformedURLException (java.net.MalformedURLException)3 HashMap (java.util.HashMap)3 List (java.util.List)3 Map (java.util.Map)3 OpenEJBException (org.apache.openejb.OpenEJBException)3 File (java.io.File)2 URISyntaxException (java.net.URISyntaxException)2 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 Properties (java.util.Properties)2 Set (java.util.Set)2 OpenEJBRuntimeException (org.apache.openejb.OpenEJBRuntimeException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 InputStream (java.io.InputStream)1 InvalidObjectException (java.io.InvalidObjectException)1 ObjectStreamException (java.io.ObjectStreamException)1