You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by rm...@apache.org on 2016/12/22 10:04:12 UTC

svn commit: r1775602 - in /openwebbeans/meecrowave/trunk: ./ meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/ meecrowave-core/src/test/java/org/apache/meecrowave/ meecrowave-doc/src/main/jbake/content/ meecrowave-doc/src/main/jbake/con...

Author: rmannibucau
Date: Thu Dec 22 10:04:12 2016
New Revision: 1775602

URL: http://svn.apache.org/viewvc?rev=1775602&view=rev
Log:
adding jta module

Added:
    openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ConfigInjection.java
      - copied, changed from r1775290, openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/MultipartTest.java
    openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-jta/
    openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-jta/index.adoc
      - copied, changed from r1775290, openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-maven/index.adoc
    openwebbeans/meecrowave/trunk/meecrowave-jta/
    openwebbeans/meecrowave/trunk/meecrowave-jta/pom.xml
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/AnyLiteral.java
      - copied, changed from r1775290, openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/DefaultLiteral.java
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/InterceptorBase.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/JtaExtension.java
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/MandatoryInterceptor.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NeverInterceptor.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NotSupportedInterceptor.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredInterceptor.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredNewInterceptor.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/SupportsInterceptor.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/TransactionContext.java   (with props)
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/services/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/RequiredInterceptorTest.java
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/ScopeTest.java
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/META-INF/
    openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/META-INF/beans.xml
Modified:
    openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java
    openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/components.adoc
    openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java
    openwebbeans/meecrowave/trunk/pom.xml

Modified: openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java?rev=1775602&r1=1775601&r2=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java (original)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java Thu Dec 22 10:04:12 2016
@@ -19,18 +19,31 @@
 package org.apache.meecrowave.openwebbeans;
 
 import org.apache.meecrowave.Meecrowave;
+import org.apache.webbeans.annotation.AnyLiteral;
+import org.apache.webbeans.annotation.DefaultLiteral;
+import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.servlet.WebBeansConfigurationListener;
 import org.apache.webbeans.web.context.WebConversationFilter;
 
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
 import javax.servlet.DispatcherType;
 import javax.servlet.FilterRegistration;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.Set;
 
+import static java.util.Arrays.asList;
+
 public class OWBAutoSetup implements ServletContainerInitializer {
     @Override
     public void onStartup(final Set<Class<?>> c, final ServletContext ctx) throws ServletException {
@@ -41,19 +54,95 @@ public class OWBAutoSetup implements Ser
         }
 
         // eager boot to let injections work in listeners
-        final EagerBootListener bootListener = new EagerBootListener();
+        final EagerBootListener bootListener = new EagerBootListener(builder);
         bootListener.doContextInitialized(new ServletContextEvent(ctx));
         ctx.addListener(bootListener);
     }
 
     public static class EagerBootListener extends WebBeansConfigurationListener {
+        private final Meecrowave.Builder config;
+
+        private EagerBootListener(final Meecrowave.Builder builder) {
+            this.config = builder;
+        }
+
         @Override
         public void contextInitialized(final ServletContextEvent event) {
             // skip
         }
 
         private void doContextInitialized(final ServletContextEvent event) {
+            try {
+                WebBeansContext.getInstance().getBeanManagerImpl().addInternalBean(new ConfigBean(config));
+            } catch (final IllegalStateException ise) {
+                // lifecycle not supporting it
+            }
             super.contextInitialized(event);
         }
+
+        private static class ConfigBean implements Bean<Meecrowave.Builder> {
+            private final Meecrowave.Builder value;
+            private final Set<Type> types = new HashSet<>(asList(Meecrowave.Builder.class, Object.class));
+            private final Set<Annotation> qualifiers = new HashSet<>(asList(DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE));
+
+            private ConfigBean(final Meecrowave.Builder config) {
+                this.value = config;
+            }
+
+            @Override
+            public Set<InjectionPoint> getInjectionPoints() {
+                return Collections.emptySet();
+            }
+
+            @Override
+            public Class<?> getBeanClass() {
+                return Meecrowave.Builder.class;
+            }
+
+            @Override
+            public boolean isNullable() {
+                return false;
+            }
+
+            @Override
+            public Meecrowave.Builder create(final CreationalContext<Meecrowave.Builder> context) {
+                return value;
+            }
+
+            @Override
+            public void destroy(final Meecrowave.Builder instance, final CreationalContext<Meecrowave.Builder> context) {
+
+            }
+
+            @Override
+            public Set<Type> getTypes() {
+                return types;
+            }
+
+            @Override
+            public Set<Annotation> getQualifiers() {
+                return qualifiers;
+            }
+
+            @Override
+            public Class<? extends Annotation> getScope() {
+                return ApplicationScoped.class;
+            }
+
+            @Override
+            public String getName() {
+                return null;
+            }
+
+            @Override
+            public Set<Class<? extends Annotation>> getStereotypes() {
+                return Collections.emptySet();
+            }
+
+            @Override
+            public boolean isAlternative() {
+                return false;
+            }
+        }
     }
 }

Copied: openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ConfigInjection.java (from r1775290, openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/MultipartTest.java)
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ConfigInjection.java?p2=openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ConfigInjection.java&p1=openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/MultipartTest.java&r1=1775290&r2=1775602&rev=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/MultipartTest.java (original)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ConfigInjection.java Thu Dec 22 10:04:12 2016
@@ -18,63 +18,28 @@
  */
 package org.apache.meecrowave;
 
