You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2008/08/07 09:50:48 UTC
svn commit: r683531 - in /openejb/trunk/openejb3:
api/ejb31-api-experimental/src/main/java/javax/ejb/
container/openejb-core/src/main/java/org/apache/openejb/
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
container/openejb-...
Author: dblevins
Date: Thu Aug 7 00:50:47 2008
New Revision: 683531
URL: http://svn.apache.org/viewvc?rev=683531&view=rev
Log:
OPENEJB-840: Singleton @Startup load-on-startup
OPENEJB-841: Singleton @DependsOn load ordering
Added:
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/DependsOn.java
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Startup.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckDependsOn.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/DependsOnTest.java
openejb/trunk/openejb3/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/KeepAilveTest.java
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanInfo.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppValidator.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/VmDeploymentManager.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/References.java
openejb/trunk/openejb3/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/SingletonContainerTest.java
openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/DependsOn.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/DependsOn.java?rev=683531&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/DependsOn.java (added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/DependsOn.java Thu Aug 7 00:50:47 2008
@@ -0,0 +1,28 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.ejb;
+
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.TYPE})
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+public @interface DependsOn {
+ String[] value();
+}
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Startup.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Startup.java?rev=683531&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Startup.java (added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Startup.java Thu Aug 7 00:50:47 2008
@@ -0,0 +1,27 @@
+/**
+ * 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.
+ */
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.ejb;
+
+@java.lang.annotation.Target(value = {java.lang.annotation.ElementType.TYPE})
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+public @interface Startup {
+}
\ No newline at end of file
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/DeploymentInfo.java Thu Aug 7 00:50:47 2008
@@ -24,6 +24,7 @@
import java.util.Collection;
import java.util.Map;
import java.util.List;
+import java.util.Set;
import javax.naming.Context;
public interface DeploymentInfo {
@@ -147,5 +148,9 @@
public <T> T set(Class<T> type, T value);
- public boolean retainIfExeption(Method removeMethod);
+ public boolean retainIfExeption(Method removeMethod);
+
+ public boolean isLoadOnStartup();
+
+ public Set<String> getDependsOn();
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Thu Aug 7 00:50:47 2008
@@ -31,6 +31,10 @@
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Set;
+import java.util.LinkedHashSet;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@@ -83,6 +87,8 @@
import org.apache.openejb.util.Messages;
import org.apache.openejb.util.OpenEJBErrorHandler;
import org.apache.openejb.util.SafeToolkit;
+import org.apache.openejb.util.References;
+import org.apache.openejb.util.CircularReferencesException;
import org.apache.openejb.util.proxy.ProxyFactory;
import org.apache.openejb.util.proxy.ProxyManager;
import org.apache.xbean.recipe.ObjectRecipe;
@@ -489,6 +495,8 @@
}
}
+ List<DeploymentInfo> allDeployments = new ArrayList<DeploymentInfo>();
+
// EJB
EjbJarBuilder ejbJarBuilder = new EjbJarBuilder(props, classLoader);
for (EjbJarInfo ejbJar : appInfo.ejbJars) {
@@ -544,11 +552,42 @@
}
}
- // now that everything is configured, deploy to the container
- ejbJarBuilder.deploy(deployments);
+ allDeployments.addAll(deployments.values());
+ }
+
+ // Sort all the singletons to the back of the list. We want to make sure
+ // all non-singletons are created first so that if a singleton refers to them
+ // they are available. We have to do this as @DependsOn only points to other
+ // Singleton beans. If it listed non-Singlton beans, then we wouldn't need to
+ // pre-sort.
+ Collections.sort(allDeployments, new Comparator<DeploymentInfo>(){
+ public int compare(DeploymentInfo a, DeploymentInfo b) {
+ int aa = (a.getComponentType() == BeanType.SINGLETON) ? 1 : 0;
+ int bb = (b.getComponentType() == BeanType.SINGLETON) ? 1 : 0;
+ return aa - bb;
+ }
+ });
+
+ // Sort all the beans with references to the back of the list. Beans
+ // without references to ther beans will be deployed first.
+ References.sort(allDeployments, new References.Visitor<DeploymentInfo>(){
+ public String getName(DeploymentInfo t) {
+ return (String) t.getDeploymentID();
+ }
+
+ public Set<String> getReferences(DeploymentInfo t) {
+ return t.getDependsOn();
+ }
+ });
- for (EnterpriseBeanInfo beanInfo : ejbJar.enterpriseBeans) {
- logger.info("createApplication.createdEjb", beanInfo.ejbDeploymentId, beanInfo.ejbName, beanInfo.containerId);
+ // now that everything is configured, deploy to the container
+ for (DeploymentInfo deployment : allDeployments) {
+ try {
+ Container container = deployment.getContainer();
+ container.deploy(deployment);
+ logger.info("createApplication.createdEjb", deployment.getDeploymentID(), deployment.getEjbName(), container.getContainerID());
+ } catch (Throwable t) {
+ throw new OpenEJBException("Error deploying '"+deployment.getEjbName()+"'. Exception: "+t.getClass()+": "+t.getMessage(), t);
}
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarBuilder.java Thu Aug 7 00:50:47 2008
@@ -66,14 +66,5 @@
}
return deployments;
}
-
- public void deploy(HashMap<String, DeploymentInfo> deployments) throws OpenEJBException {
- for (DeploymentInfo deployment : deployments.values()) {
- try {
- deployment.getContainer().deploy(deployment);
- } catch (Throwable t) {
- throw new OpenEJBException("Error deploying '"+deployment.getEjbName()+"'. Exception: "+t.getClass()+": "+t.getMessage(), t);
- }
- }
- }
+
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanBuilder.java Thu Aug 7 00:50:47 2008
@@ -211,6 +211,8 @@
if (ejbType == BeanType.SINGLETON) {
deployment.setBeanManagedConcurrency("Bean".equalsIgnoreCase(bean.concurrencyType));
+ deployment.getDependsOn().addAll(bean.dependsOn);
+ deployment.setLoadOnStartup(bean.loadOnStartup);
}
if (ejbType.isEntity()) {
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanInfo.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EnterpriseBeanInfo.java Thu Aug 7 00:50:47 2008
@@ -68,4 +68,6 @@
public List<JndiNameInfo> jndiNamess = new ArrayList<JndiNameInfo>();
public List<String> jndiNames = new ArrayList<String>();
+ public boolean loadOnStartup;
+ public final List<String> dependsOn = new ArrayList<String>() ;
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java Thu Aug 7 00:50:47 2008
@@ -121,6 +121,8 @@
import javax.ejb.Singleton;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
+import javax.ejb.Startup;
+import javax.ejb.DependsOn;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.ExcludeDefaultInterceptors;
import javax.interceptor.Interceptors;
@@ -151,6 +153,7 @@
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
+import java.util.Collections;
/**
* @version $Rev$ $Date$
@@ -662,8 +665,8 @@
}
}
for (FacesConfig facesConfig: webModule.getFacesConfigs()) {
- for(FacesManagedBean bean: facesConfig.getManagedBean()){
- String managedBeanClass = bean.getManagedBeanClass().trim();
+ for(FacesManagedBean bean: facesConfig.getManagedBean()){
+ String managedBeanClass = bean.getManagedBeanClass().trim();
if (managedBeanClass != null) {
try {
Class clazz = classLoader.loadClass(managedBeanClass);
@@ -672,7 +675,7 @@
throw new OpenEJBException("Unable to load JSF managed bean class: " + managedBeanClass, e);
}
}
- }
+ }
}
ClassFinder inheritedClassFinder = createInheritedClassFinder(classes.toArray(new Class<?>[classes.size()]));
@@ -871,6 +874,20 @@
} else {
checkAttributes(new ConcurrencyAttributeHandler(assemblyDescriptor, ejbName), ejbName, ejbModule, classFinder, "invalidConcurrencyAttribute");
}
+
+ if (!sessionBean.hasLoadOnStartup()){
+ Startup startup = getInheritableAnnotation(clazz, Startup.class);
+ sessionBean.setLoadOnStartup(startup != null);
+ }
+
+ if (sessionBean.getDependsOn() == null) {
+ DependsOn dependsOn = getInheritableAnnotation(clazz, DependsOn.class);
+ if (dependsOn != null) {
+ sessionBean.setDependsOn(dependsOn.value());
+ } else {
+ sessionBean.setDependsOn(Collections.EMPTY_LIST);
+ }
+ }
}
}
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java Thu Aug 7 00:50:47 2008
@@ -39,6 +39,8 @@
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Messages;
import org.apache.openejb.util.MakeTxLookup;
+import org.apache.openejb.util.References;
+import org.apache.openejb.util.CircularReferencesException;
import org.apache.openejb.jee.oejb3.EjbDeployment;
import org.apache.openejb.jee.jpa.unit.Persistence;
import org.apache.openejb.jee.jpa.unit.PersistenceUnit;
@@ -69,6 +71,8 @@
import java.util.Properties;
import java.util.Arrays;
import java.util.ArrayList;
+import java.util.Set;
+import java.util.LinkedHashSet;
import java.net.URL;
import java.io.File;
import java.io.IOException;
@@ -149,6 +153,7 @@
// Create the JNDI info builder
JndiEncInfoBuilder jndiEncInfoBuilder = new JndiEncInfoBuilder(appInfo);
+ List<EnterpriseBeanInfo> beans = new ArrayList<EnterpriseBeanInfo>();
// Build the JNDI tree for each ejb
for (EjbModule ejbModule : appModule.getEjbModules()) {
@@ -157,6 +162,7 @@
Map<String, EnterpriseBean> beanData = ejbModule.getEjbJar().getEnterpriseBeansByEjbName();
for (EnterpriseBeanInfo beanInfo : ejbJar.enterpriseBeans) {
+ beans.add(beanInfo);
// Get the ejb-jar.xml object
EnterpriseBean enterpriseBean = beanData.get(beanInfo.ejbName);
@@ -165,9 +171,28 @@
JndiEncInfo jndi = jndiEncInfoBuilder.build(enterpriseBean, beanInfo.ejbName, ejbJar.moduleId);
beanInfo.jndiEnc = jndi;
+
+
+ jndiEncInfoBuilder.buildDependsOnRefs(ejbModule, enterpriseBean, beanInfo, ejbJar.moduleId);
}
}
+ // Check for circular references in Singleton @DependsOn
+ try {
+ References.sort(beans, new References.Visitor<EnterpriseBeanInfo>(){
+ public String getName(EnterpriseBeanInfo bean) {
+ return bean.ejbDeploymentId;
+ }
+
+ public Set<String> getReferences(EnterpriseBeanInfo bean) {
+ return new LinkedHashSet<String>(bean.dependsOn);
+ }
+ });
+ } catch (CircularReferencesException e) {
+ List<List> circuits = e.getCircuits();
+
+ }
+
//
// Application Clients
//
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppValidator.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppValidator.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppValidator.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppValidator.java Thu Aug 7 00:50:47 2008
@@ -36,6 +36,7 @@
import org.apache.openejb.config.rules.CheckCallbacks;
import org.apache.openejb.config.rules.CheckInjectionTargets;
import org.apache.openejb.config.rules.CheckPersistenceRefs;
+import org.apache.openejb.config.rules.CheckDependsOn;
import org.apache.openejb.util.Messages;
import org.apache.openejb.util.OpenEjbVersion;
@@ -98,7 +99,8 @@
new CheckCallbacks(),
new CheckAssemblyBindings(),
new CheckInjectionTargets(),
- new CheckPersistenceRefs()
+ new CheckPersistenceRefs(),
+ new CheckDependsOn()
};
return rules;
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbJarInfoBuilder.java Thu Aug 7 00:50:47 2008
@@ -472,6 +472,9 @@
bean = new SingletonBeanInfo();
ConcurrencyType type = s.getConcurrencyType();
bean.concurrencyType = (type != null) ? type.toString() : ConcurrencyType.CONTAINER.toString();
+ bean.loadOnStartup = s.getLoadOnStartup();
+ // See JndiEncInfoBuilder.buildDependsOnRefs for processing of DependsOn
+ // bean.dependsOn.addAll(s.getDependsOn());
} else {
bean = new StatelessBeanInfo();
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/JndiEncInfoBuilder.java Thu Aug 7 00:50:47 2008
@@ -53,6 +53,9 @@
import org.apache.openejb.jee.ResourceRef;
import org.apache.openejb.jee.ServiceRef;
import org.apache.openejb.jee.EjbReference;
+import org.apache.openejb.jee.SessionBean;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.SessionType;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.Messages;
@@ -382,6 +385,65 @@
return infos;
}
+ public void buildDependsOnRefs(EjbModule module, EnterpriseBean enterpriseBean, EnterpriseBeanInfo beanInfo, String moduleId) throws OpenEJBException {
+ if (!(enterpriseBean instanceof SessionBean)) return;
+
+ SessionBean sessionBean = (SessionBean) enterpriseBean;
+
+ if (sessionBean.getSessionType() != SessionType.SINGLETON) return;
+
+ URI moduleUri = null;
+ if (moduleId != null) {
+ try {
+ moduleUri = new URI(moduleId);
+ } catch (URISyntaxException e) {
+ throw new OpenEJBException("Illegal moduleId " + moduleId, e);
+ }
+ }
+
+ EjbResolver ejbResolver = getEjbResolver(moduleId);
+
+ for (String ejbName : sessionBean.getDependsOn()) {
+ String deploymentId = ejbResolver.resolve(new SimpleRef(ejbName), moduleUri);
+ if (deploymentId != null) {
+ beanInfo.dependsOn.add(deploymentId);
+ }
+ }
+
+ }
+
+
+ private static class SimpleRef implements EjbResolver.Reference {
+ private final String name;
+
+ public SimpleRef(String name) {
+ this.name = name;
+ }
+
+ public String getEjbLink() {
+ return name;
+ }
+
+ public String getHome() {
+ return null;
+ }
+
+ public String getInterface() {
+ return null;
+ }
+
+ public String getMappedName() {
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public EjbResolver.Type getRefType() {
+ return EjbResolver.Type.UNKNOWN;
+ }
+ }
/**
* The assembler package cannot have a dependency on org.apache.openejb.jee
* so we simply have a trimmed down copy of the org.apache.openejb.jee.EjbReference interface
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/VmDeploymentManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/VmDeploymentManager.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/VmDeploymentManager.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/VmDeploymentManager.java Thu Aug 7 00:50:47 2008
@@ -79,7 +79,7 @@
private boolean deployerLocal;
public VmDeploymentManager() {
- String openejbHome = System.getProperty("openejb.home", "target/openejb-3.0.0-SNAPSHOT");
+ String openejbHome = System.getProperty("openejb.home", "target/openejb-3.1-SNAPSHOT");
File openejbHomeDir = new File(openejbHome);
if (!openejbHomeDir.exists()) {
throw new IllegalArgumentException("OpenEJB home dir does not exist: " + openejbHomeDir);
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckDependsOn.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckDependsOn.java?rev=683531&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckDependsOn.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/rules/CheckDependsOn.java Thu Aug 7 00:50:47 2008
@@ -0,0 +1,160 @@
+/**
+ * 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.rules;
+
+import org.apache.openejb.config.AppModule;
+import org.apache.openejb.config.EjbModule;
+import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.SessionBean;
+import org.apache.openejb.jee.SessionType;
+import org.apache.openejb.util.CircularReferencesException;
+import org.apache.openejb.util.Join;
+import org.apache.openejb.util.LinkResolver;
+import org.apache.openejb.util.References;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class CheckDependsOn extends ValidationBase {
+
+ public void validate(AppModule appModule) {
+ module = appModule;
+
+ LinkResolver<Bean> app = new LinkResolver<Bean>();
+
+ for (EjbModule ejbModule : appModule.getEjbModules()) {
+
+ String moduleId = ejbModule.getModuleId();
+
+ URI moduleUri = null;
+ if (moduleId != null) {
+ try {
+ moduleUri = new URI(moduleId);
+ } catch (URISyntaxException e) {
+ return;
+ }
+ }
+
+ Resolver<Bean> resolver = new Resolver(app, new LinkResolver<Bean>());
+
+ for (EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
+ Bean b = new Bean(bean, ejbModule, moduleUri, resolver);
+
+ resolver.module.add(ejbModule.getModuleId(), bean.getEjbName(), b);
+
+ resolver.app.add(ejbModule.getModuleId(), bean.getEjbName(), b);
+
+ }
+
+ }
+
+ boolean missingBeans = false;
+ for (Bean bean : app.values()) {
+ EnterpriseBean enterpriseBean = bean.bean;
+
+ if (!(enterpriseBean instanceof SessionBean)) continue;
+
+ SessionBean sessionBean = (SessionBean) enterpriseBean;
+
+ if (sessionBean.getSessionType() != SessionType.SINGLETON) continue;
+
+ for (String ejbName : sessionBean.getDependsOn()) {
+ Bean referee = bean.resolveLink(ejbName);
+ if (referee == null) {
+ bean.module.getValidation().fail(enterpriseBean.getEjbName(), "dependsOn.noSuchEjb", ejbName);
+ missingBeans = true;
+ } else {
+ bean.dependsOn.add(referee);
+ }
+ }
+ }
+
+ if (missingBeans) return;
+
+ try {
+ References.sort(new ArrayList<Bean>(app.values()), new References.Visitor<Bean>() {
+ public String getName(Bean t) {
+ return t.getId();
+ }
+
+ public Set<String> getReferences(Bean t) {
+ LinkedHashSet<String> refs = new LinkedHashSet<String>();
+ for (Bean bean : t.dependsOn) {
+ refs.add(bean.getId());
+ }
+ return refs;
+ }
+ });
+ } catch (CircularReferencesException e) {
+ for (List<Bean> circuit : e.getCircuits()) {
+ List<String> ejbNames = new ArrayList<String>(circuit.size());
+ for (Bean bean : circuit) {
+ ejbNames.add(bean.bean.getEjbName());
+ }
+ fail("EAR", "dependsOn.circuit", Join.join(" -> ", ejbNames), ejbNames.get(0));
+ }
+ }
+
+ }
+
+ public static class Resolver<T> {
+ private final LinkResolver<T> module;
+ private final LinkResolver<T> app;
+
+ public Resolver(LinkResolver<T> app, LinkResolver<T> module) {
+ this.app = app;
+ this.module = module;
+ }
+
+ public T resolveLink(String link, URI moduleUri) {
+ T value = module.resolveLink(link, moduleUri);
+ if (value != null) return value;
+
+ return app.resolveLink(link, moduleUri);
+ }
+ }
+
+ public static class Bean {
+ private final URI moduleUri;
+ private final EnterpriseBean bean;
+ private final ArrayList<Bean> dependsOn = new ArrayList<Bean>();
+ private final EjbModule module;
+ private final Resolver<Bean> resolver;
+
+ public Bean(EnterpriseBean bean, EjbModule module, URI moduleUri, Resolver<Bean> resolver) {
+ this.bean = bean;
+ this.module = module;
+ this.moduleUri = moduleUri;
+ this.resolver = resolver;
+ }
+
+ public Bean resolveLink(String ejbName) {
+ return resolver.resolveLink(ejbName, moduleUri);
+ }
+
+ public String getId() {
+ return toString();
+ }
+ }
+}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreDeploymentInfo.java Thu Aug 7 00:50:47 2008
@@ -26,6 +26,7 @@
import java.util.Set;
import java.util.ArrayList;
import java.util.TreeSet;
+import java.util.LinkedHashSet;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
@@ -92,6 +93,8 @@
private final List<Method> removeMethods = new ArrayList<Method>();
+ private final Set<String> dependsOn = new LinkedHashSet<String>();
+
private Method ejbTimeout;
private EjbTimerService ejbTimerService;
@@ -133,6 +136,7 @@
private Index<EntityManagerFactory,Map> extendedEntityManagerFactories;
private final Map<Class, InterfaceType> interfaces = new HashMap<Class, InterfaceType>();
private final Map<Class, ExceptionType> exceptions = new HashMap<Class, ExceptionType>();
+ private boolean loadOnStartup;
public Class getInterface(InterfaceType interfaceType) {
switch(interfaceType){
@@ -1112,4 +1116,16 @@
this.serviceEndpointInterface = serviceEndpointInterface;
mapObjectInterface(serviceEndpointInterface);
}
+
+ public boolean isLoadOnStartup() {
+ return loadOnStartup;
+ }
+
+ public void setLoadOnStartup(boolean loadOnStartup) {
+ this.loadOnStartup = loadOnStartup;
+ }
+
+ public Set<String> getDependsOn() {
+ return dependsOn;
+ }
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java Thu Aug 7 00:50:47 2008
@@ -116,6 +116,15 @@
if (timerService != null) {
timerService.start();
}
+
+ if (deploymentInfo.isLoadOnStartup()){
+ try {
+ ThreadContext callContext = new ThreadContext(deploymentInfo, null);
+ instanceManager.getInstance(callContext);
+ } catch (OpenEJBException e) {
+ throw new OpenEJBException("Singleton startup failed: "+deploymentInfo.getDeploymentID(), e);
+ }
+ }
}
public void undeploy(DeploymentInfo info) {
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/References.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/References.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/References.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/References.java Thu Aug 7 00:50:47 2008
@@ -77,17 +77,10 @@
if (n.refernceCount == 0) {
// if the node is totally isolated (no in or out refs),
// move it directly to the finished list, so they are first
-
if (n.references.size() == 0) {
-
sortedNodes.add(n);
-
-
} else {
-
-
leafNodes.add(n);
-
}
}
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/org/apache/openejb/config/rules/Messages.properties Thu Aug 7 00:50:47 2008
@@ -742,3 +742,13 @@
1.xml.businessLocal.notInterface = The value of <business-local> is not an interface
2.xml.businessLocal.notInterface = The value of <business-local> is not an interface: {0}
3.xml.businessLocal.notInterface = The <business-local> element of the ejb-jar.xml must be an interface. Classes, abstract classes or enums are not allowed. Either convert {0} to an interface or remove the related <business-local> xml tag from your ejb-jar.xml
+
+# fail(enterpriseBean.getEjbName(), "dependsOn.noSuchEjb", ejbName);
+1.dependsOn.noSuchEjb = Singleton @DependsOn refers to non-existant EJB:
+2.dependsOn.noSuchEjb = Singleton @DependsOn refers to non-existant EJB: {0}
+3.dependsOn.noSuchEjb = The @DependsOn annotation or <depends-on> descriptor data for this Singeton bean lists an EJB "{0}" which does not exist in any of the modules of the ear.
+
+# fail("EAR", "dependsOn.circuit", Join.join(" -> ", ejbNames), ejbNames.get(0));
+1.dependsOn.circuit = Singleton circular dependency detected
+2.dependsOn.circuit = Singleton circular dependency detected: {0}
+3.dependsOn.circuit = A Singleton circular dependency has been detected in the application. Bean "{1}" refers to one or more other singleton beans via @DependsOn which directly or indirectly refer back to bean "{1}". This circle must be broken befor the application can be built: {0}
Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/DependsOnTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/DependsOnTest.java?rev=683531&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/DependsOnTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/DependsOnTest.java Thu Aug 7 00:50:47 2008
@@ -0,0 +1,198 @@
+/**
+ * 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.core.singleton;
+
+import junit.framework.TestCase;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ProxyFactoryInfo;
+import org.apache.openejb.assembler.classic.SecurityServiceInfo;
+import org.apache.openejb.assembler.classic.SingletonSessionContainerInfo;
+import org.apache.openejb.assembler.classic.TransactionServiceInfo;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.config.ValidationFailedException;
+import org.apache.openejb.config.ValidationFailure;
+import org.apache.openejb.core.ivm.naming.InitContextFactory;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.SingletonBean;
+import org.apache.openejb.OpenEJBException;
+
+import javax.annotation.PostConstruct;
+import javax.ejb.DependsOn;
+import javax.ejb.Singleton;
+import javax.ejb.Startup;
+import javax.naming.NamingException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DependsOnTest extends TestCase {
+ private static final String one = "one";
+ private static final String two = "two";
+ private static final String three = "three";
+ private static final String four = "four";
+
+ public void test() throws Exception {
+
+ System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, InitContextFactory.class.getName());
+
+ Assembler assembler = new Assembler();
+ ConfigurationFactory config = new ConfigurationFactory();
+
+ assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+ assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+ assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+ // containers
+ assembler.createContainer(config.configureService(SingletonSessionContainerInfo.class));
+
+ actual.clear();
+
+ EjbJar ejbJar = new EjbJar();
+
+ ejbJar.addEnterpriseBean(new SingletonBean(One.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Two.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Three.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Four.class));
+
+ assembler.createApplication(config.configureApplication(ejbJar));
+
+ assertEquals(expected(four, three, two, one), actual);
+ }
+
+ public void testNoSuchEjb() throws Exception {
+
+ System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, InitContextFactory.class.getName());
+
+ Assembler assembler = new Assembler();
+ ConfigurationFactory config = new ConfigurationFactory();
+
+ assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+ assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+ assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+ // containers
+ assembler.createContainer(config.configureService(SingletonSessionContainerInfo.class));
+
+
+ EjbJar ejbJar = new EjbJar();
+
+ ejbJar.addEnterpriseBean(new SingletonBean(One.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Two.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Three.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Four.class)).setDependsOn("Five");
+
+ try {
+ config.configureApplication(ejbJar);
+ fail("Validation should have found a circular reference");
+ } catch (ValidationFailedException e) {
+ ValidationFailure[] failures = e.getFailures();
+ assertEquals(1, failures.length);
+ assertEquals("dependsOn.noSuchEjb", failures[0].getMessageKey());
+ }
+ }
+
+ public void testCircuit() throws Exception {
+
+ System.setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY, InitContextFactory.class.getName());
+
+ Assembler assembler = new Assembler();
+ ConfigurationFactory config = new ConfigurationFactory();
+
+ assembler.createProxyFactory(config.configureService(ProxyFactoryInfo.class));
+ assembler.createTransactionManager(config.configureService(TransactionServiceInfo.class));
+ assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
+
+ // containers
+ assembler.createContainer(config.configureService(SingletonSessionContainerInfo.class));
+
+
+ EjbJar ejbJar = new EjbJar();
+
+ ejbJar.addEnterpriseBean(new SingletonBean(One.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Two.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Three.class));
+ ejbJar.addEnterpriseBean(new SingletonBean(Four.class)).setDependsOn("One");
+
+ try {
+ config.configureApplication(ejbJar);
+ fail("Validation should have found a circular reference");
+ } catch (ValidationFailedException e) {
+ ValidationFailure[] failures = e.getFailures();
+ assertEquals(1, failures.length);
+ assertEquals("dependsOn.circuit", failures[0].getMessageKey());
+ }
+ }
+
+ private List<String> expected(String... strings) {
+ return Arrays.asList(strings);
+ }
+
+ private final static List<String> actual = new ArrayList<String>();
+
+ public static interface Bean {
+
+ }
+
+ @Singleton
+ @Startup
+ @DependsOn("Two")
+ public static class One implements Bean {
+
+ @PostConstruct
+ public void construct() {
+ actual.add(one);
+ }
+ }
+
+ @Singleton
+ @Startup
+ @DependsOn("Three")
+ public static class Two implements Bean {
+
+ @PostConstruct
+ public void construct() {
+ actual.add(two);
+ }
+ }
+
+ @Singleton
+ @Startup
+ @DependsOn("Four")
+ public static class Three implements Bean {
+
+ @PostConstruct
+ public void construct() {
+ actual.add(three);
+ }
+ }
+
+ @Singleton
+ @Startup
+ public static class Four implements Bean {
+
+ @PostConstruct
+ public void construct() {
+ actual.add(four);
+ }
+ }
+
+
+}
Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/SingletonContainerTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/SingletonContainerTest.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/SingletonContainerTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/singleton/SingletonContainerTest.java Thu Aug 7 00:50:47 2008
@@ -93,11 +93,7 @@
assembler.createSecurityService(config.configureService(SecurityServiceInfo.class));
// containers
- SingletonSessionContainerInfo singletonContainerInfo = config.configureService(SingletonSessionContainerInfo.class);
-// singletonContainerInfo.properties.setProperty("TimeOut", "10");
-// singletonContainerInfo.properties.setProperty("PoolSize", "0");
-// singletonContainerInfo.properties.setProperty("StrictPooling", "false");
- assembler.createContainer(singletonContainerInfo);
+ assembler.createContainer(config.configureService(SingletonSessionContainerInfo.class));
// Setup the descriptor information
Modified: openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java?rev=683531&r1=683530&r2=683531&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java (original)
+++ openejb/trunk/openejb3/container/openejb-jee/src/main/java/org/apache/openejb/jee/SessionBean.java Thu Aug 7 00:50:47 2008
@@ -25,6 +25,7 @@
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.ArrayList;
@@ -32,6 +33,7 @@
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Arrays;
/**
@@ -109,6 +111,7 @@
"serviceEndpoint",
"ejbClass",
"sessionType",
+ "loadOnStartup",
"timeoutMethod",
"initMethod",
"removeMethod",
@@ -129,7 +132,8 @@
"postActivate",
"prePassivate",
"securityRoleRef",
- "securityIdentity"
+ "securityIdentity",
+ "dependsOn"
})
public class SessionBean implements EnterpriseBean, RemoteBean, Session, TimerConsumer {
@XmlTransient
@@ -200,6 +204,14 @@
protected List<SecurityRoleRef> securityRoleRef;
@XmlElement(name = "security-identity")
protected SecurityIdentity securityIdentity;
+
+ @XmlElement(name = "load-on-startup")
+ protected Boolean loadOnStartup;
+
+ @XmlElementWrapper(name = "depends-on")
+ @XmlElement(name = "ejb-name")
+ protected List<String> dependsOn;
+
@XmlAttribute
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlID
@@ -217,7 +229,7 @@
public String getJndiConsumerName() {
return ejbName;
}
-
+
@XmlElement(name = "description", required = true)
public Text[] getDescriptions() {
return description.toArray();
@@ -645,6 +657,30 @@
this.securityIdentity = value;
}
+ public List<String> getDependsOn() {
+ return dependsOn;
+ }
+
+ public void setDependsOn(String... ejbNames) {
+ setDependsOn(Arrays.asList(ejbNames));
+ }
+
+ public void setDependsOn(List<String> ejbNames) {
+ this.dependsOn = new ArrayList(ejbNames);
+ }
+
+ public boolean hasLoadOnStartup() {
+ return loadOnStartup != null;
+ }
+
+ public boolean getLoadOnStartup() {
+ return loadOnStartup != null && loadOnStartup;
+ }
+
+ public void setLoadOnStartup(boolean loadOnStartup) {
+ this.loadOnStartup = loadOnStartup;
+ }
+
public String getId() {
return id;
}
Added: openejb/trunk/openejb3/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/KeepAilveTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/KeepAilveTest.java?rev=683531&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/KeepAilveTest.java (added)
+++ openejb/trunk/openejb3/server/openejb-ejbd/src/test/java/org/apache/openejb/server/ejbd/KeepAilveTest.java Thu Aug 7 00:50:47 2008
@@ -0,0 +1,211 @@
+/**
+ * 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.server.ejbd;
+
+import junit.framework.TestCase;
+import junit.framework.Assert;
+
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.jee.EjbJar;
+import org.apache.openejb.jee.StatelessBean;
+import org.apache.openejb.config.ConfigurationFactory;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.server.ServicePool;
+import org.apache.openejb.server.ServiceDaemon;
+import org.apache.openejb.core.ServerFederation;
+
+import javax.naming.NamingException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.ejb.Remote;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class KeepAilveTest extends TestCase {
+ public void _testPool() throws Exception {
+ int threads = 2;
+ ThreadPoolExecutor pool = new ThreadPoolExecutor(threads, threads, 120, TimeUnit.SECONDS, new LinkedBlockingQueue());
+
+ Runnable runnable = new Runnable(){
+ public void run() {
+ waitOneSecond();
+ }
+ };
+
+ print(pool);
+
+ for (int i = 0; i < 10 ; i++) {
+ System.out.println("" + i);
+ pool.execute(runnable);
+ print(pool);
+ }
+
+ waitOneSecond();
+
+ for (int i = 0; i < 10 ; i++) {
+ print(pool);
+ waitOneSecond();
+ }
+ print(pool);
+ fail();
+ }
+
+ private void waitOneSecond() {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void print(ThreadPoolExecutor pool) {
+ System.out.println("==========================================");
+ int activeCount = pool.getActiveCount();
+ System.out.println("activeCount = " + activeCount);
+ int corePoolSize = pool.getCorePoolSize();
+ System.out.println("corePoolSize = " + corePoolSize);
+ int largestPoolSize = pool.getLargestPoolSize();
+ System.out.println("largestPoolSize = " + largestPoolSize);
+ int maximumPoolSize = pool.getMaximumPoolSize();
+ System.out.println("maximumPoolSize = " + maximumPoolSize);
+ int poolSize = pool.getPoolSize();
+ System.out.println("poolSize = " + poolSize);
+ int queueSize = pool.getQueue().size();
+ System.out.println("queueSize = " + queueSize);
+ long taskCount = pool.getTaskCount();
+ System.out.println("taskCount = " + taskCount);
+ System.out.println("==========================================");
+ }
+
+ public void test() throws Exception {
+
+ }
+ public void _test() throws Exception {
+ EjbServer ejbServer = new EjbServer();
+ KeepAliveServer keepAliveServer = new KeepAliveServer(ejbServer);
+
+ Properties initProps = new Properties();
+ initProps.setProperty("openejb.deployments.classpath.include", "");
+ initProps.setProperty("openejb.deployments.classpath.filter.descriptors", "true");
+ OpenEJB.init(initProps, new ServerFederation());
+ ejbServer.init(new Properties());
+
+ ServicePool pool = new ServicePool(keepAliveServer, "ejbd", 10);
+ ServiceDaemon serviceDaemon = new ServiceDaemon(pool, 0, "localhost");
+ serviceDaemon.start();
+
+ try {
+
+ int port = serviceDaemon.getPort();
+
+ Assembler assembler = SystemInstance.get().getComponent(Assembler.class);
+ ConfigurationFactory config = new ConfigurationFactory();
+
+ EjbJar ejbJar = new EjbJar();
+ ejbJar.addEnterpriseBean(new StatelessBean(EchoBean.class));
+
+ assembler.createApplication(config.configureApplication(ejbJar));
+
+ // good creds
+
+ int threads = 1;
+ CountDownLatch latch = new CountDownLatch(threads);
+
+ for (int i = 0; i < threads; i++) {
+ Client client = new Client(latch, i, port);
+ thread(client, false);
+ }
+
+ assertTrue(latch.await(60, TimeUnit.SECONDS));
+ } finally {
+ serviceDaemon.stop();
+ OpenEJB.destroy();
+ }
+ }
+
+ public static void thread(Runnable runnable, boolean daemon) {
+ Thread thread = new Thread(runnable);
+ thread.setDaemon(daemon);
+ thread.start();
+ }
+
+ public static class Client implements Runnable {
+
+ private final Echo echo;
+ private final CountDownLatch latch;
+ private final int id;
+
+ public Client(CountDownLatch latch, int i, int port) throws NamingException {
+ this.latch = latch;
+ this.id = i;
+
+ Properties props = new Properties();
+ props.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory");
+ props.put("java.naming.provider.url", "ejbd://127.0.0.1:" + port +"?"+id);
+ Context context = new InitialContext(props);
+
+ this.echo = (Echo) context.lookup("EchoBeanRemote");
+ }
+
+ public void run() {
+
+ try {
+ int count = 10;
+ for (; count >= 0; count--){
+ String message = count + " bottles of beer on the wall";
+
+// Thread.currentThread().setName("client-"+id+": "+count);
+
+ String response = echo.echo(message);
+ Assert.assertEquals(message, reverse(response));
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ } finally {
+ latch.countDown();
+ }
+ }
+
+ private Object reverse(String s) {
+ return new StringBuilder(s).reverse().toString();
+ }
+ }
+
+
+ public static class EchoBean implements Echo {
+ public String echo(String s) {
+// System.out.println(s);
+ return new StringBuilder(s).reverse().toString();
+ }
+ }
+
+ @Remote
+ public static interface Echo {
+ public String echo(String s);
+ }
+}