You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2014/04/20 18:47:22 UTC

svn commit: r1588792 - in /tomee/tomee/trunk/container/openejb-junit/src: main/java/org/apache/openejb/junit/jee/ main/java/org/apache/openejb/junit/jee/rule/ main/java/org/apache/openejb/junit/jee/statement/ test/java/org/apache/openejb/junit/

Author: rmannibucau
Date: Sun Apr 20 16:47:21 2014
New Revision: 1588792

URL: http://svn.apache.org/r1588792
Log:
OPENEJB-2090 EJBContainer junit rules

Added:
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRule.java
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/rule/
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/rule/InjectRule.java
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/DecoratingStatement.java
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/InjectStatement.java
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/ShutingDownStatement.java
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/StartingStatement.java
    tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRule.java
    tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleSimpleRule.java
    tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleWithProgramaticInjection.java
Modified:
    tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRunner.java

Added: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRule.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRule.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRule.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRule.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,70 @@
+/**
+ * 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.junit.jee;
+
+import org.apache.openejb.OpenEJBRuntimeException;
+import org.apache.openejb.junit.jee.statement.InjectStatement;
+import org.apache.openejb.junit.jee.statement.ShutingDownStatement;
+import org.apache.openejb.junit.jee.statement.StartingStatement;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+// @Rule works but mainly designed for @ClassRule for perf reasons
+public class EJBContainerRule implements TestRule {
+    private final Object test;
+
+    private StartingStatement startingStatement;
+
+    // @ClassRule, you'll need @Rule InjectRule to get injections
+    public EJBContainerRule() {
+        this(null);
+    }
+
+    // @Rule, injections are automatic on test
+    public EJBContainerRule(final Object test) {
+        this.test = test;
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description description) {
+        if (test == null) {
+            startingStatement = new StartingStatement(base, description.getTestClass());
+        } else {
+            startingStatement = new StartingStatement(new Statement() {
+                @Override // this class avoids a dependency loop issue, we have it actually but that's just to make a nicer API
+                public void evaluate() throws Throwable {
+                    // don't use testClass since it can be another instance that the test one
+                    new InjectStatement(base, test.getClass(), test, startingStatement).evaluate();
+                }
+            }, description.getTestClass());
+        }
+        return new ShutingDownStatement(startingStatement, startingStatement);
+    }
+
+    public void inject(final Object target) {
+        try { // reuse this logic to get @TestResource for free
+            new InjectStatement(null, target.getClass(), target, startingStatement).evaluate();
+        } catch (final Throwable throwable) {
+            throw new OpenEJBRuntimeException(throwable.getMessage(), throwable);
+        }
+    }
+
+    public StartingStatement getStartingStatement() {
+        return startingStatement;
+    }
+}

Modified: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRunner.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRunner.java?rev=1588792&r1=1588791&r2=1588792&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRunner.java (original)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/EJBContainerRunner.java Sun Apr 20 16:47:21 2014
@@ -16,38 +16,23 @@
  */
 package org.apache.openejb.junit.jee;
 
-import org.apache.openejb.OpenEJB;
-import org.apache.openejb.OpenEJBException;
-import org.apache.openejb.OpenEjbContainer;
-import org.apache.openejb.junit.jee.config.Properties;
-import org.apache.openejb.junit.jee.config.Property;
-import org.apache.openejb.junit.jee.config.PropertyFile;
-import org.apache.openejb.junit.jee.resources.TestResource;
+import org.apache.openejb.junit.jee.rule.InjectRule;
+import org.apache.openejb.junit.jee.statement.ShutingDownStatement;
+import org.apache.openejb.junit.jee.statement.StartingStatement;
 import org.apache.openejb.junit.jee.transaction.TransactionRule;
-import org.apache.openejb.osgi.client.LocalInitialContextFactory;
 import org.junit.Rule;
 import org.junit.rules.TestRule;
-import org.junit.runner.Description;
 import org.junit.runners.BlockJUnit4ClassRunner;
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.Statement;
 
-import javax.ejb.embeddable.EJBContainer;
-import javax.naming.Context;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Hashtable;
 import java.util.List;
