From 0b830128540bf8aebf57e98ef4230c6ceb9d5f14 Mon Sep 17 00:00:00 2001 From: maxbruecken Date: Mon, 18 May 2015 22:10:51 +0200 Subject: [PATCH 1/3] ARIES-1324 --- .../container/BlueprintExtender.java | 2 +- blueprint/blueprint-itests/pom.xml | 12 +++++----- .../itests/BlueprintAnnotationTest.java | 22 +++++++++++++---- .../apache/aries/blueprint/itests/Helper.java | 4 ++-- blueprint/blueprint-sample-annotation/pom.xml | 2 +- .../blueprint/sample/TestXmlConfigBean.java | 17 +++++++++++++ .../resources/OSGI-INF/blueprint/config.xml | 24 +++++++++++++++++++ 7 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 blueprint/blueprint-sample-annotation/src/main/java/org/apache/aries/blueprint/sample/TestXmlConfigBean.java create mode 100644 blueprint/blueprint-sample-annotation/src/main/resources/OSGI-INF/blueprint/config.xml diff --git a/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java b/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java index e4deec43bc..bb9e220caf 100644 --- a/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java +++ b/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/BlueprintExtender.java @@ -378,7 +378,7 @@ private List getBlueprintPaths(Bundle bundle) { } } // Check annotations - if (pathList.isEmpty() && blueprintHeaderAnnotation != null && blueprintHeaderAnnotation.trim().equalsIgnoreCase("true")) { + if (blueprintHeaderAnnotation != null && blueprintHeaderAnnotation.trim().equalsIgnoreCase("true")) { LOGGER.debug("Scanning bundle {} for blueprint annotations", bundle.getSymbolicName()); ServiceReference sr = this.context.getServiceReference(BlueprintAnnotationScanner.class.getName()); if (sr != null) { diff --git a/blueprint/blueprint-itests/pom.xml b/blueprint/blueprint-itests/pom.xml index 5d5712e0f3..8c2fc0e121 100644 --- a/blueprint/blueprint-itests/pom.xml +++ b/blueprint/blueprint-itests/pom.xml @@ -208,18 +208,18 @@ org.apache.xbean - xbean-asm4-shaded - 3.16 + xbean-asm5-shaded + 3.18 org.apache.xbean xbean-bundleutils - 3.16 + 3.18 org.apache.xbean - xbean-finder-shaded - 3.16 + xbean-finder + 3.18 org.apache.aries.blueprint @@ -265,7 +265,7 @@ org.apache.aries.blueprint org.apache.aries.blueprint.sample-annotation - 1.0.0 + 1.1.0-SNAPSHOT test diff --git a/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java b/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java index 81d2d61160..14cbf21a80 100644 --- a/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java +++ b/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/BlueprintAnnotationTest.java @@ -30,6 +30,7 @@ import org.apache.aries.blueprint.sample.Bar; import org.apache.aries.blueprint.sample.Foo; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; @@ -41,12 +42,16 @@ @RunWith(PaxExam.class) public class BlueprintAnnotationTest extends AbstractBlueprintIntegrationTest { + private BlueprintContainer blueprintContainer; + + @Before + public void setUp() throws InvalidSyntaxException, InterruptedException { + blueprintContainer = getBlueprintContainerForBundle("org.apache.aries.blueprint.sample-annotation"); + assertNotNull(blueprintContainer); + } + @Test public void test() throws Exception { - BlueprintContainer blueprintContainer = getBlueprintContainerForBundle("org.apache.aries.blueprint.sample-annotation"); - - assertNotNull(blueprintContainer); - Object obj = blueprintContainer.getComponentInstance("bar"); assertNotNull(obj); assertEquals(Bar.class, obj.getClass()); @@ -69,11 +74,18 @@ public void test() throws Exception { assertNotNull(blueprintContainer.getComponentInstance("fragment")); - obj = context().getService(Foo.class, null, 5000); + obj = context().getService(Foo.class, "(blueprint.annotation.sample=true)", 5000); assertNotNull(obj); assertEquals(foo.toString(), obj.toString()); } + @Test + public void testXmlConfig() { + Object obj = blueprintContainer.getComponentInstance("testXmlConfigBean"); + assertNotNull(obj); + assertEquals("org.apache.aries.blueprint.sample.TestXmlConfigBean", obj.getClass().getName()); + } + private BlueprintContainer getBlueprintContainerForBundle(String symbolicName) throws InvalidSyntaxException, InterruptedException { return context().getService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=" + symbolicName + ")", 15000); } diff --git a/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/Helper.java b/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/Helper.java index 516e641b70..22f00c1ed8 100644 --- a/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/Helper.java +++ b/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/Helper.java @@ -71,9 +71,9 @@ public static Option blueprintBundles(boolean startBlueprint) { mvnBundle("org.apache.aries.proxy", "org.apache.aries.proxy.impl"), mvnBundle("org.apache.commons", "commons-jexl"), mvnBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.jexl.evaluator"), - mvnBundle("org.apache.xbean", "xbean-asm4-shaded"), + mvnBundle("org.apache.xbean", "xbean-asm5-shaded"), mvnBundle("org.apache.xbean", "xbean-bundleutils"), - mvnBundle("org.apache.xbean", "xbean-finder-shaded"), + mvnBundle("org.apache.xbean", "xbean-finder"), mvnBundle("org.apache.aries.quiesce", "org.apache.aries.quiesce.api", startBlueprint), mvnBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.api", startBlueprint), mvnBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.core", startBlueprint), diff --git a/blueprint/blueprint-sample-annotation/pom.xml b/blueprint/blueprint-sample-annotation/pom.xml index 5ed0fb5ce8..c7f258df77 100644 --- a/blueprint/blueprint-sample-annotation/pom.xml +++ b/blueprint/blueprint-sample-annotation/pom.xml @@ -31,7 +31,7 @@ org.apache.aries.blueprint org.apache.aries.blueprint.sample-annotation Apache Aries Blueprint Sample for Testing Annotation - 1.0.1-SNAPSHOT + 1.1.0-SNAPSHOT bundle Example blueprint application, mostly used for annotation tests. diff --git a/blueprint/blueprint-sample-annotation/src/main/java/org/apache/aries/blueprint/sample/TestXmlConfigBean.java b/blueprint/blueprint-sample-annotation/src/main/java/org/apache/aries/blueprint/sample/TestXmlConfigBean.java new file mode 100644 index 0000000000..333d9adfe3 --- /dev/null +++ b/blueprint/blueprint-sample-annotation/src/main/java/org/apache/aries/blueprint/sample/TestXmlConfigBean.java @@ -0,0 +1,17 @@ +package org.apache.aries.blueprint.sample; + +/** + * Created by Maxim Becker on 12.04.15. + */ +public class TestXmlConfigBean { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/blueprint/blueprint-sample-annotation/src/main/resources/OSGI-INF/blueprint/config.xml b/blueprint/blueprint-sample-annotation/src/main/resources/OSGI-INF/blueprint/config.xml new file mode 100644 index 0000000000..ae4674b192 --- /dev/null +++ b/blueprint/blueprint-sample-annotation/src/main/resources/OSGI-INF/blueprint/config.xml @@ -0,0 +1,24 @@ + + + + + + + + + From 8d096564d9e57a002f55645219d8914b13925f0c Mon Sep 17 00:00:00 2001 From: maxbruecken Date: Tue, 2 Jun 2015 21:43:03 +0200 Subject: [PATCH 2/3] ARIES-628 --- .../transaction/parsing/AnnotationParser.java | 2 +- .../parsing/TxNamespaceHandler.java | 26 +++-- ...nnotationEnablingNameSpaceHandlerTest.java | 24 ++--- .../MandatoryAnnotatedTranAttributeTest.java | 94 +++++++++++++++++++ transaction/transaction-testbundle/pom.xml | 9 ++ .../test/impl/AnnotatedTestBeanImpl.java | 36 +++++++ .../resources/OSGI-INF/blueprint/config.xml | 19 +++- 7 files changed, 189 insertions(+), 21 deletions(-) create mode 100644 transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryAnnotatedTranAttributeTest.java create mode 100644 transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/AnnotatedTestBeanImpl.java diff --git a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java index 2062ff6488..ac97fbae63 100644 --- a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java +++ b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java @@ -48,7 +48,7 @@ public void afterDestroy(Object arg0, String arg1) { } public Object afterInit(Object arg0, String arg1, BeanCreator arg2, BeanMetadata arg3) { - return null; + return arg0; } public void beforeDestroy(Object arg0, String arg1) { diff --git a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/TxNamespaceHandler.java b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/TxNamespaceHandler.java index 4744fb8694..d5c2bd7bb7 100644 --- a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/TxNamespaceHandler.java +++ b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/TxNamespaceHandler.java @@ -36,6 +36,7 @@ import org.apache.aries.blueprint.NamespaceHandler; import org.apache.aries.blueprint.ParserContext; import org.apache.aries.blueprint.PassThroughMetadata; +import org.apache.aries.blueprint.mutable.MutableBeanMetadata; import org.apache.aries.blueprint.mutable.MutablePassThroughMetadata; import org.apache.aries.transaction.BundleWideTxData; import org.apache.aries.transaction.Constants; @@ -114,12 +115,25 @@ private void parseElement(Element elt, ComponentMetadata cm, ParserContext pc) Node n = elt.getChildNodes().item(0); if(n == null || Boolean.parseBoolean(n.getNodeValue())) { //We need to register a bean processor to add annotation-based config - if(!!!cdr.containsComponentDefinition(ANNOTATION_PARSER_BEAN_NAME)) { - - MutablePassThroughMetadata mptmd = pc.createMetadata(MutablePassThroughMetadata.class); - mptmd.setId(ANNOTATION_PARSER_BEAN_NAME); - mptmd.setObject(new AnnotationParser(cdr, interceptor, metaDataHelper)); - cdr.registerComponentDefinition(mptmd); + if (!cdr.containsComponentDefinition(ANNOTATION_PARSER_BEAN_NAME)) { + MutableBeanMetadata meta = pc.createMetadata(MutableBeanMetadata.class); + meta.setId(ANNOTATION_PARSER_BEAN_NAME); + meta.setRuntimeClass(AnnotationParser.class); + meta.setProcessor(true); + + MutablePassThroughMetadata cdrMeta = pc.createMetadata(MutablePassThroughMetadata.class); + cdrMeta.setObject(cdr); + meta.addArgument(cdrMeta, ComponentDefinitionRegistry.class.getName(), 0); + + MutablePassThroughMetadata interceptorMeta = pc.createMetadata(MutablePassThroughMetadata.class); + interceptorMeta.setObject(interceptor); + meta.addArgument(interceptorMeta, Interceptor.class.getName(), 1); + + MutablePassThroughMetadata helperMeta = pc.createMetadata(MutablePassThroughMetadata.class); + helperMeta.setObject(metaDataHelper); + meta.addArgument(helperMeta, TxComponentMetaDataHelper.class.getName(), 2); + + cdr.registerComponentDefinition(meta); } } } diff --git a/transaction/transaction-blueprint/src/test/java/org/apache/aries/transaction/AnnotationEnablingNameSpaceHandlerTest.java b/transaction/transaction-blueprint/src/test/java/org/apache/aries/transaction/AnnotationEnablingNameSpaceHandlerTest.java index b29d64a44c..f6b72e7271 100644 --- a/transaction/transaction-blueprint/src/test/java/org/apache/aries/transaction/AnnotationEnablingNameSpaceHandlerTest.java +++ b/transaction/transaction-blueprint/src/test/java/org/apache/aries/transaction/AnnotationEnablingNameSpaceHandlerTest.java @@ -24,12 +24,15 @@ import org.apache.aries.blueprint.ComponentDefinitionRegistry; import org.apache.aries.blueprint.PassThroughMetadata; +import org.apache.aries.blueprint.container.BeanRecipe; +import org.apache.aries.blueprint.container.BlueprintContainerImpl; import org.apache.aries.transaction.annotations.TransactionPropagationType; import org.apache.aries.transaction.parsing.AnnotationParser; import org.apache.aries.transaction.parsing.TxNamespaceHandler; import org.apache.aries.transaction.pojo.AnnotatedPojo; import org.junit.Test; import org.osgi.service.blueprint.reflect.BeanMetadata; +import org.osgi.service.blueprint.reflect.Metadata; public class AnnotationEnablingNameSpaceHandlerTest extends BaseNameSpaceHandlerSetup { @@ -43,16 +46,13 @@ public void testAnnotationEnabled() throws Exception assertNotNull(compTop); assertEquals(0, cdr.getInterceptors(compTop).size()); assertNull(txenhancer.getComponentMethodTxAttribute(compTop, "increment")); - - - PassThroughMetadata pmd = (PassThroughMetadata) cdr.getComponentDefinition(TxNamespaceHandler.ANNOTATION_PARSER_BEAN_NAME); + + BeanMetadata pmd = (BeanMetadata) cdr.getComponentDefinition(TxNamespaceHandler.ANNOTATION_PARSER_BEAN_NAME); assertNotNull(pmd); - - AnnotationParser parser = (AnnotationParser) pmd.getObject(); - parser.beforeInit(new AnnotatedPojo(), "top", null, compTop); - - assertEquals(TransactionPropagationType.Required, txenhancer.getComponentMethodTxAttribute(compTop, "increment")); - assertEquals(1, cdr.getInterceptors(compTop).size()); + + assertEquals(3, pmd.getArguments().size()); + assertEquals(cdr, ((PassThroughMetadata)pmd.getArguments().get(0).getValue()).getObject()); + assertEquals(txenhancer, ((PassThroughMetadata) pmd.getArguments().get(2).getValue()).getObject()); } @Test @@ -65,9 +65,9 @@ public void testAnnotationDisabled() throws Exception assertNotNull(compTop); assertEquals(0, cdr.getInterceptors(compTop).size()); assertNull(txenhancer.getComponentMethodTxAttribute(compTop, "increment")); - - - PassThroughMetadata pmd = (PassThroughMetadata) cdr.getComponentDefinition(TxNamespaceHandler.ANNOTATION_PARSER_BEAN_NAME); + + + BeanMetadata pmd = (BeanMetadata) cdr.getComponentDefinition(TxNamespaceHandler.ANNOTATION_PARSER_BEAN_NAME); assertNull(pmd); } } diff --git a/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryAnnotatedTranAttributeTest.java b/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryAnnotatedTranAttributeTest.java new file mode 100644 index 0000000000..686a40edb8 --- /dev/null +++ b/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryAnnotatedTranAttributeTest.java @@ -0,0 +1,94 @@ +/* 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.aries.transaction.itests; + +import org.apache.aries.transaction.test.TestBean; +import org.junit.Ignore; +import org.junit.Test; + +import javax.transaction.RollbackException; +import javax.transaction.UserTransaction; +import java.sql.SQLException; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class MandatoryAnnotatedTranAttributeTest extends AbstractIntegrationTest { + + @Test + public void testMandatory() throws Exception { + String prefix = "MTAT"; + TestBean bean = context().getService(TestBean.class, "(tranAttribute=MandatoryAnnotated)"); + UserTransaction tran = context().getService(UserTransaction.class); + + //Test with client transaction - the user transaction is used to insert a row + int initialRows = bean.countRows(); + + tran.begin(); + bean.insertRow(prefix + "testWithClientTran", 1); + tran.commit(); + + int finalRows = bean.countRows(); + assertTrue("Initial rows: " + initialRows + ", Final rows: " + finalRows, finalRows - initialRows == 1); + + //Test with client transaction and application exception - the user transaction is not rolled back + initialRows = bean.countRows(); + + tran.begin(); + bean.insertRow(prefix + "testWithClientTranAndWithAppException", 1); + + try { + bean.insertRow(prefix + "testWithClientTranAndWithAppException", 2, new SQLException("Dummy exception")); + } catch (SQLException e) { + e.printStackTrace(); + } + + tran.commit(); + + finalRows = bean.countRows(); + assertTrue("Initial rows: " + initialRows + ", Final rows: " + finalRows, finalRows - initialRows == 2); + + //Test with client transaction and runtime exception - the user transaction is rolled back + initialRows = bean.countRows(); + + tran.begin(); + bean.insertRow(prefix + "testWithClientTranAndWithRuntimeException", 1); + + try { + bean.insertRow(prefix + "testWithClientTranAndWithRuntimeException", 2, new RuntimeException("Dummy exception")); + } catch (RuntimeException e) { + e.printStackTrace(); + } + + try { + tran.commit(); + fail("RollbackException not thrown"); + } catch (RollbackException e) { + e.printStackTrace(); + } + + finalRows = bean.countRows(); + assertTrue("Initial rows: " + initialRows + ", Final rows: " + finalRows, finalRows - initialRows == 0); + + //Test without client transaction - an exception is thrown because a transaction is mandatory + try { + bean.insertRow(prefix + "testWithoutClientTran", 1); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + } +} diff --git a/transaction/transaction-testbundle/pom.xml b/transaction/transaction-testbundle/pom.xml index 04c60e3d0c..99b3283e84 100644 --- a/transaction/transaction-testbundle/pom.xml +++ b/transaction/transaction-testbundle/pom.xml @@ -51,4 +51,13 @@ + + + org.apache.aries.transaction + org.apache.aries.transaction.blueprint + provided + 1.0.3-SNAPSHOT + + + diff --git a/transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/AnnotatedTestBeanImpl.java b/transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/AnnotatedTestBeanImpl.java new file mode 100644 index 0000000000..a0e68978b6 --- /dev/null +++ b/transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/AnnotatedTestBeanImpl.java @@ -0,0 +1,36 @@ +package org.apache.aries.transaction.test.impl; + +import org.apache.aries.transaction.annotations.Transaction; +import org.apache.aries.transaction.annotations.TransactionPropagationType; + +import java.sql.SQLException; + +/** + * Created by Maxim Becker on 31.05.15. + */ +public class AnnotatedTestBeanImpl extends TestBeanImpl { + + @Override + @Transaction(TransactionPropagationType.Mandatory) + public void insertRow(String name, int value) throws SQLException { + super.insertRow(name, value); + } + + @Override + @Transaction(TransactionPropagationType.Mandatory) + public void insertRow(String name, int value, Exception e) throws SQLException { + super.insertRow(name, value, e); + } + + @Override + @Transaction(TransactionPropagationType.Mandatory) + public void insertRow(String name, int value, boolean delegate) throws SQLException { + super.insertRow(name, value, delegate); + } + + @Override + @Transaction(TransactionPropagationType.NotSupported) + public int countRows() throws SQLException { + return super.countRows(); + } +} diff --git a/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml b/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml index ec15d855ee..56e5e46237 100644 --- a/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml +++ b/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml @@ -20,9 +20,11 @@ + + @@ -122,7 +124,20 @@ - + + + + + + + + + + + + + + From 0294786d99d889a395affbef30d5ea182b6ad95d Mon Sep 17 00:00:00 2001 From: maxbruecken Date: Sun, 7 Jun 2015 13:28:24 +0200 Subject: [PATCH 3/3] ARIES-628: enable jta transactional annotation --- transaction/transaction-blueprint/pom.xml | 7 +- .../transaction/parsing/AnnotationParser.java | 63 +++++++++++-- .../itests/AbstractIntegrationTest.java | 5 + ...andatoryJtaAnnotatedTranAttributeTest.java | 93 +++++++++++++++++++ transaction/transaction-testbundle/pom.xml | 6 ++ .../test/impl/JtaAnnotatedTestBeanImpl.java | 34 +++++++ .../resources/OSGI-INF/blueprint/config.xml | 39 +++++--- 7 files changed, 226 insertions(+), 21 deletions(-) create mode 100644 transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryJtaAnnotatedTranAttributeTest.java create mode 100644 transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/JtaAnnotatedTestBeanImpl.java diff --git a/transaction/transaction-blueprint/pom.xml b/transaction/transaction-blueprint/pom.xml index ff4c56fa8a..4721afed4f 100644 --- a/transaction/transaction-blueprint/pom.xml +++ b/transaction/transaction-blueprint/pom.xml @@ -96,7 +96,12 @@ junit test - + + javax.transaction + javax.transaction-api + 1.2 + provided + diff --git a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java index ac97fbae63..8c5e153120 100644 --- a/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java +++ b/transaction/transaction-blueprint/src/main/java/org/apache/aries/transaction/parsing/AnnotationParser.java @@ -18,6 +18,7 @@ */ package org.apache.aries.transaction.parsing; +import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.apache.aries.blueprint.BeanProcessor; @@ -26,8 +27,11 @@ import org.apache.aries.transaction.Constants; import org.apache.aries.transaction.TxComponentMetaDataHelper; import org.apache.aries.transaction.annotations.Transaction; +import org.apache.aries.transaction.annotations.TransactionPropagationType; import org.osgi.service.blueprint.reflect.BeanMetadata; +import javax.transaction.Transactional; + /** * Adds the transactional interceptor if Transaction annotation is present * on bean class or superclasses. @@ -59,14 +63,20 @@ public Object beforeInit(Object bean, String beanName, BeanCreator beanCreator, boolean interceptorAssigned = isInterceptorAssigned(beanData); while (c != Object.class) { for (Method m : c.getDeclaredMethods()) { - Transaction t = m.getAnnotation(Transaction.class); - if (t != null && helper.getComponentMethodTxAttribute(beanData, m.getName()) == null) { - assertAllowedModifier(m); - helper.setComponentTransactionData(cdr, beanData, t.value(), m.getName()); - if (!interceptorAssigned) { - cdr.registerInterceptorWithComponent(beanData, interceptor); - interceptorAssigned = true; + try { + if (beanData != null && helper.getComponentMethodTxAttribute(beanData, m.getName()) == null) { + Transaction t = tryGetTransaction(m); + if (t != null) { + assertAllowedModifier(m); + helper.setComponentTransactionData(cdr, beanData, t.value(), m.getName()); + if (!interceptorAssigned) { + cdr.registerInterceptorWithComponent(beanData, interceptor); + interceptorAssigned = true; + } + } } + } catch(IllegalStateException e) { + // don't break bean creation due to invalid transaction attribute } } @@ -75,6 +85,45 @@ public Object beforeInit(Object bean, String beanName, BeanCreator beanCreator, return bean; } + private Transaction tryGetTransaction(Method m) { + Transaction t = m.getAnnotation(Transaction.class); + if (t == null) { + final Transactional jtaT = m.getAnnotation(Transactional.class); + if (jtaT != null) { + t = new Transaction() { + @Override + public Class annotationType() { + return Transactional.class; + } + + @Override + public TransactionPropagationType value() { + return convert(jtaT.value()); + } + }; + } + } + return t; + } + + private static TransactionPropagationType convert(Transactional.TxType type) { + switch(type) { + case MANDATORY: + return TransactionPropagationType.Mandatory; + case REQUIRED: + return TransactionPropagationType.Required; + case REQUIRES_NEW: + return TransactionPropagationType.RequiresNew; + case SUPPORTS: + return TransactionPropagationType.Supports; + case NOT_SUPPORTED: + return TransactionPropagationType.NotSupported; + case NEVER: + return TransactionPropagationType.Never; + } + throw new IllegalArgumentException(Constants.MESSAGES.getMessage("unknown.jta.transaction.type", type.name())); + } + private boolean isInterceptorAssigned(BeanMetadata beanData) { for (Interceptor i : cdr.getInterceptors(beanData)) { if (i == interceptor) { diff --git a/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java b/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java index e38c231e55..b0fa6d661b 100644 --- a/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java +++ b/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/AbstractIntegrationTest.java @@ -73,6 +73,11 @@ public Option[] configuration() { mavenBundle("org.apache.aries.blueprint", "org.apache.aries.blueprint.core"), mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy.api"), mavenBundle("org.apache.aries.proxy", "org.apache.aries.proxy.impl"), + mavenBundle("javax.interceptor", "javax.interceptor-api", "1.2"), + mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.javax-inject", "1_2"), + mavenBundle("javax.el", "javax.el-api", "3.0.0"), + mavenBundle("javax.enterprise", "cdi-api", "1.2"), + mavenBundle("javax.transaction", "javax.transaction-api", "1.2"), mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.manager").versionAsInProject(), mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.blueprint").versionAsInProject(), mavenBundle("org.apache.aries.transaction", "org.apache.aries.transaction.jdbc").versionAsInProject(), diff --git a/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryJtaAnnotatedTranAttributeTest.java b/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryJtaAnnotatedTranAttributeTest.java new file mode 100644 index 0000000000..d1ebe13cb2 --- /dev/null +++ b/transaction/transaction-itests/src/test/java/org/apache/aries/transaction/itests/MandatoryJtaAnnotatedTranAttributeTest.java @@ -0,0 +1,93 @@ +/* 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.aries.transaction.itests; + +import org.apache.aries.transaction.test.TestBean; +import org.junit.Test; + +import javax.transaction.RollbackException; +import javax.transaction.UserTransaction; +import java.sql.SQLException; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class MandatoryJtaAnnotatedTranAttributeTest extends AbstractIntegrationTest { + + @Test + public void testMandatory() throws Exception { + String prefix = "MTAT"; + TestBean bean = context().getService(TestBean.class, "(tranAttribute=MandatoryJtaAnnotated)"); + UserTransaction tran = context().getService(UserTransaction.class); + + //Test with client transaction - the user transaction is used to insert a row + int initialRows = bean.countRows(); + + tran.begin(); + bean.insertRow(prefix + "testWithClientTran", 1); + tran.commit(); + + int finalRows = bean.countRows(); + assertTrue("Initial rows: " + initialRows + ", Final rows: " + finalRows, finalRows - initialRows == 1); + + //Test with client transaction and application exception - the user transaction is not rolled back + initialRows = bean.countRows(); + + tran.begin(); + bean.insertRow(prefix + "testWithClientTranAndWithAppException", 1); + + try { + bean.insertRow(prefix + "testWithClientTranAndWithAppException", 2, new SQLException("Dummy exception")); + } catch (SQLException e) { + e.printStackTrace(); + } + + tran.commit(); + + finalRows = bean.countRows(); + assertTrue("Initial rows: " + initialRows + ", Final rows: " + finalRows, finalRows - initialRows == 2); + + //Test with client transaction and runtime exception - the user transaction is rolled back + initialRows = bean.countRows(); + + tran.begin(); + bean.insertRow(prefix + "testWithClientTranAndWithRuntimeException", 1); + + try { + bean.insertRow(prefix + "testWithClientTranAndWithRuntimeException", 2, new RuntimeException("Dummy exception")); + } catch (RuntimeException e) { + e.printStackTrace(); + } + + try { + tran.commit(); + fail("RollbackException not thrown"); + } catch (RollbackException e) { + e.printStackTrace(); + } + + finalRows = bean.countRows(); + assertTrue("Initial rows: " + initialRows + ", Final rows: " + finalRows, finalRows - initialRows == 0); + + //Test without client transaction - an exception is thrown because a transaction is mandatory + try { + bean.insertRow(prefix + "testWithoutClientTran", 1); + fail("IllegalStateException not thrown"); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + } +} diff --git a/transaction/transaction-testbundle/pom.xml b/transaction/transaction-testbundle/pom.xml index 99b3283e84..7a13b54f46 100644 --- a/transaction/transaction-testbundle/pom.xml +++ b/transaction/transaction-testbundle/pom.xml @@ -58,6 +58,12 @@ provided 1.0.3-SNAPSHOT + + javax.transaction + javax.transaction-api + 1.2 + provided + diff --git a/transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/JtaAnnotatedTestBeanImpl.java b/transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/JtaAnnotatedTestBeanImpl.java new file mode 100644 index 0000000000..6c346dfa87 --- /dev/null +++ b/transaction/transaction-testbundle/src/main/java/org/apache/aries/transaction/test/impl/JtaAnnotatedTestBeanImpl.java @@ -0,0 +1,34 @@ +package org.apache.aries.transaction.test.impl; + +import javax.transaction.Transactional; +import java.sql.SQLException; + +/** + * Created by Maxim Becker on 31.05.15. + */ +public class JtaAnnotatedTestBeanImpl extends TestBeanImpl { + + @Override + @Transactional(Transactional.TxType.MANDATORY) + public void insertRow(String name, int value) throws SQLException { + super.insertRow(name, value); + } + + @Override + @Transactional(Transactional.TxType.MANDATORY) + public void insertRow(String name, int value, Exception e) throws SQLException { + super.insertRow(name, value, e); + } + + @Override + @Transactional(Transactional.TxType.MANDATORY) + public void insertRow(String name, int value, boolean delegate) throws SQLException { + super.insertRow(name, value, delegate); + } + + @Override + @Transactional(Transactional.TxType.NOT_SUPPORTED) + public int countRows() throws SQLException { + return super.countRows(); + } +} diff --git a/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml b/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml index 56e5e46237..29dd6ce092 100644 --- a/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml +++ b/transaction/transaction-testbundle/src/main/resources/OSGI-INF/blueprint/config.xml @@ -125,24 +125,37 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + +