/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomee.catalina; import org.apache.openejb.config.TldScanner; import java.util.concurrent.Semaphore; /** * The classes listed and loaded eagerly have static initializers which take a tiny bit of time. * These initializers cannot be actually run in parallel because classes are loaded serially, * but executing them back to back does help speed things up a bit. * * @version $Rev$ $Date$ */ public class Warmup { /** * Referencing this method is enough to cause the static initializer * to be called. Referencing this method in several classes is therefore safe. * * This method itself does nothing. */ public static void warmup() {} static { if (!Boolean.getBoolean("tomee.warmup.skip")) { final String[] classes = { "org.apache.tomee.jasper.TomEETldScanner", "javax.el.ExpressionFactory", "javax.faces.component.UIViewRoot", // "javax.imageio.ImageIO", // bug in jvm < 1.7.0_60 -> deadlocks "javax.naming.spi.NamingManager", "javax.servlet.ServletOutputStream", "org.apache.bval.jsr.ApacheValidatorFactory", "org.apache.bval.jsr.ConstraintAnnotationAttributes", "org.apache.bval.jsr.ConstraintDefaults", "org.apache.bval.jsr.groups.GroupsComputer", "org.apache.bval.jsr.xml.ValidationMappingParser", "org.apache.bval.util.PrivilegedActions", "org.apache.catalina.authenticator.AuthenticatorBase", "org.apache.catalina.connector.Connector", "org.apache.catalina.connector.CoyoteAdapter", "org.apache.catalina.connector.Request", "org.apache.catalina.connector.Response", "org.apache.catalina.core.ApplicationFilterChain", "org.apache.catalina.core.StandardContext", "org.apache.catalina.core.StandardServer", "org.apache.catalina.deploy.NamingResources", "org.apache.catalina.loader.WebappLoader", "org.apache.catalina.mbeans.GlobalResourcesLifecycleListener", "org.apache.catalina.mbeans.MBeanUtils", "org.apache.catalina.realm.RealmBase", "org.apache.catalina.security.SecurityUtil", "org.apache.catalina.servlets.DefaultServlet", "org.apache.catalina.session.ManagerBase", "org.apache.catalina.startup.Bootstrap", "org.apache.catalina.startup.Catalina", "org.apache.catalina.startup.CatalinaProperties", "org.apache.catalina.startup.ContextConfig", "org.apache.catalina.users.MemoryUserDatabase", "org.apache.catalina.util.ExtensionValidator", "org.apache.catalina.util.LifecycleBase", "org.apache.catalina.util.ServerInfo", "org.apache.catalina.valves.AccessLogValve", "org.apache.catalina.valves.ValveBase", "org.apache.coyote.AbstractProtocol", "org.apache.coyote.ajp.AbstractAjpProtocol", "org.apache.coyote.http11.AbstractHttp11Protocol", "org.apache.geronimo.transaction.manager.TransactionManagerImpl", "org.apache.jasper.compiler.JspRuntimeContext", "org.apache.myfaces.context.servlet.ServletExternalContextImplBase", "org.apache.myfaces.shared.config.MyfacesConfig", "org.apache.myfaces.spi.WebConfigProviderFactory", "org.apache.naming.ContextBindings", "org.apache.naming.resources.BaseDirContext", "org.apache.openejb.ClassLoaderUtil", "org.apache.openejb.InterfaceType", "org.apache.openejb.assembler.classic.Assembler", "org.apache.openejb.assembler.classic.AssemblerTool", "org.apache.openejb.cdi.CdiBuilder", "org.apache.openejb.cdi.ThreadSingletonServiceImpl", "org.apache.openejb.config.AnnotationDeployer", "org.apache.openejb.config.AnnotationDeployer$4", "org.apache.openejb.config.AppValidator", "org.apache.openejb.config.AutoConfig", "org.apache.openejb.config.ConfigurationFactory", "org.apache.openejb.config.MBeanDeployer", "org.apache.openejb.config.NewLoaderLogic", "org.apache.openejb.config.PersistenceContextAnnFactory", "org.apache.openejb.config.sys.JaxbJavaee", "org.apache.openejb.core.ServerFederation", "org.apache.openejb.core.ivm.EjbHomeProxyHandler$1", "org.apache.openejb.core.ivm.EjbHomeProxyHandler$MethodType", "org.apache.openejb.core.managed.ManagedContainer$MethodType", "org.apache.openejb.loader.FileUtils", "org.apache.openejb.loader.IO", "org.apache.openejb.loader.SystemInstance", "org.apache.openejb.monitoring.StatsInterceptor", "org.apache.openejb.persistence.JtaEntityManagerRegistry", "org.apache.openejb.server.ServiceLogger", "org.apache.openejb.server.ejbd.EjbDaemon", "org.apache.openejb.server.ejbd.EjbRequestHandler", "org.apache.openejb.util.Duration", "org.apache.openejb.util.Join", "org.apache.openejb.util.LogCategory", "org.apache.openejb.util.Messages", "org.apache.openejb.util.SafeToolkit", "org.apache.openejb.util.StringTemplate", "org.apache.openejb.util.proxy.ProxyManager", "org.apache.openjpa.enhance.PCRegistry", "org.apache.openjpa.lib.util.Localizer", "org.apache.openjpa.lib.util.concurrent.ConcurrentReferenceHashMap", "org.apache.tomcat.util.buf.B2CConverter", "org.apache.tomcat.util.buf.ByteChunk", "org.apache.tomcat.util.digester.Digester", "org.apache.tomcat.util.file.Matcher", "org.apache.tomcat.util.http.Cookies", "org.apache.tomcat.util.http.HttpMessages", "org.apache.tomcat.util.http.mapper.Mapper", "org.apache.tomcat.util.net.AbstractEndpoint", "org.apache.tomcat.util.scan.StandardJarScanner", "org.apache.tomcat.util.threads.ThreadPoolExecutor", // "org.apache.tomee.catalina.TomcatLoader", // can't be loaded from here "org.apache.webbeans.config.WebBeansFinder", "org.apache.webbeans.container.InjectionResolver", "org.apache.webbeans.util.WebBeansUtil", "org.apache.webbeans.web.context.WebContextsService", "org.apache.xbean.naming.reference.SimpleReference", "org.apache.xbean.propertyeditor.PropertyEditors", "org.apache.xbean.propertyeditor.ReferenceIdentityMap", "org.apache.xbean.recipe.ReflectionUtil", "org.slf4j.LoggerFactory", "org.slf4j.impl.StaticLoggerBinder", }; final ClassLoader loader = Warmup.class.getClassLoader(); // final JaxbJavaeeLoad jaxbJavaeeLoad = new JaxbJavaeeLoad(WebApp.class); // final Thread jaxb = new Thread(jaxbJavaeeLoad); // jaxb.setDaemon(true); // jaxb.start(); try { // see org.apache.openejb.Core Class.forName("org.apache.openejb.util.Logger", true, loader); } catch (final Throwable e) { // no-op } final int permits = 2 * Runtime.getRuntime().availableProcessors() + 1; final Semaphore semaphore = new Semaphore(0); final Thread tld = new Thread() { @Override public void run() { try { TldScanner.scan(loader); } catch (final Throwable throwable) { // no-op } } }; tld.setDaemon(true); tld.start(); final int part = Math.max(1, (int) Math.round(classes.length * 1. / permits)); for (int i = 0; i < permits; i++) { final int offset = i * part; final Thread thread = new Thread() { @Override public void run() { int max = offset + part; if (offset / part == permits - 1) { // last one max = classes.length; } for (int c = offset; c < max; c++) { try { Class.forName(classes[c], true, loader); } catch (final Throwable e) { // no-op } } semaphore.release(); } }; thread.setName("warmup - " + (i + 1)); thread.setDaemon(true); thread.start(); } try { semaphore.acquire(permits); tld.join(); // jaxb.join(); } catch (final InterruptedException e) { Thread.interrupted(); } } } // private static class JaxbJavaeeLoad implements Runnable { // // private final Class<?> type; // // private JaxbJavaeeLoad(Class<?> type) { // this.type = type; // } // // @Override // public void run() { // try { // JaxbJavaee.getContext(type); // } catch (JAXBException e) { // } // } // } }