Merged latest trunk into subsystemsR6
git-svn-id: https://svn.apache.org/repos/asf/aries/branches/subsystemsR6@1653940 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Bean.java b/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Bean.java
index 446c3c4..9affbb7 100644
--- a/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Bean.java
+++ b/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Bean.java
@@ -18,6 +18,7 @@
*/
package org.apache.aries.blueprint.plugin.model;
+import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.SortedSet;
@@ -43,11 +44,11 @@
this.clazz = clazz;
this.id = getBeanName(clazz);
for (Method method : clazz.getDeclaredMethods()) {
- PostConstruct postConstruct = method.getAnnotation(PostConstruct.class);
+ PostConstruct postConstruct = getEffectiveAnnotation(method, PostConstruct.class);
if (postConstruct != null) {
this.initMethod = method.getName();
}
- PreDestroy preDestroy = method.getAnnotation(PreDestroy.class);
+ PreDestroy preDestroy = getEffectiveAnnotation(method, PreDestroy.class);
if (preDestroy != null) {
this.destroyMethod = method.getName();
}
@@ -104,6 +105,46 @@
private static String getBeanNameFromSimpleName(String name) {
return name.substring(0, 1).toLowerCase() + name.substring(1, name.length());
}
+
+ private static <T extends Annotation> T getEffectiveAnnotation(Method method, Class<T> annotationClass) {
+ final Class<?> methodClass = method.getDeclaringClass();
+ final String name = method.getName();
+ final Class<?>[] params = method.getParameterTypes();
+
+ // 1. Current class
+ final T rootAnnotation = method.getAnnotation(annotationClass);
+ if (rootAnnotation != null) {
+ return rootAnnotation;
+ }
+
+ // 2. Superclass
+ final Class<?> superclass = methodClass.getSuperclass();
+ if (superclass != null) {
+ final T annotation = getMethodAnnotation(superclass, name, params, annotationClass);
+ if (annotation != null)
+ return annotation;
+ }
+
+ // 3. Interfaces
+ for (final Class<?> intfs : methodClass.getInterfaces()) {
+ final T annotation = getMethodAnnotation(intfs, name, params, annotationClass);
+ if (annotation != null)
+ return annotation;
+ }
+
+ return null;
+ }
+
+ private static <T extends Annotation> T getMethodAnnotation(Class<?> searchClass, String name, Class<?>[] params,
+ Class<T> annotationClass) {
+ try {
+ Method method = searchClass.getMethod(name, params);
+ return getEffectiveAnnotation(method, annotationClass);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
public boolean matches(Class<?> destType, String destId) {
boolean assignable = destType.isAssignableFrom(this.clazz);
diff --git a/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Context.java b/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Context.java
index 41f410c..e7d6ca8 100644
--- a/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Context.java
+++ b/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Context.java
@@ -27,6 +27,7 @@
import javax.inject.Named;
import org.ops4j.pax.cdi.api.OsgiService;
+import org.springframework.beans.factory.annotation.Qualifier;
public class Context implements Matcher {
@@ -67,8 +68,7 @@
}
public Bean getMatching(Field field) {
- Named named = field.getAnnotation(Named.class);
- String destId = (named == null) ? null : named.value();
+ String destId = getDestinationId(field);
// TODO Replace loop by lookup
for (Bean bean : beans) {
if (bean.matches(field.getType(), destId)) {
@@ -83,6 +83,18 @@
return null;
}
+ private String getDestinationId(Field field) {
+ Named named = field.getAnnotation(Named.class);
+ if (named != null) {
+ return named.value();
+ }
+ Qualifier qualifier = field.getAnnotation(Qualifier.class);
+ if (qualifier != null) {
+ return qualifier.value();
+ }
+ return null;
+ }
+
public SortedSet<Bean> getBeans() {
return beans;
}
diff --git a/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Property.java b/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Property.java
index 891b273..fa13b02 100644
--- a/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Property.java
+++ b/blueprint/blueprint-maven-plugin/src/main/java/org/apache/aries/blueprint/plugin/model/Property.java
@@ -24,6 +24,7 @@
import javax.inject.Named;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
public class Property implements Comparable<Property> {
@@ -58,7 +59,14 @@
*/
private static String getRefName(Field field) {
Named named = field.getAnnotation(Named.class);
- return (named != null) ? named.value() : Bean.getBeanName(field.getType());
+ if (named != null) {
+ return named.value();
+ }
+ Qualifier qualifier = field.getAnnotation(Qualifier.class);
+ if (qualifier != null) {
+ return qualifier.value();
+ }
+ return Bean.getBeanName(field.getType());
}
private static boolean needsInject(Field field) {
diff --git a/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean1.java b/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean1.java
index 94a4683..fef16dd 100644
--- a/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean1.java
+++ b/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean1.java
@@ -18,8 +18,6 @@
*/
package org.apache.aries.blueprint.plugin.test;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
@@ -30,7 +28,7 @@
@Singleton
@Transactional(value=TxType.REQUIRED)
-public class MyBean1 {
+public class MyBean1 extends ParentBean {
@Autowired
ServiceA bean2;
@@ -38,14 +36,10 @@
@PersistenceUnit(unitName="person")
EntityManager em;
- @PostConstruct
public void init() {
-
}
- @PreDestroy
public void destroy() {
-
}
public void saveData() {
diff --git a/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean3.java b/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean3.java
index 2320b0a..0d3131e 100644
--- a/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean3.java
+++ b/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/MyBean3.java
@@ -22,6 +22,7 @@
import javax.inject.Named;
import javax.inject.Singleton;
+import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@@ -34,7 +35,7 @@
ServiceA serviceA1;
@Inject
- @Named("my2")
+ @Qualifier("my2")
ServiceA serviceA2;
@Inject
diff --git a/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/ParentBean.java b/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/ParentBean.java
new file mode 100644
index 0000000..d4a7775
--- /dev/null
+++ b/blueprint/blueprint-maven-plugin/src/test/java/org/apache/aries/blueprint/plugin/test/ParentBean.java
@@ -0,0 +1,33 @@
+/**
+ * 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.blueprint.plugin.test;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+public class ParentBean {
+
+ @PostConstruct
+ public void init() {
+ }
+
+ @PreDestroy
+ public void destroy() {
+ }
+}
diff --git a/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManagerHandler.java b/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManagerHandler.java
index 671aa46..7e94baf 100644
--- a/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManagerHandler.java
+++ b/jpa/jpa-container-context/src/main/java/org/apache/aries/jpa/container/context/transaction/impl/JTAEntityManagerHandler.java
@@ -97,17 +97,11 @@
*/
private EntityManager getPersistenceContext(boolean forceTransaction) {
if (forceTransaction) {
- EntityManager manager = activeManager.get();
- if (manager != null) {
- manager.clear();
- }
+ clearDetachedManager();
return reg.getCurrentPersistenceContext(emf, props, instanceCount, callback);
} else {
if (reg.isTransactionActive()) {
- EntityManager manager = activeManager.get();
- if (manager != null) {
- manager.clear();
- }
+ clearDetachedManager();
return reg.getCurrentPersistenceContext(emf, props, instanceCount, callback);
} else {
if (!!!reg.jtaIntegrationAvailable() && _logger.isDebugEnabled())
@@ -126,6 +120,13 @@
}
}
+ private void clearDetachedManager() {
+ EntityManager manager = activeManager.get();
+ if (manager != null) {
+ manager.clear();
+ }
+ }
+
/**
* Called reflectively by blueprint
*/
diff --git a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java
index 2ae9ca0..1bef6e5 100644
--- a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java
+++ b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/impl/EntityManagerFactoryManager.java
@@ -25,8 +25,15 @@
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
@@ -162,7 +169,17 @@
"org.osgi.service.jdbc.DataSourceFactory", this);
tracker.open();
}
- registerEntityManagerFactories();
+ ExecutorService executor = Executors.newSingleThreadExecutor();
+ Future<Void> result = executor.submit(new Callable<Void>() {
+
+ @Override
+ public Void call() throws InvalidPersistenceUnitException {
+ registerEntityManagerFactories();
+ return null;
+ }
+ });
+ executor.shutdown();
+ handleCreationResult(result);
break;
//Stopping means the EMFs should
case Bundle.STOPPING :
@@ -180,6 +197,22 @@
}
}
+ private void handleCreationResult(Future<Void> result) throws InvalidPersistenceUnitException {
+ try {
+ result.get(5000, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ _logger.warn(e.getMessage(), e);
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof InvalidPersistenceUnitException) {
+ throw (InvalidPersistenceUnitException) e.getCause();
+ } else if (e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException) e.getCause();
+ }
+ } catch (TimeoutException e) {
+ _logger.info("EntityManagerFactory creation takes long. Continuing in background", e);
+ }
+ }
+
/**
* Unregister all {@link EntityManagerFactory} services
*/
diff --git a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/EntityManagerProxyFactory.java b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/EntityManagerProxyFactory.java
index 8f7bd76..ed929ee 100644
--- a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/EntityManagerProxyFactory.java
+++ b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/EntityManagerProxyFactory.java
@@ -1,6 +1,7 @@
package org.apache.aries.jpa.container.quiesce.impl;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
@@ -35,7 +36,9 @@
new PersistenceException(NLS.MESSAGES.getMessage("wrong.JPA.version", new Object[]{
method.getName(), delegate
}), e);
- }
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ }
// This will only ever be called once, the second time there
// will be an IllegalStateException from the line above
diff --git a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceEMFHandler.java b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceEMFHandler.java
index 35e3ac1..928be3e 100644
--- a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceEMFHandler.java
+++ b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceEMFHandler.java
@@ -1,6 +1,7 @@
package org.apache.aries.jpa.container.quiesce.impl;
import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
@@ -59,7 +60,9 @@
new PersistenceException(NLS.MESSAGES.getMessage("wrong.JPA.version", new Object[]{
method.getName(), delegate
}), e);
- }
+ } catch (InvocationTargetException e) {
+ throw e.getCause();
+ }
// This will only ever be called once, the second time there
// will be an IllegalStateException from the line above
diff --git a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceParticipantImpl.java b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceParticipantImpl.java
index e95a1ff..37d6bdd 100644
--- a/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceParticipantImpl.java
+++ b/jpa/jpa-container/src/main/java/org/apache/aries/jpa/container/quiesce/impl/QuiesceParticipantImpl.java
@@ -110,6 +110,7 @@
private QuiesceHandler quiesceHandler;
private final BundleContext context;
+ @SuppressWarnings("rawtypes")
private ServiceRegistration quiesceReg;
/** Some events that we need to tidy up */
diff --git a/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java b/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java
index f62a971..fc049bf 100644
--- a/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java
+++ b/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java
@@ -134,9 +134,6 @@
public static final String OBJECTCLASS = PACKAGENAME;
public static final String SERVICE_OR_WILDCARD = "(" + OBJECTCLASS + "|[*])(?:;\\s*(?:" + PARAMETER + "))*";
- public static final String SUBSYSTEM_IMPORTEXPORTSERVICE = SERVICE_OR_WILDCARD + "(?:,\\s*(?:" + SERVICE_OR_WILDCARD + "))*";
- public static final String SUBSYSTEM_EXPORTSERVICE = SUBSYSTEM_IMPORTEXPORTSERVICE;
- public static final String SUBSYSTEM_IMPORTSERVICE = SUBSYSTEM_IMPORTEXPORTSERVICE;
public static final String RESOURCE = SYMBOLICNAME + "(?:;\\s*(?:" + PARAMETER + "))*";
public static final String PREFERRED_PROVIDER = RESOURCE + "(?:,\\s*(?:" + RESOURCE + "))*";
diff --git a/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java b/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java
index 875a135..65f9a5a 100644
--- a/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java
+++ b/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java
@@ -164,7 +164,7 @@
public static final String NAME = SubsystemConstants.SUBSYSTEM_EXPORTSERVICE;
- private static final Pattern PATTERN = Pattern.compile("(" + Grammar.SUBSYSTEM_EXPORTSERVICE + ")(?=,|\\z)");
+ private static final Pattern PATTERN = Pattern.compile("(" + Grammar.SERVICE_OR_WILDCARD + ")(?=,|\\z)");
private final Set<Clause> clauses = new HashSet<Clause>();
diff --git a/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java b/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java
index 137a0d6..4cfbfad 100644
--- a/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java
+++ b/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java
@@ -144,7 +144,7 @@
public static final String NAME = SubsystemConstants.SUBSYSTEM_IMPORTSERVICE;
- private static final Pattern PATTERN = Pattern.compile("(" + Grammar.SUBSYSTEM_IMPORTSERVICE + ")(?=,|\\z)");
+ private static final Pattern PATTERN = Pattern.compile("(" + Grammar.SERVICE_OR_WILDCARD + ")(?=,|\\z)");
private static Collection<Clause> processHeader(String header) {
Matcher matcher = PATTERN.matcher(header);
diff --git a/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF b/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF
index 6b01bf9..520e9eb 100644
--- a/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF
+++ b/subsystem/subsystem-itests/src/test/resources/composite2/OSGI-INF/SUBSYSTEM.MF
@@ -2,5 +2,5 @@
Subsystem-Type: osgi.subsystem.composite
Subsystem-Content: org.apache.aries.subsystem.itests.tb4;version="[1.0.0,1.0.0]"
Import-Package: org.osgi.framework,org.osgi.util.tracker
-Subsystem-ExportService: *;filter:="(test=tb4)"
-Subsystem-ImportService: *;filter:="(test=testCompositeServiceImports)"
+Subsystem-ExportService: does.not.exist; filter:="(a=b)",*;filter:="(test=tb4)", does.not.exist1; filter:="(q=g)"
+Subsystem-ImportService: does.not.exist; filter:="(a=b)",*;filter:="(test=testCompositeServiceImports)",does.not.exist1; filter:="(q=g)"
\ No newline at end of file
diff --git a/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/XADataSourceMCFFactory.java b/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/XADataSourceMCFFactory.java
index 3f49b2a..4006ba2 100644
--- a/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/XADataSourceMCFFactory.java
+++ b/transaction/transaction-jdbc/src/main/java/org/apache/aries/transaction/jdbc/internal/XADataSourceMCFFactory.java
@@ -25,11 +25,15 @@
import org.tranql.connector.jdbc.AbstractXADataSourceMCF;
import org.tranql.connector.jdbc.ConfigurableSQLStateExceptionSorter;
import org.tranql.connector.jdbc.KnownSQLStateExceptionSorter;
+import org.tranql.connector.jdbc.ManagedXAConnection;
import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionFactory;
import javax.resource.spi.ResourceAdapterInternalException;
import javax.resource.spi.TransactionSupport;
+import javax.security.auth.Subject;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
@@ -64,6 +68,26 @@
}
@Override
+ public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
+ CredentialExtractor credentialExtractor = new CredentialExtractor(subject, connectionRequestInfo, this);
+
+ XAConnection sqlConnection = getPhysicalConnection(credentialExtractor);
+ try {
+ return new ManagedXAConnection(this, sqlConnection, credentialExtractor, exceptionSorter) {
+ @Override
+ public void cleanup() throws ResourceException {
+ // ARIES-1279 - Transaction does not work on error SQLException
+ // that's why we don't call super.cleanup() which calls con.setAutocommit(true)
+ // super.cleanup();
+ dissociateConnections();
+ }
+ };
+ } catch (SQLException e) {
+ throw new ResourceAdapterInternalException("Could not set up ManagedXAConnection", e);
+ }
+ }
+
+ @Override
protected XAConnection getPhysicalConnection(CredentialExtractor credentialExtractor) throws ResourceException {
try {
String userName = credentialExtractor.getUserName();