-import java.util.Map;
 
 public class EJBContainerRunner extends BlockJUnit4ClassRunner {
-    private java.util.Properties properties;
-    private EJBContainer container;
+    private StartingStatement startingStatement;
 
     public EJBContainerRunner(final Class<?> klass) throws InitializationError {
         super(klass);
@@ -55,12 +40,13 @@ public class EJBContainerRunner extends 
 
     @Override
     protected Statement withBeforeClasses(final Statement statement) {
-        return new StartingStatement(super.withBeforeClasses(statement));
+        startingStatement = new StartingStatement(super.withBeforeClasses(statement), getTestClass().getJavaClass());
+        return startingStatement;
     }
 
     @Override
     protected Statement withAfterClasses(final Statement statement) {
-        return new ShutingDownStatement(super.withAfterClasses(statement));
+        return new ShutingDownStatement(super.withAfterClasses(statement), startingStatement);
     }
 
     @Override
@@ -73,149 +59,10 @@ public class EJBContainerRunner extends 
     @Override
     protected List<TestRule> getTestRules(final Object target) {
         final List<TestRule> rules = new ArrayList<TestRule>();
-        rules.add(new InjectRule(target));
+        rules.add(new InjectRule(target, startingStatement));
         rules.add(new TransactionRule());
         rules.addAll(getTestClass().getAnnotatedFieldValues(target, Rule.class, TestRule.class));
         return rules;
     }
-
-    private static abstract class DecoratingStatement extends Statement {
-        protected Statement decorated;
-
-        public DecoratingStatement(final Statement statement) {
-            decorated = statement;
-        }
-
-        @Override
-        public void evaluate() throws Throwable {
-            before();
-            try {
-                decorated.evaluate();
-            } finally {
-                after();
-            }
-        }
-
-        protected void before() throws Exception {
-            // no-op
-        }
-
-        protected void after() throws Exception {
-            // no-op
-        }
-    }
-
-    private class StartingStatement extends DecoratingStatement {
-        public StartingStatement(final Statement statement) {
-            super(statement);
-        }
-
-        @Override
-        protected void before() throws Exception {
-            final Class<?> clazz = getTestClass().getJavaClass();
-            properties = new java.util.Properties();
-            properties.put(OpenEjbContainer.Provider.OPENEJB_ADDITIONNAL_CALLERS_KEY, clazz.getName());
-
-            final PropertyFile propertyFile = clazz.getAnnotation(PropertyFile.class);
-            if (propertyFile != null) {
-                final String path = propertyFile.value();
-                if (!path.isEmpty()) {
-                    InputStream is = clazz.getClassLoader().getResourceAsStream(path);
-                    if (is == null) {
-                        final File file = new File(path);
-                        if (file.exists()) {
-                            is = new FileInputStream(file);
-                        } else {
-                            throw new OpenEJBException("properties resource '" + path + "' not found");
-                        }
-                    }
-
-                    final java.util.Properties fileProps = new java.util.Properties();
-                    fileProps.load(is);
-                    for (Map.Entry<Object, Object> entry : fileProps.entrySet()) {
-                        properties.put(entry.getKey().toString(), entry.getValue().toString());
-                    }
-                }
-            }
-
-            final Properties annotationConfig = clazz.getAnnotation(Properties.class);
-            if (annotationConfig != null) {
-                for (Property property : annotationConfig.value()) {
-                    properties.put(property.key(), property.value());
-                }
-            }
-
-            if (!properties.containsKey(Context.INITIAL_CONTEXT_FACTORY)) {
-                properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
-            }
-
-            container = EJBContainer.createEJBContainer(properties);
-        }
-    }
-
-    private class ShutingDownStatement extends DecoratingStatement {
-        public ShutingDownStatement(final Statement statement) {
-            super(statement);
-        }
-
-        @Override
-        protected void after() throws Exception {
-            if (container != null) {
-                container.close();
-                OpenEJB.destroy();
-                container = null;
-            }
-        }
-    }
-
-    private class InjectRule implements TestRule {
-        private Object test;
-
-        public InjectRule(final Object target) {
-            this.test = target;
-        }
-
-        @Override
-        public Statement apply(final Statement base, final Description description) {
-            return new InjectStatement(base, test);
-        }
-    }
-
-    private class InjectStatement extends Statement {
-        private Object test;
-        private Statement statement;
-
-        public InjectStatement(final Statement stat, final Object o) {
-            statement = stat;
-            test = o;
-        }
-
-        @Override
-        public void evaluate() throws Throwable {
-            Class<?> clazz = test.getClass();
-            while (!Object.class.equals(clazz)) {
-                for (Field field : clazz.getDeclaredFields()) {
-                    final TestResource resource = field.getAnnotation(TestResource.class);
-                    if (resource != null) {
-                        if (Context.class.isAssignableFrom(field.getType())) {
-                            field.setAccessible(true);
-                            field.set(test, container.getContext());
-                        } else if (Hashtable.class.isAssignableFrom(field.getType())) {
-                            field.setAccessible(true);
-                            field.set(test, properties);
-                        } else if (EJBContainer.class.isAssignableFrom(field.getType())) {
-                            field.setAccessible(true);
-                            field.set(test, container);
-                        } else {
-                            throw new OpenEJBException("can't inject field '" + field.getName() + "'");
-                        }
-                    }
-                }
-                clazz = clazz.getSuperclass();
-            }
-            container.getContext().bind("inject", test);
-            statement.evaluate();
-        }
-    }
 }
 

Added: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/rule/InjectRule.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/rule/InjectRule.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/rule/InjectRule.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/rule/InjectRule.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,27 @@
+package org.apache.openejb.junit.jee.rule;
+
+import org.apache.openejb.junit.jee.EJBContainerRule;
+import org.apache.openejb.junit.jee.statement.InjectStatement;
+import org.apache.openejb.junit.jee.statement.StartingStatement;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+public class InjectRule implements TestRule {
+    private final StartingStatement startingStatement;
+    private final Object test;
+
+    public InjectRule(final Object target, final EJBContainerRule rule) {
+        this(target, rule.getStartingStatement());
+    }
+
+    public InjectRule(final Object target, final StartingStatement startingStatement) {
+        this.test = target;
+        this.startingStatement = startingStatement;
+    }
+
+    @Override
+    public Statement apply(final Statement base, final Description description) {
+        return new InjectStatement(base, test.getClass(), test, startingStatement);
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/DecoratingStatement.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/DecoratingStatement.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/DecoratingStatement.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/DecoratingStatement.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,45 @@
+/**
+ * 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.junit.jee.statement;
+
+import org.junit.runners.model.Statement;
+
+public abstract class DecoratingStatement extends Statement {
+    protected Statement decorated;
+
+    public DecoratingStatement(final Statement statement) {
+        decorated = statement;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        before();
+        try {
+            decorated.evaluate();
+        } finally {
+            after();
+        }
+    }
+
+    protected void before() throws Exception {
+        // no-op
+    }
+
+    protected void after() throws Exception {
+        // no-op
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/InjectStatement.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/InjectStatement.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/InjectStatement.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/InjectStatement.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,59 @@
+package org.apache.openejb.junit.jee.statement;
+
+import org.apache.openejb.Injector;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.junit.jee.resources.TestResource;
+import org.junit.runners.model.Statement;
+
+import javax.ejb.embeddable.EJBContainer;
+import javax.naming.Context;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Hashtable;
+
+public class InjectStatement extends Statement {
+    private final StartingStatement startingStatement;
+    private final Object test;
+    private final Statement statement;
+    private final Class<?> clazz;
+
+    public InjectStatement(final Statement stat, final Class<?> clazz, final Object o, final StartingStatement startingStatement) {
+        this.statement = stat;
+        this.clazz = clazz;
+        this.test = o;
+        this.startingStatement = startingStatement;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+        if (startingStatement != null) {
+            Class<?> clazz = this.clazz;
+            while (!Object.class.equals(clazz)) {
+                for (Field field : clazz.getDeclaredFields()) {
+                    final TestResource resource = field.getAnnotation(TestResource.class);
+                    if (resource != null) {
+                        if (Context.class.isAssignableFrom(field.getType())) {
+                            field.setAccessible(true);
+                            field.set(Modifier.isStatic(field.getModifiers()) ? null : test, startingStatement.getContainer().getContext());
+                        } else if (Hashtable.class.isAssignableFrom(field.getType())) {
+                            field.setAccessible(true);
+                            field.set(Modifier.isStatic(field.getModifiers()) ? null : test, startingStatement.getProperties());
+                        } else if (EJBContainer.class.isAssignableFrom(field.getType())) {
+                            field.setAccessible(true);
+                            field.set(Modifier.isStatic(field.getModifiers()) ? null : test, startingStatement.getContainer());
+                        } else {
+                            throw new OpenEJBException("can't inject field '" + field.getName() + "'");
+                        }
+                    }
+                }
+                clazz = clazz.getSuperclass();
+            }
+        }
+        if (test != null) {
+            Injector.inject(test);
+        }
+        if (statement != null) {
+            statement.evaluate();
+        }
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/ShutingDownStatement.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/ShutingDownStatement.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/ShutingDownStatement.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/ShutingDownStatement.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,24 @@
+package org.apache.openejb.junit.jee.statement;
+
+import org.apache.openejb.OpenEJB;
+import org.junit.runners.model.Statement;
+
+import javax.ejb.embeddable.EJBContainer;
+
+public class ShutingDownStatement extends DecoratingStatement {
+    private final StartingStatement startingStatement;
+
+    public ShutingDownStatement(final Statement statement, final StartingStatement startingStatement) {
+        super(statement);
+        this.startingStatement = startingStatement;
+    }
+
+    @Override
+    protected void after() throws Exception {
+        final EJBContainer container = startingStatement.getContainer();
+        if (container != null) {
+            container.close();
+            OpenEJB.destroy();
+        }
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/StartingStatement.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/StartingStatement.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/StartingStatement.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/main/java/org/apache/openejb/junit/jee/statement/StartingStatement.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,103 @@
+/**
+ * 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.junit.jee.statement;
+
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.OpenEjbContainer;
+import org.apache.openejb.junit.jee.config.Properties;
+import org.apache.openejb.junit.jee.config.Property;
+import org.apache.openejb.junit.jee.config.PropertyFile;
+import org.apache.openejb.osgi.client.LocalInitialContextFactory;
+import org.apache.openejb.util.Classes;
+import org.junit.runners.model.Statement;
+
+import javax.ejb.embeddable.EJBContainer;
+import javax.naming.Context;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Map;
+
+public class StartingStatement extends DecoratingStatement {
+    private final Class<?> clazz;
+    private java.util.Properties properties;
+    private EJBContainer container = null;
+
+    public StartingStatement(final Statement statement, final Class<?> clazz) {
+        super(statement);
+        this.clazz = clazz;
+    }
+
+    @Override
+    protected void before() throws Exception {
+        properties = new java.util.Properties();
+
+        { // set caller first to let it be overridable by @Property
+            final StringBuilder b = new StringBuilder();
+            for (final Class<?> c : Classes.ancestors(clazz)) {
+                if (c != Object.class) {
+                    b.append(c.getName()).append(",");
+                }
+            }
+            b.setLength(b.length() - 1);
+            properties.put(OpenEjbContainer.Provider.OPENEJB_ADDITIONNAL_CALLERS_KEY, b.toString());
+        }
+
+        final PropertyFile propertyFile = clazz.getAnnotation(PropertyFile.class);
+        if (propertyFile != null) {
+            final String path = propertyFile.value();
+            if (!path.isEmpty()) {
+                InputStream is = clazz.getClassLoader().getResourceAsStream(path);
+                if (is == null) {
+                    final File file = new File(path);
+                    if (file.exists()) {
+                        is = new FileInputStream(file);
+                    } else {
+                        throw new OpenEJBException("properties resource '" + path + "' not found");
+                    }
+                }
+
+                final java.util.Properties fileProps = new java.util.Properties();
+                fileProps.load(is);
+                for (final Map.Entry<Object, Object> entry : fileProps.entrySet()) {
+                    properties.put(entry.getKey().toString(), entry.getValue().toString());
+                }
+            }
+        }
+
+        final Properties annotationConfig = clazz.getAnnotation(Properties.class);
+        if (annotationConfig != null) {
+            for (final Property property : annotationConfig.value()) {
+                properties.put(property.key(), property.value());
+            }
+        }
+
+        if (!properties.containsKey(Context.INITIAL_CONTEXT_FACTORY)) {
+            properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName());
+        }
+
+        container = EJBContainer.createEJBContainer(properties);
+    }
+
+    public java.util.Properties getProperties() {
+        return properties;
+    }
+
+    public EJBContainer getContainer() {
+        return container;
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRule.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRule.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRule.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRule.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,76 @@
+/**
+ * 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.junit;
+
+import org.apache.openejb.junit.ejbs.BasicEjbLocal;
+import org.apache.openejb.junit.jee.EJBContainerRule;
+import org.apache.openejb.junit.jee.config.Properties;
+import org.apache.openejb.junit.jee.config.Property;
+import org.apache.openejb.junit.jee.rule.InjectRule;
+import org.apache.openejb.config.DeploymentFilterable;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+import javax.ejb.EJB;
+import javax.ejb.embeddable.EJBContainer;
+import javax.naming.Context;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@Properties({
+        // FallbackPropertyInjector for ejb to test config
+        @org.apache.openejb.junit.jee.config.Property(key = DeploymentFilterable.CLASSPATH_EXCLUDE, value = "jar:.*")
+})
+public class TestEJBContainerRule {
+    @ClassRule
+    public static final EJBContainerRule CONTAINER_RULE = new EJBContainerRule();
+
+    @Rule
+    public final InjectRule injectRule = new InjectRule(this, CONTAINER_RULE);
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private Context ctx;
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private java.util.Properties props;
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private EJBContainer container;
+
+    @EJB
+    private BasicEjbLocal ejb;
+
+    private void doChecks() {
+        assertNotNull(ctx);
+        assertNotNull(props);
+        assertNotNull(container);
+        assertNotNull(ejb);
+        assertEquals("a b", ejb.concat("a", "b"));
+    }
+
+    @Test
+    public void checkAllIsFine() {
+        doChecks();
+    }
+
+    @Test
+    public void checkAllIsStillFine() {
+        doChecks();
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleSimpleRule.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleSimpleRule.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleSimpleRule.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleSimpleRule.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,72 @@
+/**
+ * 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.junit;
+
+import org.apache.openejb.config.DeploymentFilterable;
+import org.apache.openejb.junit.ejbs.BasicEjbLocal;
+import org.apache.openejb.junit.jee.EJBContainerRule;
+import org.apache.openejb.junit.jee.config.Properties;
+import org.apache.openejb.junit.jee.config.Property;
+import org.junit.Rule;
+import org.junit.Test;
+
+import javax.ejb.EJB;
+import javax.ejb.embeddable.EJBContainer;
+import javax.naming.Context;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@Properties({
+        // FallbackPropertyInjector for ejb to test config
+        @Property(key = DeploymentFilterable.CLASSPATH_EXCLUDE, value = "jar:.*"),
+        @Property(key = DeploymentFilterable.CLASSPATH_INCLUDE, value = ".*openejb-junit.*")
+})
+public class TestEJBContainerRuleSimpleRule {
+    @Rule
+    public final EJBContainerRule containerRule = new EJBContainerRule(this);
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private Context ctx;
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private java.util.Properties props;
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private EJBContainer container;
+
+    @EJB
+    private BasicEjbLocal ejb;
+
+    private void doChecks() {
+        assertNotNull(ctx);
+        assertNotNull(props);
+        assertNotNull(container);
+        assertNotNull(ejb);
+        assertEquals("a b", ejb.concat("a", "b"));
+    }
+
+    @Test
+    public void checkAllIsFine() {
+        doChecks();
+    }
+
+    @Test
+    public void checkAllIsStillFine() {
+        doChecks();
+    }
+}

Added: tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleWithProgramaticInjection.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleWithProgramaticInjection.java?rev=1588792&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleWithProgramaticInjection.java (added)
+++ tomee/tomee/trunk/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEJBContainerRuleWithProgramaticInjection.java Sun Apr 20 16:47:21 2014
@@ -0,0 +1,72 @@
+/**
+ * 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.junit;
+
+import org.apache.openejb.config.DeploymentFilterable;
+import org.apache.openejb.junit.ejbs.BasicEjbLocal;
+import org.apache.openejb.junit.jee.EJBContainerRule;
+import org.apache.openejb.junit.jee.config.Properties;
+import org.apache.openejb.junit.jee.config.Property;
+import org.junit.ClassRule;
+import org.junit.Test;
+
+import javax.ejb.EJB;
+import javax.ejb.embeddable.EJBContainer;
+import javax.naming.Context;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@Properties({
+        // FallbackPropertyInjector for ejb to test config
+        @Property(key = DeploymentFilterable.CLASSPATH_EXCLUDE, value = "jar:.*")
+})
+public class TestEJBContainerRuleWithProgramaticInjection {
+    @ClassRule
+    public static final EJBContainerRule CONTAINER_RULE = new EJBContainerRule();
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private Context ctx;
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private java.util.Properties props;
+
+    @org.apache.openejb.junit.jee.resources.TestResource
+    private EJBContainer container;
+
+    @EJB
+    private BasicEjbLocal ejb;
+
+    private void doChecks() {
+        CONTAINER_RULE.inject(this);
+        assertNotNull(ctx);
+        assertNotNull(props);
+        assertNotNull(container);
+        assertNotNull(ejb);
+        assertEquals("a b", ejb.concat("a", "b"));
+    }
+
+    @Test
+    public void checkAllIsFine() {
+        doChecks();
+    }
+
+    @Test
+    public void checkAllIsStillFine() {
+        doChecks();
+    }
+}