Repository: tomee Updated Branches: refs/heads/master 3cc7dcd4a -> 1f9a2bfa0
saving few hundredof ms deploying our internal app since we can precompute most of the needed model Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/1f9a2bfa Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/1f9a2bfa Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/1f9a2bfa Branch: refs/heads/master Commit: 1f9a2bfa025bebc471ab200f394e53b2725b00ff Parents: 3cc7dcd Author: Romain Manni-Bucau <rmannibu...@apache.org> Authored: Tue Jun 16 13:57:16 2015 +0200 Committer: Romain Manni-Bucau <rmannibu...@apache.org> Committed: Tue Jun 16 13:57:16 2015 +0200 ---------------------------------------------------------------------- .../apache/openejb/assembler/DeployerEjb.java | 15 +- .../openejb/assembler/classic/Assembler.java | 10 +- .../classic/cmd/ConfigurationInfoEjb.java | 10 +- .../openejb/config/ConfigurationFactory.java | 12 +- .../java/org/apache/openejb/config/Module.java | 1 + .../apache/openejb/config/SystemAppInfo.java | 146 +++++++++++++++++++ .../org/apache/openejb/config/SystemApps.java | 37 +++-- .../java/org/apache/openejb/mgmt/MEJBBean.java | 12 +- 8 files changed, 214 insertions(+), 29 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java index bc4d354..cc17061 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/DeployerEjb.java @@ -40,11 +40,6 @@ import org.apache.openejb.loader.provisining.ProvisioningResolver; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; -import javax.ejb.Remote; -import javax.ejb.Stateless; -import javax.ejb.TransactionManagement; -import javax.enterprise.inject.Alternative; -import javax.validation.ValidationException; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -56,13 +51,21 @@ import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.TreeMap; +import javax.ejb.Lock; +import javax.ejb.Remote; +import javax.ejb.Singleton; +import javax.ejb.TransactionManagement; +import javax.enterprise.inject.Alternative; +import javax.validation.ValidationException; +import static javax.ejb.LockType.READ; import static javax.ejb.TransactionManagementType.BEAN; import static org.apache.openejb.config.ConfigurationFactory.ADDITIONAL_DEPLOYMENTS; import static org.apache.openejb.loader.ProvisioningUtil.realLocation; @SuppressWarnings("EjbProhibitedPackageUsageInspection") -@Stateless(name = "openejb/Deployer") +@Singleton(name = "openejb/Deployer") +@Lock(READ) @Remote(Deployer.class) @TransactionManagement(BEAN) @Alternative http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java index b5947fe..4fc22b8 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java @@ -780,6 +780,10 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A final Map<String, ValidatorFactory> validatorFactories = new HashMap<String, ValidatorFactory>(); for (final CommonInfoObject info : vfs) { + if (info.validationInfo == null) { + continue; + } + final ComparableValidationConfig conf = new ComparableValidationConfig( info.validationInfo.providerClassName, info.validationInfo.messageInterpolatorClass, info.validationInfo.traversableResolverClass, info.validationInfo.constraintFactoryClass, @@ -2333,7 +2337,11 @@ public class Assembler extends AssemblerTool implements org.apache.openejb.spi.A } public ClassLoader createAppClassLoader(final AppInfo appInfo) throws OpenEJBException, IOException { - final Set<URL> jars = new HashSet<URL>(); + 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)); http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/cmd/ConfigurationInfoEjb.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/cmd/ConfigurationInfoEjb.java b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/cmd/ConfigurationInfoEjb.java index 075dea1..7718d20 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/cmd/ConfigurationInfoEjb.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/cmd/ConfigurationInfoEjb.java @@ -20,14 +20,18 @@ package org.apache.openejb.assembler.classic.cmd; import org.apache.openejb.assembler.classic.OpenEjbConfiguration; import org.apache.openejb.loader.SystemInstance; -import javax.ejb.Remote; -import javax.ejb.Stateless; import java.io.File; +import javax.ejb.Lock; +import javax.ejb.Remote; +import javax.ejb.Singleton; + +import static javax.ejb.LockType.READ; /** * @version $Rev$ $Date$ */ -@Stateless(name = "openejb/ConfigurationInfo") +@Singleton(name = "openejb/ConfigurationInfo") +@Lock(READ) @Remote(ConfigurationInfo.class) public class ConfigurationInfoEjb implements ConfigurationInfo { http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java index 7f21b73..19837a6 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/ConfigurationFactory.java @@ -325,6 +325,10 @@ public class ConfigurationFactory implements OpenEjbConfigurationFactory { this.serviceTypeIsAdjustable = true; } + public boolean isOffline() { + return offline; + } + public static List<HandlerChainInfo> toHandlerChainInfo(final HandlerChains chains) { final List<HandlerChainInfo> handlerChains = new ArrayList<HandlerChainInfo>(); if (chains == null) { @@ -538,7 +542,13 @@ public class ConfigurationFactory implements OpenEjbConfigurationFactory { if (options.get("openejb.system.apps", false)) { try { - final AppInfo appInfo = configureApplication(new AppModule(SystemApps.getSystemModule())); + final boolean extended = SystemApps.isExtended(); + final AppInfo appInfo; + if (!extended) { // do it manually, we know what we need and can skip a bunch of processing + appInfo = SystemAppInfo.preComputedInfo(this); + } else { + appInfo = configureApplication(new AppModule(SystemApps.getSystemModule())); + } // they doesn't use CDI so no need to activate it // 1) will be faster // 2) will let embedded containers (tomee-embedded mainly) not be noised by it in our singleton service http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/config/Module.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/Module.java b/container/openejb-core/src/main/java/org/apache/openejb/config/Module.java index bdf1dad..3b1bd5b 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/Module.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/Module.java @@ -28,6 +28,7 @@ import java.util.Properties; import java.util.Set; public class Module { + // note: 0 is reserved for internal app, don't set it to 0! private static int currentId = 1; // unique id to be able to bind something for each module in the jndi tree private boolean isStandaloneModule = true; http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/config/SystemAppInfo.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/SystemAppInfo.java b/container/openejb-core/src/main/java/org/apache/openejb/config/SystemAppInfo.java new file mode 100644 index 0000000..a33eda0 --- /dev/null +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/SystemAppInfo.java @@ -0,0 +1,146 @@ +/* + * 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.openejb.config; + +import org.apache.openejb.OpenEJBException; +import org.apache.openejb.assembler.classic.AppInfo; +import org.apache.openejb.assembler.classic.CallbackInfo; +import org.apache.openejb.assembler.classic.ContainerInfo; +import org.apache.openejb.assembler.classic.EjbJarInfo; +import org.apache.openejb.assembler.classic.EnterpriseBeanInfo; +import org.apache.openejb.assembler.classic.InterceptorBindingInfo; +import org.apache.openejb.assembler.classic.InterceptorInfo; +import org.apache.openejb.assembler.classic.MethodConcurrencyInfo; +import org.apache.openejb.assembler.classic.MethodInfo; +import org.apache.openejb.assembler.classic.SingletonBeanInfo; +import org.apache.openejb.assembler.classic.SingletonSessionContainerInfo; + +import java.net.URI; + +public final class SystemAppInfo { + // + // + // DONT MODIFY IT WITHOUT UPDATING org.apache.openejb.config.SystemApps + // + // + public static AppInfo preComputedInfo(final ConfigurationFactory factory) { + final String singletonContainerId; + try { + singletonContainerId = findSingletonContainer(factory); + } catch (final OpenEJBException e) { + throw new IllegalStateException(e); + } + + final EjbJarInfo ejbJarInfo = new EjbJarInfo(); + ejbJarInfo.moduleId = "openejb"; + ejbJarInfo.moduleName = ejbJarInfo.moduleId; + ejbJarInfo.moduleUri = URI.create(ejbJarInfo.moduleId); + ejbJarInfo.properties.setProperty("openejb.deploymentId.format", "{ejbName}"); + ejbJarInfo.properties.setProperty("openejb.jndiname.format", "{deploymentId}{interfaceType.openejbLegacyName}"); + + final SingletonBeanInfo deployer = new SingletonBeanInfo(); + deployer.ejbDeploymentId = "openejb/Deployer"; + deployer.ejbName = deployer.ejbDeploymentId; + deployer.ejbClass = "org.apache.openejb.assembler.DeployerEjb"; + deployer.businessRemote.add("org.apache.openejb.assembler.Deployer"); + deployer.parents.add(deployer.ejbClass); + deployer.transactionType = "BEAN"; + deployer.concurrencyType = "CONTAINER"; + deployer.containerId = singletonContainerId; + ejbJarInfo.enterpriseBeans.add(deployer); + + final SingletonBeanInfo configuration = new SingletonBeanInfo(); + configuration.ejbDeploymentId = "openejb/ConfigurationInfo"; + configuration.ejbName = deployer.ejbDeploymentId; + configuration.ejbClass = "org.apache.openejb.assembler.classic.cmd.ConfigurationInfoEjb"; + configuration.businessRemote.add("org.apache.openejb.assembler.classic.cmd.ConfigurationInfo"); + configuration.parents.add(deployer.ejbClass); + configuration.transactionType = "CONTAINER"; + configuration.concurrencyType = "CONTAINER"; + configuration.containerId = singletonContainerId; + ejbJarInfo.enterpriseBeans.add(configuration); + + final SingletonBeanInfo mejb = new SingletonBeanInfo(); + mejb.ejbDeploymentId = "MEJB"; + mejb.ejbName = deployer.ejbDeploymentId; + mejb.ejbClass = "org.apache.openejb.mgmt.MEJBBean"; + mejb.home = "javax.management.j2ee.ManagementHome"; + mejb.remote = "javax.management.j2ee.Management"; + mejb.parents.add(deployer.ejbClass); + mejb.transactionType = "CONTAINER"; + mejb.concurrencyType = "CONTAINER"; + mejb.containerId = singletonContainerId; + ejbJarInfo.enterpriseBeans.add(mejb); + + for (final EnterpriseBeanInfo ebi : ejbJarInfo.enterpriseBeans) { + final MethodInfo methodInfo = new MethodInfo(); + methodInfo.ejbDeploymentId = ebi.ejbDeploymentId; + methodInfo.ejbName = ebi.ejbName; + methodInfo.methodName = "*"; + methodInfo.className = ebi.ejbClass; + + final MethodConcurrencyInfo methodConcurrencyInfo = new MethodConcurrencyInfo(); + methodConcurrencyInfo.concurrencyAttribute = "READ"; + methodConcurrencyInfo.methods.add(methodInfo); + ejbJarInfo.methodConcurrency.add(methodConcurrencyInfo); + } + + final CallbackInfo callbackInfo = new CallbackInfo(); + callbackInfo.className = "org.apache.openejb.security.internal.InternalSecurityInterceptor"; + callbackInfo.method = "invoke"; + + final InterceptorInfo interceptorInfo = new InterceptorInfo(); + interceptorInfo.clazz = "org.apache.openejb.security.internal.InternalSecurityInterceptor"; + interceptorInfo.aroundInvoke.add(callbackInfo); + ejbJarInfo.interceptors.add(interceptorInfo); + + final InterceptorBindingInfo interceptorBindingInfo = new InterceptorBindingInfo(); + interceptorBindingInfo.ejbName = "*"; + interceptorBindingInfo.interceptors.add("org.apache.openejb.security.internal.InternalSecurityInterceptor"); + ejbJarInfo.interceptorBindings.add(interceptorBindingInfo); + + ejbJarInfo.mbeans.add("org.apache.openejb.assembler.monitoring.JMXDeployer"); + ejbJarInfo.uniqueId = "0"; // we start at 1 so no conflict using 0 + + final AppInfo appInfo = new AppInfo(); + appInfo.appId = ejbJarInfo.moduleId; + appInfo.path = appInfo.appId; + appInfo.ejbJars.add(ejbJarInfo); + return appInfo; + } + + // simplified logic compared to AutoConfig + private static String findSingletonContainer(final ConfigurationFactory configFactory) throws OpenEJBException { + for (final ContainerInfo containerInfo : configFactory.getContainerInfos()) { + if (SingletonSessionContainerInfo.class.isInstance(configFactory)) { + return containerInfo.id; + } + } + if (configFactory.isOffline()) { + throw new IllegalStateException("system application (openejb) needs a singleton container. " + + "Noone is defined and container is in offline mode. " + + "Please define one in tomee.xml."); + } + final ContainerInfo containerInfo = configFactory.configureService(SingletonSessionContainerInfo.class); + configFactory.install(containerInfo); + return containerInfo.id; + } + + private SystemAppInfo() { + // no-op + } +} http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java b/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java index cdedc98..f4a3d59 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/config/SystemApps.java @@ -24,7 +24,6 @@ import org.apache.openejb.jee.EjbJar; import org.apache.openejb.jee.Interceptor; import org.apache.openejb.jee.InterceptorBinding; import org.apache.openejb.jee.SingletonBean; -import org.apache.openejb.jee.StatelessBean; import org.apache.openejb.jee.oejb3.EjbDeployment; import org.apache.openejb.jee.oejb3.OpenejbJar; import org.apache.openejb.mgmt.MEJBBean; @@ -34,6 +33,7 @@ import org.apache.openejb.security.internal.InternalSecurityInterceptor; * Avoids the needs to scan the classpath to load system applications that are used * for deploy tools and other command line tooling. */ +// see org.apache.openejb.config.SystemAppInfo public class SystemApps { public static EjbModule getSystemModule() { @@ -42,24 +42,25 @@ public class SystemApps { final OpenejbJar openejbJar = module.getOpenejbJar(); final EjbJar ejbJar = module.getEjbJar(); - ejbJar.addEnterpriseBean(new StatelessBean(null, DeployerEjb.class)); - ejbJar.addEnterpriseBean(new StatelessBean(null, ConfigurationInfoEjb.class)); - ejbJar.addEnterpriseBean(new StatelessBean(null, MEJBBean.class)); + // + // + // DONT MODIFY IT WITHOUT VALIDATING org.apache.openejb.config.SystemAppInfo.preComputedInfo() + // + // + ejbJar.addEnterpriseBean(singleton(DeployerEjb.class)); + ejbJar.addEnterpriseBean(singleton(ConfigurationInfoEjb.class)); + ejbJar.addEnterpriseBean(singleton(MEJBBean.class)); ejbJar.addInterceptor(new Interceptor(InternalSecurityInterceptor.class)); ejbJar.getAssemblyDescriptor().addInterceptorBinding(new InterceptorBinding("*", InternalSecurityInterceptor.class.getName())); module.getMbeans().add(JMXDeployer.class.getName()); - final String className = "org.apache.tomee.catalina.deployer.WebappDeployer"; - if (exists(className)) { - final SingletonBean bean = ejbJar.addEnterpriseBean(new SingletonBean("openejb/WebappDeployer", className)); - final EjbDeployment deployment = openejbJar.addEjbDeployment(bean); - deployment.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.annotationName}"); - - final SingletonBean exceptionManager = ejbJar.addEnterpriseBean(new SingletonBean("openejb/ExceptionManagerFacade", "org.apache.tomee.catalina.facade.ExceptionManagerFacadeBean")); - final EjbDeployment exceptionMgr = openejbJar.addEjbDeployment(exceptionManager); - exceptionMgr.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.annotationName}"); - } + final SingletonBean bean = ejbJar.addEnterpriseBean(new SingletonBean("openejb/WebappDeployer", "org.apache.tomee.catalina.deployer.WebappDeployer")); + final EjbDeployment deployment = openejbJar.addEjbDeployment(bean); + deployment.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.annotationName}"); + final SingletonBean exceptionManager = ejbJar.addEnterpriseBean(new SingletonBean("openejb/ExceptionManagerFacade", "org.apache.tomee.catalina.facade.ExceptionManagerFacadeBean")); + final EjbDeployment exceptionMgr = openejbJar.addEjbDeployment(exceptionManager); + exceptionMgr.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.annotationName}"); openejbJar.getProperties().put("openejb.deploymentId.format", "{ejbName}"); openejbJar.getProperties().put("openejb.jndiname.format", "{deploymentId}{interfaceType.openejbLegacyName}"); @@ -67,6 +68,14 @@ public class SystemApps { return module; } + public static boolean isExtended() { + return exists("org.apache.tomee.catalina.deployer.WebappDeployer"); + } + + private static SingletonBean singleton(final Class<?> ejbClass) { + return new SingletonBean(null, ejbClass); + } + private static boolean exists(final String className) { try { SystemApps.class.getClassLoader().loadClass(className); http://git-wip-us.apache.org/repos/asf/tomee/blob/1f9a2bfa/container/openejb-core/src/main/java/org/apache/openejb/mgmt/MEJBBean.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/mgmt/MEJBBean.java b/container/openejb-core/src/main/java/org/apache/openejb/mgmt/MEJBBean.java index 65d0296..ec5b129 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/mgmt/MEJBBean.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/mgmt/MEJBBean.java @@ -17,8 +17,11 @@ package org.apache.openejb.mgmt; +import java.util.List; +import java.util.Set; +import javax.ejb.Lock; import javax.ejb.RemoteHome; -import javax.ejb.Stateless; +import javax.ejb.Singleton; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; @@ -34,10 +37,11 @@ import javax.management.QueryExp; import javax.management.ReflectionException; import javax.management.j2ee.ListenerRegistration; import javax.management.j2ee.ManagementHome; -import java.util.List; -import java.util.Set; -@Stateless(name = "MEJB") +import static javax.ejb.LockType.READ; + +@Singleton(name = "MEJB") +@Lock(READ) @RemoteHome(ManagementHome.class) public class MEJBBean {