/** {@inheritDoc} */ @Override public void requestInitialized(final ServletRequestEvent event) { final Object oldContext = ThreadSingletonServiceImpl.enter(this.webBeansContext); if (event != null) { event.getServletRequest().setAttribute(contextKey, oldContext); } try { if (logger.isDebugEnabled()) { logger.debug( "Starting a new request : [{0}]", event == null ? "null" : event.getServletRequest().getRemoteAddr()); } if (webBeansContext instanceof WebappWebBeansContext) { // start before child ((WebappWebBeansContext) webBeansContext) .getParent() .getContextsService() .startContext(RequestScoped.class, event); } this.webBeansContext.getContextsService().startContext(RequestScoped.class, event); // we don't initialise the Session here but do it lazily if it gets requested // the first time. See OWB-457 } catch (final Exception e) { logger.error(OWBLogConst.ERROR_0019, event == null ? "null" : event.getServletRequest()); WebBeansUtil.throwRuntimeExceptions(e); } }
public static void initializeServletContext( final ServletContext servletContext, final WebBeansContext context) { if (context == null || !context.getBeanManagerImpl().isInUse()) { return; } final ELAdaptor elAdaptor = context.getService(ELAdaptor.class); final ELResolver resolver = elAdaptor.getOwbELResolver(); // Application is configured as JSP if (context.getOpenWebBeansConfiguration().isJspApplication()) { logger.debug("Application is configured as JSP. Adding EL Resolver."); setJspELFactory(servletContext, resolver); } // Add BeanManager to the 'javax.enterprise.inject.spi.BeanManager' servlet context attribute servletContext.setAttribute(BeanManager.class.getName(), context.getBeanManagerImpl()); }
/** {@inheritDoc} */ @Override public void sessionCreated(final HttpSessionEvent event) { try { if (logger.isDebugEnabled()) { logger.debug("Starting a session with session id : [{0}]", event.getSession().getId()); } if (webBeansContext instanceof WebappWebBeansContext) { // start before child ((WebappWebBeansContext) webBeansContext) .getParent() .getContextsService() .startContext(SessionScoped.class, event.getSession()); } this.webBeansContext .getContextsService() .startContext(SessionScoped.class, event.getSession()); } catch (final Exception e) { logger.error(OWBLogConst.ERROR_0020, event.getSession()); WebBeansUtil.throwRuntimeExceptions(e); } }
/** On Tomcat we need to sometimes force a class load to get our hands on the JspFactory */ private static void setJspELFactory(ServletContext startupObject, ELResolver resolver) { JspFactory factory = JspFactory.getDefaultFactory(); if (factory == null) { try { try { Class.forName("org.apache.jasper.servlet.JasperInitializer"); } catch (final Throwable th) { Class.forName("org.apache.jasper.compiler.JspRuntimeContext"); } factory = JspFactory.getDefaultFactory(); } catch (Exception e) { // ignore } } if (factory != null) { JspApplicationContext applicationCtx = factory.getJspApplicationContext(startupObject); applicationCtx.addELResolver(resolver); } else { logger.debug("Default JSPFactroy instance has not found. Skipping OWB JSP handling"); } }
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<String, List<String>>(); final List<URL> usedUrls = new ArrayList<URL>(); // for fake classloader for (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 { final JarFile jar = new JarFile(file); 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()); } } catch (IOException e) { // ignored } } else { usedUrls.add(url); } } // enhancement final ClassLoader tccl = Thread.currentThread().getContextClassLoader(); final ClassLoader fakeClassLoader = new URLClassLoaderFirst( usedUrls.toArray(new URL[usedUrls.size()]), event.getParentClassLoader()); Thread.currentThread().setContextClassLoader(fakeClassLoader); try { for (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 (Exception e) { LOGGER.debug("can't create options for enhancing"); return; } LOGGER.info("enhancing url(s): " + Arrays.asList(event.getUrls())); try { enhancerMethod.invoke(null, toFilePaths(entry.getValue()), optsArg); } catch (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 (Map.Entry<String, List<String>> entry : classesByPXml.entrySet()) { final List<String> values = entry.getValue(); for (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(); }
@SuppressWarnings("unchecked") private static Configuration<?> getConfig(final ValidationInfo info) { Configuration<?> target = null; final Thread thread = Thread.currentThread(); final ClassLoader classLoader = thread.getContextClassLoader(); String providerClassName = info.providerClassName; if (providerClassName == null) { providerClassName = SystemInstance.get().getOptions().get(VALIDATION_PROVIDER_KEY, (String) null); } if (providerClassName != null) { try { @SuppressWarnings({"unchecked", "rawtypes"}) final Class clazz = classLoader.loadClass(providerClassName); target = Validation.byProvider(clazz).configure(); logger.info("Using " + providerClassName + " as validation provider."); } catch (final ClassNotFoundException e) { logger.warning("Unable to load provider class " + providerClassName, e); } catch (final ValidationException ve) { logger.warning( "Unable create validator factory with provider " + providerClassName + " (" + ve.getMessage() + ")." + " Default one will be used."); } } if (target == null) { // force to use container provider to ignore any conflicting configuration thread.setContextClassLoader(ValidatorBuilder.class.getClassLoader()); target = Validation.byDefaultProvider().configure(); thread.setContextClassLoader(classLoader); } final Set<ExecutableType> types = new HashSet<>(); for (final String type : info.validatedTypes) { types.add(ExecutableType.valueOf(type)); } final Map<String, String> props = new HashMap<>(); for (final Map.Entry<Object, Object> entry : info.propertyTypes.entrySet()) { final PropertyType property = new PropertyType(); property.setName((String) entry.getKey()); property.setValue((String) entry.getValue()); props.put(property.getName(), property.getValue()); if (logger.isDebugEnabled()) { logger.debug( "Found property '" + property.getName() + "' with value '" + property.getValue()); } target.addProperty(property.getName(), property.getValue()); } final OpenEjbBootstrapConfig bootstrapConfig = new OpenEjbBootstrapConfig( providerClassName, info.constraintFactoryClass, info.messageInterpolatorClass, info.traversableResolverClass, info.parameterNameProviderClass, new HashSet<>(info.constraintMappings), info.executableValidationEnabled, types, props); final OpenEjbConfig config = new OpenEjbConfig(bootstrapConfig, target); target.ignoreXmlConfiguration(); final String messageInterpolatorClass = info.messageInterpolatorClass; if (messageInterpolatorClass != null) { try { @SuppressWarnings("unchecked") final Class<MessageInterpolator> clazz = (Class<MessageInterpolator>) classLoader.loadClass(messageInterpolatorClass); target.messageInterpolator(newInstance(config, clazz)); } catch (final Exception e) { logger.warning( "Unable to set " + messageInterpolatorClass + " as message interpolator.", e); } logger.info("Using " + messageInterpolatorClass + " as message interpolator."); } final String traversableResolverClass = info.traversableResolverClass; if (traversableResolverClass != null) { try { @SuppressWarnings("unchecked") final Class<TraversableResolver> clazz = (Class<TraversableResolver>) classLoader.loadClass(traversableResolverClass); target.traversableResolver(newInstance(config, clazz)); } catch (final Exception e) { logger.warning( "Unable to set " + traversableResolverClass + " as traversable resolver.", e); } logger.info("Using " + traversableResolverClass + " as traversable resolver."); } final String constraintFactoryClass = info.constraintFactoryClass; if (constraintFactoryClass != null) { try { @SuppressWarnings("unchecked") final Class<ConstraintValidatorFactory> clazz = (Class<ConstraintValidatorFactory>) classLoader.loadClass(constraintFactoryClass); target.constraintValidatorFactory(newInstance(config, clazz)); } catch (final Exception e) { logger.warning("Unable to set " + constraintFactoryClass + " as constraint factory.", e); } logger.info("Using " + constraintFactoryClass + " as constraint factory."); } for (final String mappingFileName : info.constraintMappings) { if (logger.isDebugEnabled()) { logger.debug("Opening input stream for " + mappingFileName); } final InputStream in = classLoader.getResourceAsStream(mappingFileName); if (in == null) { logger.warning( "Unable to open input stream for mapping file " + mappingFileName + ". It will be ignored"); } else { target.addMapping(in); } } if (info.parameterNameProviderClass != null) { try { final Class<ParameterNameProvider> clazz = (Class<ParameterNameProvider>) classLoader.loadClass(info.parameterNameProviderClass); target.parameterNameProvider(newInstance(config, clazz)); } catch (final Exception e) { logger.warning( "Unable to set " + info.parameterNameProviderClass + " as parameter name provider.", e); } logger.info("Using " + info.parameterNameProviderClass + " as parameter name provider."); } return config; }
@Override public void stopApplication(final Object endObject) { logger.debug("OpenWebBeans Container is stopping."); try { // Fire shut down if (WebappBeanManager.class.isInstance(beanManager)) { WebappBeanManager.class.cast(beanManager).beforeStop(); } webBeansContext.getContextsService().endContext(RequestScoped.class, endObject); webBeansContext.getContextsService().endContext(ConversationScoped.class, endObject); webBeansContext.getContextsService().endContext(SessionScoped.class, endObject); webBeansContext.getContextsService().endContext(ApplicationScoped.class, endObject); webBeansContext.getContextsService().endContext(Singleton.class, endObject); // clean up the EL caches after each request ELContextStore elStore = ELContextStore.getInstance(false); if (elStore != null) { elStore.destroyELContextStore(); } this.beanManager.fireEvent(new BeforeShutdownImpl(), true); // this will now even destroy the ExtensionBeans and other internal stuff this.contextsService.destroy(endObject); // Unbind BeanManager if (jndiService != null) { jndiService.unbind(WebBeansConstants.WEB_BEANS_MANAGER_JNDI_NAME); } // Free all plugin resources ((CdiPlugin) webBeansContext.getPluginLoader().getEjbPlugin()).clearProxies(); webBeansContext.getPluginLoader().shutDown(); // Clear extensions webBeansContext.getExtensionLoader().clear(); // Delete Resolutions Cache beanManager.getInjectionResolver().clearCaches(); // Delete AnnotateTypeCache webBeansContext.getAnnotatedElementFactory().clear(); // After Stop // Clear the resource injection service final ResourceInjectionService injectionServices = webBeansContext.getService(ResourceInjectionService.class); if (injectionServices != null) { injectionServices.clear(); } // Comment out for commit OWB-502 // ContextFactory.cleanUpContextFactory(); CdiAppContextsService.class.cast(contextsService).removeThreadLocals(); WebBeansFinder.clearInstances(WebBeansUtil.getCurrentClassLoader()); // Clear BeanManager this.beanManager.clear(); // Clear singleton list WebBeansFinder.clearInstances(WebBeansUtil.getCurrentClassLoader()); } catch (final Exception e) { logger.error("An error occured while stopping the container.", e); } }
@Override public void startApplication(final Object startupObject) { if (ServletContextEvent.class.isInstance(startupObject)) { startServletContext( ServletContext.class.cast( getServletContext(startupObject))); // TODO: check it is relevant return; } else if (!StartupObject.class.isInstance(startupObject)) { logger.debug("startupObject is not of StartupObject type; ignored"); return; } final StartupObject stuff = (StartupObject) startupObject; final ClassLoader oldCl = Thread.currentThread().getContextClassLoader(); // Initalize Application Context logger.info("OpenWebBeans Container is starting..."); final long begin = System.currentTimeMillis(); try { Thread.currentThread().setContextClassLoader(stuff.getClassLoader()); final AppContext appContext = stuff.getAppContext(); if (stuff.getWebContext() == null) { // do it before any other things to keep our singleton finder working appContext.setWebBeansContext(webBeansContext); } // Load all plugins webBeansContext.getPluginLoader().startUp(); // Get Plugin final CdiPlugin cdiPlugin = (CdiPlugin) webBeansContext.getPluginLoader().getEjbPlugin(); cdiPlugin.setClassLoader(stuff.getClassLoader()); cdiPlugin.setWebBeansContext(webBeansContext); // Configure EJB Deployments cdiPlugin.configureDeployments(stuff.getBeanContexts()); // Resournce Injection Service final CdiResourceInjectionService injectionService = (CdiResourceInjectionService) webBeansContext.getService(ResourceInjectionService.class); // todo use startupObject allDeployments to find Comp in priority (otherwise we can keep N // times comps and loose time at injection time injectionService.setAppContext( stuff.getAppContext(), stuff.getBeanContexts() != null ? stuff.getBeanContexts() : Collections.<BeanContext>emptyList()); // Deploy the beans CdiScanner cdiScanner = null; try { // Scanning process logger.debug("Scanning classpaths for beans artifacts."); if (CdiScanner.class.isInstance(scannerService)) { cdiScanner = CdiScanner.class.cast(scannerService); cdiScanner.setContext(webBeansContext); cdiScanner.init(startupObject); } else { cdiScanner = new CdiScanner(); cdiScanner.setContext(webBeansContext); cdiScanner.init(startupObject); } // Scan this.scannerService.scan(); // just to let us write custom CDI Extension using our internals easily CURRENT_APP_INFO.set(stuff.getAppInfo()); addInternalBeans(); // before next event which can register custom beans (JAX-RS) SystemInstance.get().fireEvent(new WebBeansContextBeforeDeploy(webBeansContext)); // Deploy bean from XML. Also configures deployments, interceptors, decorators. deployer.deploy(scannerService); contextsService.init( startupObject); // fire app event and also starts SingletonContext and // ApplicationContext } catch (final Exception e1) { SystemInstance.get() .getComponent(Assembler.class) .logger .error("CDI Beans module deployment failed", e1); throw new OpenEJBRuntimeException(e1); } finally { CURRENT_APP_INFO.remove(); } final Collection<Class<?>> ejbs = new ArrayList<>(stuff.getBeanContexts().size()); for (final BeanContext bc : stuff.getBeanContexts()) { final CdiEjbBean cdiEjbBean = bc.get(CdiEjbBean.class); if (cdiEjbBean == null) { continue; } ejbs.add(bc.getManagedClass()); if (AbstractProducer.class.isInstance(cdiEjbBean)) { AbstractProducer.class .cast(cdiEjbBean) .defineInterceptorStack( cdiEjbBean, cdiEjbBean.getAnnotatedType(), cdiEjbBean.getWebBeansContext()); } bc.mergeOWBAndOpenEJBInfo(); bc.set( InterceptorResolutionService.BeanInterceptorInfo.class, InjectionTargetImpl.class.cast(cdiEjbBean.getInjectionTarget()).getInterceptorInfo()); cdiEjbBean.initInternals(); } // Start actual starting on sub-classes if (beanManager instanceof WebappBeanManager) { ((WebappBeanManager) beanManager).afterStart(); } for (final Class<?> clazz : cdiScanner.getStartupClasses()) { if (ejbs.contains(clazz)) { continue; } starts(beanManager, clazz); } } finally { Thread.currentThread().setContextClassLoader(oldCl); // cleanup threadlocal used to enrich cdi context manually OptimizedLoaderService.ADDITIONAL_EXTENSIONS.remove(); } logger.info( "OpenWebBeans Container has started, it took {0} ms.", Long.toString(System.currentTimeMillis() - begin)); }