-import org.apache.johnzon.mapper.reflection.JohnzonParameterizedType;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.inject.OWBInjector;
 import org.junit.Test;
 
-import javax.enterprise.context.ApplicationScoped;
-import javax.json.bind.annotation.JsonbProperty;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.client.Client;
-import javax.ws.rs.client.ClientBuilder;
-import javax.ws.rs.core.GenericType;
-import javax.ws.rs.core.MediaType;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import javax.inject.Inject;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class ConfigInjection {
+    @Inject
+    private Meecrowave.Builder builder;
 
-// just a sample using multiparts
-public class MultipartTest {
     @Test
-    public void configBinding() {
+    public void inject() {
         try (final Meecrowave meecrowave = new Meecrowave(
                 new Meecrowave.Builder()
                         .randomHttpPort()
-                        .includePackages(MultipartTest.MultiEndpoint.class.getName())).bake()) {
-            final Client client = ClientBuilder.newClient();
-            try {
-                // for mixed types use org.apache.cxf.jaxrs.ext.multipart.MultipartBody
-                final Map<String, JsonbModel> response = client.target("http://localhost:" + meecrowave.getConfiguration().getHttpPort() + "/MultipartTest")
-                        .request()
-                        .get(new GenericType<Map<String, JsonbModel>>(new JohnzonParameterizedType(Map.class, String.class, JsonbModel.class)) {{}});
-                assertEquals(1, response.size());
-                assertEquals("ok", response.get(MediaType.APPLICATION_JSON).value);
-            } finally {
-                client.close();
-            }
-        }
-    }
-
-    @ApplicationScoped
-    @Path("MultipartTest")
-    public static class MultiEndpoint {
-        @Produces("multipart/mixed")
-        @GET
-        public Map<String, Object> getBooks() {
-            final JsonbModel jsonbModel = new JsonbModel();
-            jsonbModel.value = "ok";
-
-            final Map<String, Object> map = new LinkedHashMap<>();
-            map.put("application/json", jsonbModel);
-
-            return map;
+                        .includePackages(ConfigInjection.class.getName())).bake()) {
+            OWBInjector.inject(WebBeansContext.currentInstance().getBeanManagerImpl(), this, null);
+            assertNotNull(builder);
+            assertEquals(ConfigInjection.class.getName(), builder.getScanningPackageIncludes());
         }
     }
-
-    public static class JsonbModel {
-        @JsonbProperty("test")
-        public String value;
-    }
 }

Modified: openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/components.adoc
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/components.adoc?rev=1775602&r1=1775601&r2=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/components.adoc (original)
+++ openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/components.adoc Thu Dec 22 10:04:12 2016
@@ -48,6 +48,12 @@ Meecrowave provides few integration for
 
 link:{context_rootpath}/meecrowave-jolokia/index.html[Jolokia (JMX)]
 
+== Meecrowave and JTA
+
+This is an experimental integration of geronimo-transaction and meecrowave.
+
+link:{context_rootpath}/meecrowave-jta/index.html[JTA module]
+
 == Going further
 
 Meecrowave scope is not the full scope of microservices (whatever it means) or at least enterprise needs

Copied: openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-jta/index.adoc (from r1775290, openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-maven/index.adoc)
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-jta/index.adoc?p2=openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-jta/index.adoc&p1=openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-maven/index.adoc&r1=1775290&r2=1775602&rev=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-maven/index.adoc (original)
+++ openwebbeans/meecrowave/trunk/meecrowave-doc/src/main/jbake/content/meecrowave-jta/index.adoc Thu Dec 22 10:04:12 2016
@@ -1,5 +1,5 @@
-= Meecrowave Maven
-:jbake-date: 2016-10-24
+= Meecrowave JTA
+:jbake-date: 2016-12-22
 :jbake-type: page
 :jbake-status: published
 :jbake-meecrowavepdf:
@@ -11,15 +11,11 @@ Coordinates:
 
 [source,xml]
 ----
-<plugin>
+<dependency>
   <groupId>org.apache.meecrowave</groupId>
-  <artifactId>meecrowave-maven-plugin</artifactId>
+  <artifactId>meecrowave-jta</artifactId>
   <version>${meecrowave.version}</version>
-</plugin>
+</dependency>
 ----
 
-TIP: most of the configuration is inherited from meecrowave-core.
-
-Here are the available options (see core configuration for the details):
-
-include::../../../../../target/generated-doc/MavenConfiguration.adoc[]
+This allows to use `@Transactional` and `@TransactionScoped` features of JTA 1.2.

Modified: openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java?rev=1775602&r1=1775601&r2=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java (original)
+++ openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java Thu Dec 22 10:04:12 2016
@@ -43,6 +43,7 @@ public class PersistenceUnitInfoBuilder
     private String unitName;
     private String providerClass;
     private DataSource dataSource;
+    private DataSource jtaDataSource;
     private List<String> mappingFiles = emptyList();
     private List<URL> jarFiles = emptyList();
     private URL rootUrl;
@@ -53,6 +54,16 @@ public class PersistenceUnitInfoBuilder
     private Properties properties = new Properties();
     private String version = "2.0";
     private ClassLoader loader = Thread.currentThread().getContextClassLoader();
+    private PersistenceUnitTransactionType transactionType = RESOURCE_LOCAL;
+
+    public PersistenceUnitTransactionType getTransactionType() {
+        return transactionType;
+    }
+
+    public PersistenceUnitInfoBuilder setTransactionType(final PersistenceUnitTransactionType transactionType) {
+        this.transactionType = transactionType;
+        return this;
+    }
 
     public String getUnitName() {
         return unitName;
@@ -72,6 +83,15 @@ public class PersistenceUnitInfoBuilder
         return this;
     }
 
+    public DataSource getJtaDataSource() {
+        return jtaDataSource;
+    }
+
+    public PersistenceUnitInfoBuilder setJtaDataSource(final DataSource jtaDataSource) {
+        this.jtaDataSource = jtaDataSource;
+        return this;
+    }
+
     public DataSource getDataSource() {
         return dataSource;
     }
@@ -207,12 +227,12 @@ public class PersistenceUnitInfoBuilder
 
             @Override
             public PersistenceUnitTransactionType getTransactionType() {
-                return RESOURCE_LOCAL;
+                return transactionType;
             }
 
             @Override
             public DataSource getJtaDataSource() {
-                return null;
+                return jtaDataSource;
             }
 
             @Override

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/pom.xml
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/pom.xml?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/pom.xml (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/pom.xml Thu Dec 22 10:04:12 2016
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="
+            http://maven.apache.org/POM/4.0.0
+            http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>meecrowave</artifactId>
+    <groupId>org.apache.meecrowave</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>meecrowave-jta</artifactId>
+  <name>Meecrowave :: JTA</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jta_1.2_spec</artifactId>
+      <version>1.0-alpha-1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.geronimo.components</groupId>
+      <artifactId>geronimo-transaction</artifactId>
+      <version>3.1.4</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.22</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-slf4j-impl</artifactId>
+      <version>${log4j2.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.meecrowave</groupId>
+      <artifactId>meecrowave-core</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.meecrowave</groupId>
+      <artifactId>meecrowave-junit</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junit.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

Copied: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/AnyLiteral.java (from r1775290, openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java)
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/AnyLiteral.java?p2=openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/AnyLiteral.java&p1=openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java&r1=1775290&r2=1775602&rev=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java (original)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/AnyLiteral.java Thu Dec 22 10:04:12 2016
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.meecrowave.jpa.internal;
+package org.apache.meecrowave.jta;
 
 import javax.enterprise.inject.Any;
 import javax.enterprise.util.AnnotationLiteral;

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/DefaultLiteral.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/DefaultLiteral.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/DefaultLiteral.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/DefaultLiteral.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,51 @@
+/*
+ * 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 Default
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.meecrowave.jta;
+
+import javax.enterprise.inject.Default;
+import javax.enterprise.util.AnnotationLiteral;
+import java.lang.annotation.Annotation;
+
+public class DefaultLiteral extends AnnotationLiteral<Default> implements Default {
+    public static final DefaultLiteral INSTANCE = new DefaultLiteral();
+
+    private static final String TOSTRING = "@javax.enterprise.inject.Default()";
+    private static final long serialVersionUID = -8922048102786275371L;
+
+    @Override
+    public Class<? extends Annotation> annotationType() {
+        return Default.class;
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        return Default.class.isInstance(other)
+                || (AnnotationLiteral.class.isInstance(other) && AnnotationLiteral.class.cast(other).annotationType() == annotationType());
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return TOSTRING;
+    }
+}

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/InterceptorBase.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/InterceptorBase.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/InterceptorBase.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/InterceptorBase.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,256 @@
+/*
+ * 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.meecrowave.jta;
+
+import org.apache.meecrowave.Meecrowave;
+import org.apache.meecrowave.runner.cli.CliOption;
+
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.CDI;
+import javax.inject.Inject;
+import javax.interceptor.InvocationContext;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionRolledbackException;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static java.util.Arrays.asList;
+
+public abstract class InterceptorBase implements Serializable {
+    private static final IllegalStateException ILLEGAL_STATE_EXCEPTION = new IllegalStateException("Can't use UserTransaction from @Transaction call");
+    private static final ThreadLocal<RuntimeException> ERROR = new ThreadLocal<>();
+
+    private transient volatile ConcurrentMap<Method, Boolean> rollback = new ConcurrentHashMap<>();
+
+    @Inject
+    private Meecrowave.Builder config;
+
+    @Inject
+    protected TransactionManager transactionManager;
+
+    protected Object intercept(final InvocationContext ic) throws Exception {
+        final boolean forbidsUt = doesForbidUtUsage();
+        final RuntimeException oldEx;
+        final IllegalStateException illegalStateException;
+        if (forbidsUt) {
+            illegalStateException = ILLEGAL_STATE_EXCEPTION;
+            oldEx = error(illegalStateException);
+        } else {
+            illegalStateException = null;
+            oldEx = null;
+        }
+
+        State state = null;
+        try {
+            state = start();
+            final Object proceed = ic.proceed();
+            commit(state); // force commit there to ensure we can catch synchro exceptions
+            return proceed;
+        } catch (final Exception e) {
+            if (illegalStateException == e) {
+                throw e;
+            }
+
+            Exception error = unwrap(e);
+            if (error != null && (!config.getExtension(Jta.class).isHandleExceptionOnlyForClient() || isNewTransaction(state))) {
+                final Method method = ic.getMethod();
+                if (rollback == null) {
+                    synchronized (this) {
+                        if (rollback == null) {
+                            rollback = new ConcurrentHashMap<>();
+                        }
+                    }
+                }
+                Boolean doRollback = rollback.get(method);
+                if (doRollback != null) {
+                    if (doRollback && isTransactionActive(state.current)) {
+                        setRollbackOnly();
+                    }
+                } else {
+                    // computed lazily but we could cache it later for sure if that's really a normal case
+                    final AnnotatedType<?> annotatedType = CDI.current().getBeanManager().createAnnotatedType(method.getDeclaringClass());
+                    Transactional tx = null;
+                    for (final AnnotatedMethod<?> m : annotatedType.getMethods()) {
+                        if (method.equals(m.getJavaMember())) {
+                            tx = m.getAnnotation(Transactional.class);
+                            break;
+                        }
+                    }
+                    if (tx == null) {
+                        tx = annotatedType.getAnnotation(Transactional.class);
+                    }
+                    if (tx != null) {
+                        doRollback = new ExceptionPriotiryRules(tx.rollbackOn(), tx.dontRollbackOn()).accept(error, method.getExceptionTypes());
+                        rollback.putIfAbsent(method, doRollback);
+                        if (doRollback && isTransactionActive(state.current)) {
+                            setRollbackOnly();
+                        }
+                    }
+                }
+            }
+            try {
+                commit(state);
+            } catch (final Exception ex) {
+                // no-op: swallow to keep the right exception
+                final Logger logger = Logger.getLogger(getClass().getName());
+                if (logger.isLoggable(Level.FINE)) {
+                    logger.fine("Swallowing: " + ex.getMessage());
+                }
+            }
+
+            throw new TransactionalException(e.getMessage(), error);
+        } finally {
+            if (forbidsUt) {
+                resetError(oldEx);
+            }
+        }
+    }
+
+    protected abstract boolean isNewTransaction(final State state);
+    protected abstract State start();
+    protected abstract void commit(final State state);
+
+    private void resetError(final RuntimeException oldEx) {
+        ERROR.set(oldEx);
+    }
+
+    protected void setRollbackOnly() throws SystemException {
+        transactionManager.setRollbackOnly();
+    }
+
+    public boolean isTransactionActive(final Transaction current) {
+        if (current == null) {
+            return false;
+        }
+
+        try {
+            final int status = current.getStatus();
+            return status == Status.STATUS_ACTIVE || status == Status.STATUS_MARKED_ROLLBACK;
+        } catch (final SystemException e) {
+            return false;
+        }
+    }
+
+
+    protected RuntimeException error(IllegalStateException illegalStateException) {
+        final RuntimeException p = ERROR.get();
+        ERROR.set(illegalStateException);
+        return p;
+    }
+
+    private Exception unwrap(final Exception e) {
+        Exception error = e;
+        while (error != null && (SystemException.class.isInstance(error) || TransactionRolledbackException.class.isInstance(error))) {
+            final Throwable cause = error.getCause();
+            if (cause == error) {
+                break;
+            }
+            error = Exception.class.isInstance(cause) ? Exception.class.cast(cause) : null;
+        }
+        if (RollbackException.class.isInstance(error) && Exception.class.isInstance(error.getCause())) {
+            error = Exception.class.cast(error.getCause());
+        }
+        return error;
+    }
+
+    protected boolean doesForbidUtUsage() {
+        return true;
+    }
+
+    private static final class ExceptionPriotiryRules {
+        private final Class<?>[] includes;
+        private final Class<?>[] excludes;
+
+        private ExceptionPriotiryRules(final Class<?>[] includes, final Class<?>[] excludes) {
+            this.includes = includes;
+            this.excludes = excludes;
+        }
+
+        private boolean accept(final Exception e, final Class<?>[] exceptionTypes) {
+            if (e == null) {
+                return false;
+            }
+
+            final int includeScore = contains(includes, e);
+            final int excludeScore = contains(excludes, e);
+
+            if (excludeScore < 0) {
+                return includeScore >= 0 || isNotChecked(e, exceptionTypes);
+            }
+            return includeScore - excludeScore >= 0;
+        }
+
+        private static int contains(final Class<?>[] list, final Exception e) {
+            int score = -1;
+            for (final Class<?> clazz : list) {
+                if (clazz.isInstance(e)) {
+                    final int thisScore = score(clazz, e.getClass());
+                    if (score < 0) {
+                        score = thisScore;
+                    } else {
+                        score = Math.min(thisScore, score);
+                    }
+                }
+            }
+            return score;
+        }
+
+        private static int score(final Class<?> config, final Class<?> ex) {
+            int score = 0;
+            Class<?> current = ex;
+            while (current != null && !current.equals(config)) {
+                score++;
+                current = current.getSuperclass();
+            }
+            return score;
+        }
+
+        private static boolean isNotChecked(final Exception e, final Class<?>[] exceptionTypes) {
+            return RuntimeException.class.isInstance(e) && (exceptionTypes.length == 0 || !asList(exceptionTypes).contains(e.getClass()));
+        }
+    }
+
+    public static class Jta {
+        @CliOption(name = "jta-handle-exception-only-for-client", description = "should JTA exception only be managed by client")
+        private boolean handleExceptionOnlyForClient;
+
+        public boolean isHandleExceptionOnlyForClient() {
+            return handleExceptionOnlyForClient;
+        }
+    }
+
+    protected static class State {
+        protected final Transaction old;
+        protected final Transaction current;
+
+        public State(final Transaction old, final Transaction current) {
+            this.old = old;
+            this.current = current;
+        }
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/InterceptorBase.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/JtaExtension.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/JtaExtension.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/JtaExtension.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/JtaExtension.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,159 @@
+/*
+ * 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.meecrowave.jta;
+
+import org.apache.geronimo.transaction.manager.GeronimoTransactionManager;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.ProcessBean;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.xa.XAException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+
+public class JtaExtension implements Extension {
+    private TransactionContext context;
+    private boolean hasManager;
+    private boolean hasRegistry;
+
+    void register(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager beanManager) {
+        Stream.of(
+                MandatoryInterceptor.class, NeverInterceptor.class,
+                NotSupportedInterceptor.class, RequiredInterceptor.class,
+                RequiredNewInterceptor.class, SupportsInterceptor.class)
+                .forEach(c -> beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(c)));
+    }
+
+    void findJtaComponents(@Observes final ProcessBean<?> bean) {
+        if (!hasManager && bean.getBean().getTypes().contains(TransactionManager.class)) {
+            hasManager = true;
+        }
+        if (!hasRegistry && bean.getBean().getTypes().contains(TransactionSynchronizationRegistry.class)) {
+            hasRegistry = true;
+        }
+    }
+
+    void addContext(@Observes final AfterBeanDiscovery afterBeanDiscovery) {
+        context = new TransactionContext();
+        afterBeanDiscovery.addContext(context);
+
+        if (!hasManager && !hasRegistry) {
+            try {
+                final GeronimoTransactionManager mgr = new GeronimoTransactionManager();
+                afterBeanDiscovery.addBean(new JtaBean(mgr));
+            } catch (final XAException e) {
+                throw new IllegalStateException(e);
+            }
+            hasManager = true;
+            hasRegistry = true;
+        }
+    }
+
+    void init(@Observes final AfterDeploymentValidation afterDeploymentValidation, final BeanManager bm) {
+        if (!hasRegistry && hasManager) {
+            afterDeploymentValidation.addDeploymentProblem(new IllegalStateException("You should produce a TransactionManager and TransactionSynchronizationRegistry"));
+        }
+        final TransactionManager manager = TransactionManager.class.cast(
+                bm.getReference(bm.resolve(bm.getBeans(TransactionManager.class)), TransactionManager.class, bm.createCreationalContext(null)));
+        final TransactionSynchronizationRegistry registry = TransactionSynchronizationRegistry.class.isInstance(manager) ?
+                TransactionSynchronizationRegistry.class.cast(manager) :
+                TransactionSynchronizationRegistry.class.cast(bm.getReference(bm.resolve(bm.getBeans(TransactionSynchronizationRegistry.class)),
+                        TransactionSynchronizationRegistry.class, bm.createCreationalContext(null)));
+        context.init(manager, registry);
+    }
+
+    private static class JtaBean implements Bean<TransactionManager> {
+        private final GeronimoTransactionManager manager;
+        private final Set<Type> types = new HashSet<>(asList(TransactionManager.class, TransactionSynchronizationRegistry.class, Object.class));
+        private final Set<Annotation> qualifiers = new HashSet<>(asList(DefaultLiteral.INSTANCE, AnyLiteral.INSTANCE));
+
+        private JtaBean(final GeronimoTransactionManager mgr) {
+            this.manager = mgr;
+        }
+
+        @Override
+        public Set<InjectionPoint> getInjectionPoints() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public Class<?> getBeanClass() {
+            return GeronimoTransactionManager.class;
+        }
+
+        @Override
+        public boolean isNullable() {
+            return false;
+        }
+
+        @Override
+        public TransactionManager create(final CreationalContext<TransactionManager> context) {
+            return manager;
+        }
+
+        @Override
+        public void destroy(final TransactionManager instance, final CreationalContext<TransactionManager> context) {
+            // no-op
+        }
+
+        @Override
+        public Set<Type> getTypes() {
+            return types;
+        }
+
+        @Override
+        public Set<Annotation> getQualifiers() {
+            return qualifiers;
+        }
+
+        @Override
+        public Class<? extends Annotation> getScope() {
+            return ApplicationScoped.class;
+        }
+
+        @Override
+        public String getName() {
+            return null;
+        }
+
+        @Override
+        public Set<Class<? extends Annotation>> getStereotypes() {
+            return Collections.emptySet();
+        }
+
+        @Override
+        public boolean isAlternative() {
+            return false;
+        }
+    }
+}

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/MandatoryInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/MandatoryInterceptor.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/MandatoryInterceptor.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/MandatoryInterceptor.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,56 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+
+@Interceptor
+@Transactional(Transactional.TxType.MANDATORY)
+@Priority(200)
+public class MandatoryInterceptor extends InterceptorBase {
+    @AroundInvoke
+    public Object intercept(final InvocationContext ic) throws Exception {
+        return super.intercept(ic);
+    }
+
+    @Override
+    protected boolean isNewTransaction(final State state) {
+        return false;
+    }
+
+    @Override
+    protected State start() {
+        try {
+            final Transaction transaction = transactionManager.getTransaction();
+            return new State(transaction, transaction);
+        } catch (final SystemException e) {
+            throw new TransactionalException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    protected void commit(final State state) {
+        // no-op
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/MandatoryInterceptor.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NeverInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NeverInterceptor.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NeverInterceptor.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NeverInterceptor.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,65 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.SystemException;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+
+@Interceptor
+@Transactional(Transactional.TxType.NEVER)
+@Priority(200)
+public class NeverInterceptor extends InterceptorBase {
+    private static final State STATE = new State(null, null);
+
+    @AroundInvoke
+    public Object intercept(final InvocationContext ic) throws Exception {
+        return super.intercept(ic);
+    }
+
+    @Override
+    protected boolean isNewTransaction(final State state) {
+        return false;
+    }
+
+    @Override
+    protected State start() {
+        try {
+            if (transactionManager.getTransaction() != null) {
+                throw new TransactionalException("@Transactional(NEVER) but a transaction is running", new IllegalStateException());
+            }
+            return STATE;
+        } catch (final SystemException e) {
+            throw new TransactionalException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    protected void commit(final State state) {
+        // no-op
+    }
+
+
+    @Override
+    protected boolean doesForbidUtUsage() {
+        return false;
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NeverInterceptor.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NotSupportedInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NotSupportedInterceptor.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NotSupportedInterceptor.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NotSupportedInterceptor.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,68 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+
+@Interceptor
+@Transactional(Transactional.TxType.NOT_SUPPORTED)
+@Priority(200)
+public class NotSupportedInterceptor extends InterceptorBase {
+    @AroundInvoke
+    public Object intercept(final InvocationContext ic) throws Exception {
+        return super.intercept(ic);
+    }
+
+    @Override
+    protected boolean isNewTransaction(final State state) {
+        return false;
+    }
+
+    @Override
+    protected State start() {
+        try {
+            final Transaction tx = transactionManager.getTransaction();
+            return new State(tx, null);
+        } catch (final SystemException e) {
+            throw new TransactionalException(e.getMessage(), e);
+        }
+    }
+
+    @Override
+    protected void commit(final State state) {
+        if (state.old != null) {
+            try {
+                transactionManager.resume(state.old);
+            } catch (final InvalidTransactionException | SystemException e) {
+                throw new TransactionalException(e.getMessage(), e);
+            }
+        }
+    }
+
+    @Override
+    protected boolean doesForbidUtUsage() {
+        return false;
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/NotSupportedInterceptor.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredInterceptor.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredInterceptor.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredInterceptor.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,73 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+
+@Interceptor
+@Transactional(Transactional.TxType.REQUIRED)
+@Priority(200)
+public class RequiredInterceptor extends InterceptorBase {
+    @AroundInvoke
+    public Object intercept(final InvocationContext ic) throws Exception {
+        return super.intercept(ic);
+    }
+
+    @Override
+    protected boolean isNewTransaction(final State state) {
+        return state.old == null;
+    }
+
+    @Override
+    protected State start() {
+        try {
+            final Transaction transaction = transactionManager.getTransaction();
+            final Transaction current;
+            if (transaction == null) {
+                transactionManager.begin();
+                current = transactionManager.getTransaction();
+            } else {
+                current = transaction;
+            }
+            return new State(transaction, current);
+        } catch (final SystemException | NotSupportedException se) {
+            throw new TransactionalException(se.getMessage(), se);
+        }
+    }
+
+    @Override
+    protected void commit(final State state) {
+        if (state.old != state.current) {
+            try {
+                state.current.commit();
+            } catch (final HeuristicMixedException | HeuristicRollbackException | RollbackException | SystemException e) {
+                throw new TransactionalException(e.getMessage(), e);
+            }
+        }
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredInterceptor.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredNewInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredNewInterceptor.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredNewInterceptor.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredNewInterceptor.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,78 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+
+@Interceptor
+@Transactional(Transactional.TxType.REQUIRES_NEW)
+@Priority(200)
+public class RequiredNewInterceptor extends InterceptorBase {
+    @AroundInvoke
+    public Object intercept(final InvocationContext ic) throws Exception {
+        return super.intercept(ic);
+    }
+
+    @Override
+    protected boolean isNewTransaction(final State state) {
+        return state.old == null;
+    }
+
+    @Override
+    protected State start() {
+        try {
+            final Transaction transaction = transactionManager.suspend();
+            transactionManager.begin();
+            return new State(transaction, transactionManager.getTransaction());
+        } catch (final SystemException | NotSupportedException se) {
+            throw new TransactionalException(se.getMessage(), se);
+        }
+    }
+
+    @Override
+    protected void commit(final State state) {
+        try {
+            if (state.old != state.current) {
+                try {
+                    state.current.commit();
+                } catch (final HeuristicMixedException | HeuristicRollbackException | RollbackException | SystemException e) {
+                    throw new TransactionalException(e.getMessage(), e);
+                }
+            }
+        } finally {
+            if (state.old != null) {
+                try {
+                    transactionManager.resume(state.old);
+                } catch (final InvalidTransactionException | SystemException e) {
+                    throw new TransactionalException(e.getMessage(), e);
+                }
+            }
+        }
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/RequiredNewInterceptor.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/SupportsInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/SupportsInterceptor.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/SupportsInterceptor.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/SupportsInterceptor.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,57 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.Transactional;
+import javax.transaction.TransactionalException;
+
+@Interceptor
+@Transactional(Transactional.TxType.SUPPORTS)
+@Priority(200)
+public class SupportsInterceptor extends InterceptorBase {
+    @AroundInvoke
+    public Object intercept(final InvocationContext ic) throws Exception {
+        return super.intercept(ic);
+    }
+
+    @Override
+    protected boolean isNewTransaction(final State state) {
+        return false;
+    }
+
+    @Override
+    protected State start() {
+        final Transaction transaction;
+        try {
+            transaction = transactionManager.getTransaction();
+        } catch (final SystemException e) {
+            throw new TransactionalException(e.getMessage(), e);
+        }
+        return new State(transaction, transaction);
+    }
+
+    @Override
+    protected void commit(final State state) {
+        // no-op
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/SupportsInterceptor.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/TransactionContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/TransactionContext.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/TransactionContext.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/TransactionContext.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,192 @@
+/*
+ * 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.meecrowave.jta;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.spi.AlterableContext;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionScoped;
+import javax.transaction.TransactionSynchronizationRegistry;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+public class TransactionContext implements AlterableContext, Synchronization {
+    private TransactionManager transactionManager;
+    private Map<Contextual<?>, BeanInstanceBag<?>> componentInstanceMap;
+
+    void init(final TransactionManager transactionManager, final TransactionSynchronizationRegistry transactionSynchronizationRegistry) {
+        this.transactionManager = transactionManager;
+        this.componentInstanceMap = Map.class.cast(Proxy.newProxyInstance(
+                Thread.currentThread().getContextClassLoader(), new Class<?>[]{Map.class},
+                new TransactionalMapHandler(this, transactionSynchronizationRegistry)));
+    }
+
+    @Override
+    public boolean isActive() {
+        try {
+            final int status = transactionManager.getTransaction().getStatus();
+            return status == Status.STATUS_ACTIVE || status == Status.STATUS_MARKED_ROLLBACK
+                    || status == Status.STATUS_PREPARED || status == Status.STATUS_PREPARING
+                    || status == Status.STATUS_COMMITTING || status == Status.STATUS_ROLLING_BACK
+                    || status == Status.STATUS_UNKNOWN;
+        } catch (final Throwable e) {
+            return false;
+        }
+    }
+
+    private void checkActive() {
+        if (!isActive()) {
+            throw new ContextNotActiveException("Context with scope annotation @" + getScope().getName() + " is not active");
+        }
+    }
+
+    private <T> BeanInstanceBag<T> createContextualBag(final Contextual<T> contextual, final CreationalContext<T> creationalContext) {
+        final BeanInstanceBag<T> bag = new BeanInstanceBag<>(creationalContext);
+        componentInstanceMap.put(contextual, bag);
+        return bag;
+    }
+
+    @Override
+    public <T> T get(final Contextual<T> component) {
+        checkActive();
+        final BeanInstanceBag bag = componentInstanceMap.get(component);
+        if (bag != null) {
+            return (T) bag.beanInstance;
+        }
+        return null;
+    }
+
+    @Override
+    public <T> T get(Contextual<T> contextual, CreationalContext<T> creationalContext) {
+        checkActive();
+
+        return getInstance(contextual, creationalContext);
+    }
+
+    private <T> T getInstance(final Contextual<T> contextual, final CreationalContext<T> creationalContext) {
+        T instance;
+        BeanInstanceBag<T> bag = (BeanInstanceBag<T>) componentInstanceMap.get(contextual);
+        if (bag == null) {
+            bag = createContextualBag(contextual, creationalContext);
+        }
+
+        instance = bag.beanInstance;
+        if (instance != null) {
+            return instance;
+        } else {
+            if (creationalContext == null) {
+                return null;
+            } else {
+                instance = bag.create(contextual);
+            }
+        }
+
+        return instance;
+    }
+
+    @Override
+    public void destroy(final Contextual<?> contextual) {
+        BeanInstanceBag<?> instance = componentInstanceMap.get(contextual);
+        if (instance == null) {
+            return;
+        }
+
+        CreationalContext<Object> cc = (CreationalContext<Object>) instance.beanCreationalContext;
+        final Object beanInstance = instance.beanInstance;
+        if (beanInstance != null) {
+            destroyInstance((Contextual<Object>) contextual, beanInstance, cc);
+        }
+    }
+
+    private <T> void destroyInstance(final Contextual<T> component, final T instance, final CreationalContext<T> creationalContext) {
+        //Destroy component
+        component.destroy(instance, creationalContext);
+        componentInstanceMap.remove(component);
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return TransactionScoped.class;
+    }
+
+    @Override
+    public void beforeCompletion() {
+        new HashSet<>(componentInstanceMap.keySet()).forEach(this::destroy);
+    }
+
+    @Override
+    public void afterCompletion(final int status) {
+        // no-op
+    }
+
+    private static final class TransactionalMapHandler implements InvocationHandler {
+        private static final String KEY = "@Transactional#meecrowave.map";
+        private final TransactionSynchronizationRegistry registry;
+        private final TransactionContext context;
+
+        private TransactionalMapHandler(final TransactionContext transactionContext, final TransactionSynchronizationRegistry registry) {
+            this.context = transactionContext;
+            this.registry = registry;
+        }
+
+        @Override
+        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+            try {
+                return method.invoke(findMap(), args);
+            } catch (final InvocationTargetException ite) {
+                throw ite.getCause();
+            }
+        }
+
+        private Map<Contextual<?>, BeanInstanceBag<?>> findMap() {
+            final Object resource = registry.getResource(KEY);
+            if (resource == null) {
+                final Map<Contextual<?>, BeanInstanceBag<?>> map = new HashMap<>();
+                registry.putResource(KEY, map);
+                registry.registerInterposedSynchronization(context);
+                return map;
+            }
+            return Map.class.cast(resource);
+        }
+    }
+
+    private static final class BeanInstanceBag<T> {
+        private final CreationalContext<T> beanCreationalContext;
+        private T beanInstance;
+
+        public BeanInstanceBag(CreationalContext<T> beanCreationalContext) {
+            this.beanCreationalContext = beanCreationalContext;
+        }
+
+        public T create(Contextual<T> contextual) {
+            if (beanInstance == null) {
+                beanInstance = contextual.create(beanCreationalContext);
+            }
+            return beanInstance;
+        }
+    }
+}

Propchange: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/java/org/apache/meecrowave/jta/TransactionContext.java
------------------------------------------------------------------------------
    svn:executable = *

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Thu Dec 22 10:04:12 2016
@@ -0,0 +1 @@
+org.apache.meecrowave.jta.JtaExtension

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/RequiredInterceptorTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/RequiredInterceptorTest.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/RequiredInterceptorTest.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/RequiredInterceptorTest.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,62 @@
+/*
+ * 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.meecrowave.jta;
+
+import org.apache.meecrowave.Meecrowave;
+import org.apache.meecrowave.junit.MeecrowaveRule;
+import org.junit.Rule;
+import org.junit.Test;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+import javax.transaction.Transactional;
+import java.io.IOException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+public class RequiredInterceptorTest {
+    @Rule
+    public final MeecrowaveRule rule = new MeecrowaveRule(
+            new Meecrowave.Builder().includePackages(RequiredInterceptorTest.class.getName()), "")
+            .inject(this);
+
+    @Inject
+    private Tx tx;
+
+    @Test
+    public void run() throws IOException {
+        tx.asserts();
+    }
+
+    @Transactional
+    @ApplicationScoped
+    public static class Tx {
+        @Inject
+        private TransactionManager manager;
+
+        public void asserts() {
+            try {
+                assertNotNull(manager.getTransaction());
+            } catch (final SystemException e) {
+                fail(e.getMessage());
+            }
+        }
+    }
+}

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/ScopeTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/ScopeTest.java?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/ScopeTest.java (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/java/org/apache/meecrowave/jta/ScopeTest.java Thu Dec 22 10:04:12 2016
@@ -0,0 +1,68 @@
+
+/*
+ * 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.meecrowave.jta;
+
+import org.apache.meecrowave.Meecrowave;
+import org.apache.meecrowave.junit.MeecrowaveRule;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.transaction.TransactionManager;
+import javax.transaction.TransactionScoped;
+import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class ScopeTest {
+    @Rule
+    public final MeecrowaveRule rule = new MeecrowaveRule(
+            new Meecrowave.Builder().includePackages(ScopeTest.class.getName()), "")
+            .inject(this);
+
+    @Inject
+    private Tx tx;
+
+    @Inject
+    private TransactionManager manager;
+
+    @Test
+    public void run() throws Exception {
+        manager.begin();
+        final AtomicBoolean ref = new AtomicBoolean();
+        tx.handle(ref);
+        Assert.assertFalse(ref.get());
+        manager.commit();
+        Assert.assertTrue(ref.get());
+    }
+
+    @TransactionScoped
+    public static class Tx implements Serializable {
+        private AtomicBoolean ref;
+
+        @PreDestroy
+        private void destroy() {
+            ref.set(true);
+        }
+
+        public void handle(final AtomicBoolean ref) {
+            this.ref = ref;
+        }
+    }
+}

Added: openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/META-INF/beans.xml
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/META-INF/beans.xml?rev=1775602&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/META-INF/beans.xml (added)
+++ openwebbeans/meecrowave/trunk/meecrowave-jta/src/test/resources/META-INF/beans.xml Thu Dec 22 10:04:12 2016
@@ -0,0 +1,19 @@
+<!--
+    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.
+-->
+<beans />

Modified: openwebbeans/meecrowave/trunk/pom.xml
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/pom.xml?rev=1775602&r1=1775601&r2=1775602&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/pom.xml (original)
+++ openwebbeans/meecrowave/trunk/pom.xml Thu Dec 22 10:04:12 2016
@@ -59,6 +59,7 @@
     <module>meecrowave-jpa</module>
     <module>meecrowave-jolokia</module>
     <module>meecrowave-doc</module>
+    <module>meecrowave-jta</module>
   </modules>
 
   <build>