You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2016/03/15 19:41:43 UTC

[2/3] tomee git commit: TOMEE-1735 starting JMS2 implementation

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEConnectionFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEConnectionFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEConnectionFactory.java
new file mode 100644
index 0000000..7bb6a52
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEConnectionFactory.java
@@ -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 ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ActiveMQConnection;
+import org.apache.activemq.ActiveMQSslConnectionFactory;
+import org.apache.activemq.management.JMSStatsImpl;
+import org.apache.activemq.transport.Transport;
+
+import javax.jms.JMSContext;
+
+public class TomEEConnectionFactory extends ActiveMQSslConnectionFactory {
+    @Override
+    protected ActiveMQConnection createActiveMQConnection(final Transport transport, final JMSStatsImpl stats) throws Exception {
+        return new TomEEConnection(transport, getClientIdGenerator(), getConnectionIdGenerator(), stats);
+    }
+
+    @Override
+    public JMSContext createContext() {
+        return new JMSContextImpl(this, -1, null, null, false);
+    }
+
+    @Override
+    public JMSContext createContext(final int sessionMode) {
+        return new JMSContextImpl(this, sessionMode, null, null, false);
+    }
+
+    @Override
+    public JMSContext createContext(final String userName, final String password) {
+        return new JMSContextImpl(this, -1, userName, password, false);
+    }
+
+    @Override
+    public JMSContext createContext(final String userName, final String password, final int sessionMode) {
+        return new JMSContextImpl(this, sessionMode, userName, password, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnection.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnection.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnection.java
new file mode 100644
index 0000000..4d7bb29
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnection.java
@@ -0,0 +1,60 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ActiveMQConnection;
+import org.apache.activemq.ra.ActiveMQConnectionRequestInfo;
+import org.apache.activemq.ra.ActiveMQManagedConnection;
+import org.apache.activemq.ra.ManagedConnectionProxy;
+
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.security.auth.Subject;
+import java.lang.reflect.Field;
+import java.util.Collection;
+
+public class TomEEManagedConnection extends ActiveMQManagedConnection {
+    private static final Field PROXY_CONNECTIONS_FIELD;
+
+    static {
+        try {
+            PROXY_CONNECTIONS_FIELD = ActiveMQManagedConnection.class.getDeclaredField("proxyConnections");
+        } catch (final NoSuchFieldException e) {
+            throw new IllegalStateException("Incompatible AMQ", e);
+        }
+        PROXY_CONNECTIONS_FIELD.setAccessible(true);
+    }
+
+    private final Collection<ManagedConnectionProxy> proxyConnections;
+
+    public TomEEManagedConnection(final Subject subject, final ActiveMQConnection physicalConnection,
+                                  final ActiveMQConnectionRequestInfo info) throws ResourceException {
+        super(subject, physicalConnection, info);
+        try {
+            proxyConnections = Collection.class.cast(PROXY_CONNECTIONS_FIELD.get(this));
+        } catch (final IllegalAccessException e) {
+            throw new IllegalStateException("Incompatible AMQ", e);
+        }
+    }
+
+    @Override
+    public Object getConnection(final Subject subject, final ConnectionRequestInfo info) throws ResourceException {
+        final ManagedConnectionProxy proxy = new TomEEManagedConnectionProxy(this, info);
+        proxyConnections.add(proxy);
+        return proxy;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionFactory.java
new file mode 100644
index 0000000..44ea157
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionFactory.java
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.ra.ActiveMQConnectionRequestInfo;
+import org.apache.activemq.ra.ActiveMQManagedConnectionFactory;
+import org.apache.activemq.ra.MessageActivationSpec;
+import org.apache.activemq.ra.SimpleConnectionManager;
+
+import javax.jms.JMSException;
+import javax.resource.ResourceException;
+import javax.resource.spi.ConnectionManager;
+import javax.resource.spi.ConnectionRequestInfo;
+import javax.resource.spi.ManagedConnection;
+import javax.security.auth.Subject;
+
+public class TomEEManagedConnectionFactory extends ActiveMQManagedConnectionFactory {
+    @Override
+    public Object createConnectionFactory(final ConnectionManager manager) throws ResourceException {
+        return new TomEERAConnectionFactory(this, manager, getInfo());
+    }
+
+    @Override
+    public Object createConnectionFactory() throws ResourceException {
+        return createConnectionFactory(new SimpleConnectionManager());
+    }
+
+    @Override
+    protected ActiveMQConnectionFactory createConnectionFactory(final ActiveMQConnectionRequestInfo connectionRequestInfo, final MessageActivationSpec activationSpec) {
+        final TomEEConnectionFactory connectionFactory = new TomEEConnectionFactory();
+        connectionRequestInfo.configure(connectionFactory, activationSpec);
+        return connectionFactory;
+    }
+
+    @Override
+    public ManagedConnection createManagedConnection(final Subject subject, final ConnectionRequestInfo connectionRequestInfo) throws ResourceException {
+        final ActiveMQConnectionRequestInfo amqInfo;
+        if (ActiveMQConnectionRequestInfo.class.isInstance(connectionRequestInfo)) {
+            amqInfo = ActiveMQConnectionRequestInfo.class.cast(connectionRequestInfo);
+        } else {
+            amqInfo = getInfo();
+        }
+        try {
+            return new TomEEManagedConnection(subject, makeConnection(amqInfo), amqInfo);
+        } catch (final JMSException e) {
+            throw new ResourceException("Could not create connection.", e);
+        }
+    }
+
+    @Override
+    public boolean equals(final Object object) {
+        return !(object == null || !getClass().isInstance(object))
+            && ((ActiveMQManagedConnectionFactory) object).getInfo().equals(getInfo());
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionProxy.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionProxy.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionProxy.java
new file mode 100644
index 0000000..f07b7a2
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEManagedConnectionProxy.java
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ra.ActiveMQManagedConnection;
+import org.apache.activemq.ra.ManagedConnectionProxy;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionConsumer;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSException;
+import javax.jms.QueueConnection;
+import javax.jms.ServerSessionPool;
+import javax.jms.Session;
+import javax.jms.Topic;
+import javax.jms.TopicConnection;
+import javax.resource.spi.ConnectionRequestInfo;
+
+public class TomEEManagedConnectionProxy extends ManagedConnectionProxy
+    // cause org.apache.openejb.resource.AutoConnectionTracker.proxyConnection() just uses getInterfaces()
+    implements Connection, QueueConnection, TopicConnection, ExceptionListener {
+
+    private volatile ActiveMQManagedConnection connection;
+
+    public TomEEManagedConnectionProxy(final ActiveMQManagedConnection managedConnection, final ConnectionRequestInfo info) {
+        super(managedConnection, info);
+        connection = managedConnection;
+    }
+
+    @Override
+    public void cleanup() {
+        super.cleanup();
+        connection = null;
+    }
+
+    @Override
+    public Session createSession(final int sessionMode) throws JMSException {
+        return connection.getPhysicalConnection().createSession(sessionMode);
+    }
+
+    @Override
+    public Session createSession() throws JMSException {
+        return connection.getPhysicalConnection().createSession();
+    }
+
+    @Override
+    public ConnectionConsumer createSharedDurableConnectionConsumer(final Topic topic, final String subscriptionName,
+                                                                    final String messageSelector, final ServerSessionPool sessionPool,
+                                                                    final int maxMessages) throws JMSException {
+        return connection.getPhysicalConnection().createSharedDurableConnectionConsumer(topic, subscriptionName, messageSelector, sessionPool, maxMessages);
+    }
+
+    @Override
+    public ConnectionConsumer createSharedConnectionConsumer(final Topic topic, final String subscriptionName, final String messageSelector,
+                                                             final ServerSessionPool sessionPool, final int maxMessages) throws JMSException {
+        return connection.getPhysicalConnection().createSharedConnectionConsumer(topic, subscriptionName, messageSelector, sessionPool, maxMessages);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEERAConnectionFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEERAConnectionFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEERAConnectionFactory.java
new file mode 100644
index 0000000..75f3582
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEERAConnectionFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ra.ActiveMQConnectionFactory;
+import org.apache.activemq.ra.ActiveMQConnectionRequestInfo;
+import org.apache.activemq.ra.ActiveMQManagedConnectionFactory;
+
+import javax.jms.JMSContext;
+import javax.jms.Session;
+import javax.resource.spi.ConnectionManager;
+
+public class TomEERAConnectionFactory extends ActiveMQConnectionFactory {
+    public TomEERAConnectionFactory(final ActiveMQManagedConnectionFactory factory, final ConnectionManager manager,
+                                    final ActiveMQConnectionRequestInfo connectionRequestInfo) {
+        super(factory, manager, connectionRequestInfo);
+    }
+
+    @Override
+    public JMSContext createContext() {
+        return new JMSContextImpl(this, Session.AUTO_ACKNOWLEDGE, null, null, false);
+    }
+
+    @Override
+    public JMSContext createContext(final int sessionMode) {
+        return new JMSContextImpl(this, sessionMode, null, null, false);
+    }
+
+    @Override
+    public JMSContext createContext(final String userName, final String password) {
+        return new JMSContextImpl(this, Session.AUTO_ACKNOWLEDGE, userName, password, false);
+    }
+
+    @Override
+    public JMSContext createContext(final String userName, final String password, final int sessionMode) {
+        return new JMSContextImpl(this, sessionMode, userName, password, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnection.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnection.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnection.java
new file mode 100644
index 0000000..7726fd5
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnection.java
@@ -0,0 +1,42 @@
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ActiveMQConnection;
+import org.apache.activemq.ActiveMQXAConnection;
+import org.apache.activemq.management.JMSStatsImpl;
+import org.apache.activemq.transport.Transport;
+import org.apache.activemq.util.IdGenerator;
+
+import javax.jms.ConnectionConsumer;
+import javax.jms.JMSException;
+import javax.jms.ServerSessionPool;
+import javax.jms.Session;
+import javax.jms.Topic;
+
+public class TomEEXAConnection extends ActiveMQXAConnection {
+    protected TomEEXAConnection(final Transport transport, final IdGenerator clientIdGenerator,
+                                final IdGenerator connectionIdGenerator, final JMSStatsImpl factoryStats) throws Exception {
+        super(transport, clientIdGenerator, connectionIdGenerator, factoryStats);
+    }
+
+    @Override
+    public Session createSession(final int sessionMode) throws JMSException {
+        return null;
+    }
+
+    @Override
+    public Session createSession() throws JMSException {
+        return null;
+    }
+
+    @Override
+    public ConnectionConsumer createSharedDurableConnectionConsumer(final Topic topic, final String subscriptionName, final String messageSelector,
+                                                                    final ServerSessionPool sessionPool, final int maxMessages) throws JMSException {
+        return null;
+    }
+
+    @Override
+    public ConnectionConsumer createSharedConnectionConsumer(final Topic topic, final String subscriptionName, final String messageSelector,
+                                                             final ServerSessionPool sessionPool, final int maxMessages) throws JMSException {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnectionFactory.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnectionFactory.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnectionFactory.java
new file mode 100644
index 0000000..ff5fd95
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/TomEEXAConnectionFactory.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.ActiveMQXAConnectionFactory;
+
+import javax.jms.JMSContext;
+import javax.jms.Session;
+import javax.jms.XAJMSContext;
+import java.net.URI;
+
+public class TomEEXAConnectionFactory extends ActiveMQXAConnectionFactory {
+    public TomEEXAConnectionFactory() {
+        super();
+    }
+
+    public TomEEXAConnectionFactory(final String userName, final String password, final String brokerURL) {
+        super(userName, password, brokerURL);
+    }
+
+    public TomEEXAConnectionFactory(final String userName, final String password, final URI brokerURL) {
+        super(userName, password, brokerURL);
+    }
+
+    public TomEEXAConnectionFactory(final String brokerURL) {
+        super(brokerURL);
+    }
+
+    public TomEEXAConnectionFactory(final URI brokerURL) {
+        super(brokerURL);
+    }
+
+    @Override
+    public JMSContext createContext() {
+        return new JMSContextImpl(this, Session.AUTO_ACKNOWLEDGE, null, null, true);
+    }
+
+    @Override
+    public JMSContext createContext(final int sessionMode) {
+        return new JMSContextImpl(this, sessionMode, null, null, true);
+    }
+
+    @Override
+    public JMSContext createContext(final String userName, final String password) {
+        return new JMSContextImpl(this, Session.AUTO_ACKNOWLEDGE, userName, password, true);
+    }
+
+    @Override
+    public JMSContext createContext(final String userName, final String password, final int sessionMode) {
+        return new JMSContextImpl(this, sessionMode, userName, password, true);
+    }
+
+    @Override
+    public XAJMSContext createXAContext() {
+        return new XAJMSContextImpl(this, Session.SESSION_TRANSACTED, userName, password);
+    }
+
+    @Override
+    public XAJMSContext createXAContext(String userName, String password) {
+        return new XAJMSContextImpl(this, Session.SESSION_TRANSACTED, userName, password);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingByteMessage.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingByteMessage.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingByteMessage.java
new file mode 100644
index 0000000..898f7de
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingByteMessage.java
@@ -0,0 +1,184 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.command.ActiveMQBytesMessage;
+
+import javax.jms.BytesMessage;
+import javax.jms.JMSException;
+
+public class WrappingByteMessage extends DelegateMessage implements BytesMessage {
+    private final BytesMessage message;
+
+    public WrappingByteMessage(final BytesMessage message) {
+        super(message);
+        this.message = message;
+    }
+
+    @Override
+    public boolean isBodyAssignableTo(final Class c) throws JMSException {
+        return byte[].class == c;
+    }
+
+    @Override
+    public <T> T getBody(final Class<T> c) throws JMSException {
+        final int len = (int) getBodyLength();
+        if (len == 0) {
+            return null;
+        }
+        final byte[] dst = new byte[len];
+        if (ActiveMQBytesMessage.class.isInstance(message)) {
+            System.arraycopy(ActiveMQBytesMessage.class.cast(message).getContent().getData(), 0, dst, 0, len);
+        }
+        return c.cast(dst);
+    }
+
+    @Override
+    public long getBodyLength() throws JMSException {
+        return message.getBodyLength();
+    }
+
+    @Override
+    public boolean readBoolean() throws JMSException {
+        return message.readBoolean();
+    }
+
+    @Override
+    public byte readByte() throws JMSException {
+        return message.readByte();
+    }
+
+    @Override
+    public int readUnsignedByte() throws JMSException {
+        return message.readUnsignedByte();
+    }
+
+    @Override
+    public short readShort() throws JMSException {
+        return message.readShort();
+    }
+
+    @Override
+    public int readUnsignedShort() throws JMSException {
+        return message.readUnsignedShort();
+    }
+
+    @Override
+    public char readChar() throws JMSException {
+        return message.readChar();
+    }
+
+    @Override
+    public int readInt() throws JMSException {
+        return message.readInt();
+    }
+
+    @Override
+    public long readLong() throws JMSException {
+        return message.readLong();
+    }
+
+    @Override
+    public float readFloat() throws JMSException {
+        return message.readFloat();
+    }
+
+    @Override
+    public double readDouble() throws JMSException {
+        return message.readDouble();
+    }
+
+    @Override
+    public String readUTF() throws JMSException {
+        return message.readUTF();
+    }
+
+    @Override
+    public int readBytes(final byte[] value) throws JMSException {
+        return message.readBytes(value);
+    }
+
+    @Override
+    public int readBytes(final byte[] value, final int length) throws JMSException {
+        return message.readBytes(value, length);
+    }
+
+    @Override
+    public void writeBoolean(final boolean value) throws JMSException {
+        message.writeBoolean(value);
+    }
+
+    @Override
+    public void writeByte(final byte value) throws JMSException {
+        message.writeByte(value);
+    }
+
+    @Override
+    public void writeShort(final short value) throws JMSException {
+        message.writeShort(value);
+    }
+
+    @Override
+    public void writeChar(final char value) throws JMSException {
+        message.writeChar(value);
+    }
+
+    @Override
+    public void writeInt(final int value) throws JMSException {
+        message.writeInt(value);
+    }
+
+    @Override
+    public void writeLong(final long value) throws JMSException {
+        message.writeLong(value);
+    }
+
+    @Override
+    public void writeFloat(final float value) throws JMSException {
+        message.writeFloat(value);
+    }
+
+    @Override
+    public void writeDouble(final double value) throws JMSException {
+        message.writeDouble(value);
+    }
+
+    @Override
+    public void writeUTF(final String value) throws JMSException {
+        message.writeUTF(value);
+    }
+
+    @Override
+    public void writeBytes(final byte[] value) throws JMSException {
+        message.writeBytes(value);
+    }
+
+    @Override
+    public void writeBytes(final byte[] value, final int offset, final int length) throws JMSException {
+        message.writeBytes(value, offset, length);
+    }
+
+    @Override
+    public void writeObject(final Object value) throws JMSException {
+        message.writeObject(value);
+    }
+
+    @Override
+    public void reset() throws JMSException {
+        message.reset();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingMapMessage.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingMapMessage.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingMapMessage.java
new file mode 100644
index 0000000..a9edf76
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingMapMessage.java
@@ -0,0 +1,173 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import org.apache.activemq.command.ActiveMQMapMessage;
+
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.MessageFormatException;
+import java.util.Enumeration;
+import java.util.Map;
+
+public class WrappingMapMessage extends DelegateMessage implements MapMessage {
+    private final MapMessage message;
+
+    public WrappingMapMessage(final MapMessage message) {
+        super(message);
+        this.message = message;
+    }
+
+    @Override
+    public boolean isBodyAssignableTo(final Class c) throws JMSException {
+        return c == Map.class || Object.class == c;
+    }
+
+    @Override
+    public <T> T getBody(final Class<T> c) throws JMSException {
+        if (isBodyAssignableTo(c)) {
+            return c.cast(ActiveMQMapMessage.class.isInstance(message) ?
+                ActiveMQMapMessage.class.cast(message).getContentMap() : message /* unlikely */);
+        }
+        throw new MessageFormatException("Can't get the body with type " + c);
+    }
+
+    @Override
+    public boolean getBoolean(final String name) throws JMSException {
+        return message.getBoolean(name);
+    }
+
+    @Override
+    public byte getByte(final String name) throws JMSException {
+        return message.getByte(name);
+    }
+
+    @Override
+    public short getShort(final String name) throws JMSException {
+        return message.getShort(name);
+    }
+
+    @Override
+    public char getChar(final String name) throws JMSException {
+        return message.getChar(name);
+    }
+
+    @Override
+    public int getInt(final String name) throws JMSException {
+        return message.getInt(name);
+    }
+
+    @Override
+    public long getLong(final String name) throws JMSException {
+        return message.getLong(name);
+    }
+
+    @Override
+    public float getFloat(final String name) throws JMSException {
+        return message.getFloat(name);
+    }
+
+    @Override
+    public double getDouble(final String name) throws JMSException {
+        return message.getDouble(name);
+    }
+
+    @Override
+    public String getString(final String name) throws JMSException {
+        return message.getString(name);
+    }
+
+    @Override
+    public byte[] getBytes(final String name) throws JMSException {
+        return message.getBytes(name);
+    }
+
+    @Override
+    public Object getObject(final String name) throws JMSException {
+        return message.getObject(name);
+    }
+
+    @Override
+    public Enumeration getMapNames() throws JMSException {
+        return message.getMapNames();
+    }
+
+    @Override
+    public void setBoolean(final String name, final boolean value) throws JMSException {
+        message.setBoolean(name, value);
+    }
+
+    @Override
+    public void setByte(final String name, final byte value) throws JMSException {
+        message.setByte(name, value);
+    }
+
+    @Override
+    public void setShort(final String name, final short value) throws JMSException {
+        message.setShort(name, value);
+    }
+
+    @Override
+    public void setChar(final String name, final char value) throws JMSException {
+        message.setChar(name, value);
+    }
+
+    @Override
+    public void setInt(final String name, final int value) throws JMSException {
+        message.setInt(name, value);
+    }
+
+    @Override
+    public void setLong(final String name, final long value) throws JMSException {
+        message.setLong(name, value);
+    }
+
+    @Override
+    public void setFloat(final String name, final float value) throws JMSException {
+        message.setFloat(name, value);
+    }
+
+    @Override
+    public void setDouble(final String name, final double value) throws JMSException {
+        message.setDouble(name, value);
+    }
+
+    @Override
+    public void setString(final String name, final String value) throws JMSException {
+        message.setString(name, value);
+    }
+
+    @Override
+    public void setBytes(final String name, final byte[] value) throws JMSException {
+        message.setBytes(name, value);
+    }
+
+    @Override
+    public void setBytes(final String name, final byte[] value, final int offset, final int length) throws JMSException {
+        message.setBytes(name, value, offset, length);
+    }
+
+    @Override
+    public void setObject(final String name, final Object value) throws JMSException {
+        message.setObject(name, value);
+    }
+
+    @Override
+    public boolean itemExists(final String name) throws JMSException {
+        return message.itemExists(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingObjectMessage.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingObjectMessage.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingObjectMessage.java
new file mode 100644
index 0000000..89deddc
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingObjectMessage.java
@@ -0,0 +1,50 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import javax.jms.JMSException;
+import javax.jms.ObjectMessage;
+import java.io.Serializable;
+
+public class WrappingObjectMessage extends DelegateMessage implements ObjectMessage {
+    private final ObjectMessage message;
+
+    public WrappingObjectMessage(final ObjectMessage message) {
+        super(message);
+        this.message = message;
+    }
+
+    @Override
+    public boolean isBodyAssignableTo(final Class c) throws JMSException {
+        return c.isInstance(message.getObject());
+    }
+
+    @Override
+    public <T> T getBody(final Class<T> c) throws JMSException {
+        return c.cast(message.getObject());
+    }
+
+    @Override
+    public void setObject(final Serializable object) throws JMSException {
+        message.setObject(object);
+    }
+
+    @Override
+    public Serializable getObject() throws JMSException {
+        return message.getObject();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingStreamMessage.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingStreamMessage.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingStreamMessage.java
new file mode 100644
index 0000000..be993e0
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingStreamMessage.java
@@ -0,0 +1,160 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import javax.jms.JMSException;
+import javax.jms.MessageFormatException;
+import javax.jms.StreamMessage;
+
+public class WrappingStreamMessage extends DelegateMessage implements StreamMessage {
+    private final StreamMessage message;
+
+    public WrappingStreamMessage(final StreamMessage message) {
+        super(message);
+        this.message = message;
+    }
+
+    @Override
+    public <T> T getBody(final Class<T> c) throws JMSException {
+        throw new MessageFormatException("Can't getBody on a stream message");
+    }
+
+    @Override
+    public boolean isBodyAssignableTo(final Class c) throws JMSException {
+        return false;
+    }
+
+    @Override
+    public boolean readBoolean() throws JMSException {
+        return message.readBoolean();
+    }
+
+    @Override
+    public byte readByte() throws JMSException {
+        return message.readByte();
+    }
+
+    @Override
+    public short readShort() throws JMSException {
+        return message.readShort();
+    }
+
+    @Override
+    public char readChar() throws JMSException {
+        return message.readChar();
+    }
+
+    @Override
+    public int readInt() throws JMSException {
+        return message.readInt();
+    }
+
+    @Override
+    public long readLong() throws JMSException {
+        return message.readLong();
+    }
+
+    @Override
+    public float readFloat() throws JMSException {
+        return message.readFloat();
+    }
+
+    @Override
+    public double readDouble() throws JMSException {
+        return message.readDouble();
+    }
+
+    @Override
+    public String readString() throws JMSException {
+        return message.readString();
+    }
+
+    @Override
+    public int readBytes(byte[] value) throws JMSException {
+        return message.readBytes(value);
+    }
+
+    @Override
+    public Object readObject() throws JMSException {
+        return message.readObject();
+    }
+
+    @Override
+    public void writeBoolean(final boolean value) throws JMSException {
+        message.writeBoolean(value);
+    }
+
+    @Override
+    public void writeByte(final byte value) throws JMSException {
+        message.writeByte(value);
+    }
+
+    @Override
+    public void writeShort(final short value) throws JMSException {
+        message.writeShort(value);
+    }
+
+    @Override
+    public void writeChar(final char value) throws JMSException {
+        message.writeChar(value);
+    }
+
+    @Override
+    public void writeInt(final int value) throws JMSException {
+        message.writeInt(value);
+    }
+
+    @Override
+    public void writeLong(final long value) throws JMSException {
+        message.writeLong(value);
+    }
+
+    @Override
+    public void writeFloat(float value) throws JMSException {
+        message.writeFloat(value);
+    }
+
+    @Override
+    public void writeDouble(final double value) throws JMSException {
+        message.writeDouble(value);
+    }
+
+    @Override
+    public void writeString(final String value) throws JMSException {
+        message.writeString(value);
+    }
+
+    @Override
+    public void writeBytes(final byte[] value) throws JMSException {
+        message.writeBytes(value);
+    }
+
+    @Override
+    public void writeBytes(final byte[] value, final int offset, final int length) throws JMSException {
+        message.writeBytes(value, offset, length);
+    }
+
+    @Override
+    public void writeObject(final Object value) throws JMSException {
+        message.writeObject(value);
+    }
+
+    @Override
+    public void reset() throws JMSException {
+        message.reset();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingTextMessage.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingTextMessage.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingTextMessage.java
new file mode 100644
index 0000000..fd90067
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/WrappingTextMessage.java
@@ -0,0 +1,49 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import javax.jms.JMSException;
+import javax.jms.TextMessage;
+
+public class WrappingTextMessage extends DelegateMessage implements TextMessage {
+    private final TextMessage message;
+
+    public WrappingTextMessage(final TextMessage message) {
+        super(message);
+        this.message = message;
+    }
+
+    @Override
+    public boolean isBodyAssignableTo(final Class c) throws JMSException {
+        return CharSequence.class.isAssignableFrom(c);
+    }
+
+    @Override
+    public <T> T getBody(final Class<T> c) throws JMSException {
+        return c.cast(message.getText());
+    }
+
+    @Override
+    public String getText() throws JMSException {
+        return message.getText();
+    }
+
+    @Override
+    public void setText(final String string) throws JMSException {
+        message.setText(string);
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/XAJMSContextImpl.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/XAJMSContextImpl.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/XAJMSContextImpl.java
new file mode 100644
index 0000000..63af633
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/XAJMSContextImpl.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSContext;
+import javax.jms.XAJMSContext;
+import javax.jms.XASession;
+import javax.transaction.xa.XAResource;
+
+public class XAJMSContextImpl extends JMSContextImpl implements XAJMSContext {
+    public XAJMSContextImpl(final ConnectionFactory factory, final int sessionMode, final String user, final String pwd) {
+        super(factory, sessionMode, user, pwd, true);
+    }
+
+    @Override
+    public JMSContext getContext() {
+        return this;
+    }
+
+    @Override
+    public XAResource getXAResource() {
+        return XASession.class.cast(session()).getXAResource();
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/cdi/JMS2CDIExtension.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/cdi/JMS2CDIExtension.java b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/cdi/JMS2CDIExtension.java
new file mode 100644
index 0000000..43eb6ec
--- /dev/null
+++ b/container/openejb-core/src/main/java/org/apache/openejb/resource/activemq/jms2/cdi/JMS2CDIExtension.java
@@ -0,0 +1,465 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.resource.activemq.jms2.cdi;
+
+import org.apache.openejb.OpenEJB;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.spi.ContainerSystem;
+
+import javax.annotation.PreDestroy;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.spi.Annotated;
+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.inject.Inject;
+import javax.jms.BytesMessage;
+import javax.jms.ConnectionFactory;
+import javax.jms.ConnectionMetaData;
+import javax.jms.Destination;
+import javax.jms.ExceptionListener;
+import javax.jms.JMSConnectionFactory;
+import javax.jms.JMSConsumer;
+import javax.jms.JMSContext;
+import javax.jms.JMSPasswordCredential;
+import javax.jms.JMSProducer;
+import javax.jms.JMSRuntimeException;
+import javax.jms.JMSSessionMode;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueBrowser;
+import javax.jms.StreamMessage;
+import javax.jms.TemporaryQueue;
+import javax.jms.TemporaryTopic;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.naming.NamingException;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionScoped;
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+// this extension adds to CDI a producer a JMSContext,
+// the producer creates the JMSContext only if not already there
+// and it switch to a facade request scoped or transaction scoped depending if there is a tx we can reuse or not
+public class JMS2CDIExtension implements Extension {
+    @ApplicationScoped
+    public static class ContextProducer { // small hack to reuse CDI proxying and get it properly setup when injected
+        @Inject
+        private RequestAutoContextDestruction requestScoped;
+
+        @Inject
+        private TransactionAutoContextDestruction transactionScoped;
+
+        @Produces
+        public JMSContext context(final InjectionPoint ip) {
+            return new InternalJMSContext(newKey(ip), requestScoped, transactionScoped);
+        }
+
+        private Key newKey(final InjectionPoint ip) {
+            final Annotated annotated = ip.getAnnotated();
+            final JMSConnectionFactory jmsConnectionFactory = annotated.getAnnotation(JMSConnectionFactory.class);
+            final JMSSessionMode sessionMode = annotated.getAnnotation(JMSSessionMode.class);
+            final JMSPasswordCredential credential = annotated.getAnnotation(JMSPasswordCredential.class);
+
+            final String jndi = jmsConnectionFactory == null ? null : "openejb:Resource/" + jmsConnectionFactory.value();
+            return new Key(
+                jndi,
+                credential != null ? credential.userName() : null,
+                credential != null ? credential.password() : null,
+                sessionMode != null ? sessionMode.value() : null);
+        }
+    }
+
+    public static abstract class AutoContextDestruction implements Serializable {
+        private transient Map<Key, JMSContext> contexts = new ConcurrentHashMap<>();
+
+        public void push(final Key key, final JMSContext c) {
+            contexts.put(key, c);
+        }
+
+        public JMSContext find(final Key key) {
+            return contexts.get(key);
+        }
+
+        @PreDestroy
+        private void destroy() {
+            if (contexts != null) {
+                JMSRuntimeException jre = null;
+                for (final JMSContext c : contexts.values()) {
+                    try {
+                        c.close();
+                    } catch (final JMSRuntimeException e) {
+                        jre = e;
+                    }
+                }
+                if (jre != null) {
+                    throw jre;
+                }
+            }
+        }
+    }
+
+    @RequestScoped
+    public static class RequestAutoContextDestruction extends AutoContextDestruction {
+    }
+
+    @TransactionScoped
+    public static class TransactionAutoContextDestruction extends AutoContextDestruction {
+    }
+
+    public static class Key {
+        private volatile ConnectionFactory connectionFactoryInstance;
+        private final String connectionFactory;
+        private final String username;
+        private final String password;
+        private final Integer session;
+        private final int hash;
+
+        public Key(final String connectionFactory, final String username, final String password, final Integer session) {
+            this.connectionFactory = connectionFactory;
+            this.username = username;
+            this.password = password;
+            this.session = session;
+
+            int result = connectionFactory != null ? connectionFactory.hashCode() : 0;
+            result = 31 * result + (username != null ? username.hashCode() : 0);
+            result = 31 * result + (password != null ? password.hashCode() : 0);
+            result = 31 * result + (session != null ? session.hashCode() : 0);
+            this.hash = result;
+        }
+
+        private ConnectionFactory connectionFactory() {
+            if (connectionFactoryInstance != null) {
+                return connectionFactoryInstance;
+            }
+            synchronized (this) {
+                if (connectionFactoryInstance != null) {
+                    return connectionFactoryInstance;
+                }
+                try {
+                    return connectionFactoryInstance = connectionFactory == null ?
+                        findDefaultConnectionFactory() :
+                        ConnectionFactory.class.cast(
+                            SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext()
+                                .lookup(connectionFactory));
+                } catch (final NamingException e) {
+                    throw new JMSRuntimeException(e.getMessage(), null, e);
+                }
+            }
+        }
+
+        private ConnectionFactory findDefaultConnectionFactory() {
+            // TODO: link scanning to auto create a default and use it there? See AutoConfig
+            throw new IllegalArgumentException("You have to specify @JMSConnectionFactory");
+        }
+
+        public JMSContext create() {
+            if (username != null && session != null) {
+                return connectionFactory().createContext(username, password, session);
+            } else if (username != null) {
+                return connectionFactory().createContext(username, password);
+            } else if (session != null) {
+                return connectionFactory().createContext(session);
+            }
+            return connectionFactory().createContext();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            final Key key = Key.class.cast(o);
+            return connectionFactory != null ? connectionFactory.equals(key.connectionFactory) : key.connectionFactory == null
+                && (username != null ? username.equals(key.username) : key.username == null
+                && (password != null ? password.equals(key.password) : key.password == null
+                && (session != null ? session.equals(key.session) : key.session == null)));
+
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+    }
+
+    public static class InternalJMSContext implements JMSContext {
+        private final Key key;
+        private final RequestAutoContextDestruction requestStorage;
+        private final TransactionAutoContextDestruction transactionStorage;
+
+        public InternalJMSContext(final Key key, final RequestAutoContextDestruction requestScoped, final TransactionAutoContextDestruction transactionScoped) {
+            this.key = key;
+            this.requestStorage = requestScoped;
+            this.transactionStorage = transactionScoped;
+        }
+
+        private synchronized JMSContext context() {
+            if (inTx()) {
+                return findOrCreateContext(transactionStorage);
+            }
+            return findOrCreateContext(requestStorage);
+        }
+
+        private JMSContext findOrCreateContext(final AutoContextDestruction storage) {
+            JMSContext jmsContext = storage.find(key);
+            if (jmsContext == null) { // both scopes are thread safe
+                jmsContext = key.create();
+                storage.push(key, jmsContext);
+            }
+            return jmsContext;
+        }
+
+        private boolean inTx() {
+            try {
+                return OpenEJB.getTransactionManager().getTransaction() != null;
+            } catch (SystemException e) {
+                return false;
+            }
+        }
+
+        // plain delegation now
+
+        @Override
+        public void acknowledge() {
+            context().acknowledge();
+        }
+
+        @Override
+        public void close() {
+            context().close();
+        }
+
+        @Override
+        public void commit() {
+            context().commit();
+        }
+
+        @Override
+        public QueueBrowser createBrowser(final Queue queue) {
+            return context().createBrowser(queue);
+        }
+
+        @Override
+        public QueueBrowser createBrowser(final Queue queue, final String messageSelector) {
+            return context().createBrowser(queue, messageSelector);
+        }
+
+        @Override
+        public BytesMessage createBytesMessage() {
+            return context().createBytesMessage();
+        }
+
+        @Override
+        public JMSConsumer createConsumer(final Destination destination) {
+            return context().createConsumer(destination);
+        }
+
+        @Override
+        public JMSConsumer createConsumer(final Destination destination, final String messageSelector) {
+            return context().createConsumer(destination, messageSelector);
+        }
+
+        @Override
+        public JMSConsumer createConsumer(final Destination destination, final String messageSelector, final boolean noLocal) {
+            return context().createConsumer(destination, messageSelector, noLocal);
+        }
+
+        @Override
+        public JMSContext createContext(final int sessionMode) {
+            return context().createContext(sessionMode);
+        }
+
+        @Override
+        public JMSConsumer createDurableConsumer(final Topic topic, final String name) {
+            return context().createDurableConsumer(topic, name);
+        }
+
+        @Override
+        public JMSConsumer createDurableConsumer(final Topic topic, final String name, final String messageSelector, final boolean noLocal) {
+            return context().createDurableConsumer(topic, name, messageSelector, noLocal);
+        }
+
+        @Override
+        public MapMessage createMapMessage() {
+            return context().createMapMessage();
+        }
+
+        @Override
+        public Message createMessage() {
+            return context().createMessage();
+        }
+
+        @Override
+        public ObjectMessage createObjectMessage() {
+            return context().createObjectMessage();
+        }
+
+        @Override
+        public ObjectMessage createObjectMessage(final Serializable object) {
+            return context().createObjectMessage(object);
+        }
+
+        @Override
+        public JMSProducer createProducer() {
+            return context().createProducer();
+        }
+
+        @Override
+        public Queue createQueue(final String queueName) {
+            return context().createQueue(queueName);
+        }
+
+        @Override
+        public JMSConsumer createSharedConsumer(final Topic topic, final String sharedSubscriptionName) {
+            return context().createSharedConsumer(topic, sharedSubscriptionName);
+        }
+
+        @Override
+        public JMSConsumer createSharedConsumer(final Topic topic, final String sharedSubscriptionName, final String messageSelector) {
+            return context().createSharedConsumer(topic, sharedSubscriptionName, messageSelector);
+        }
+
+        @Override
+        public JMSConsumer createSharedDurableConsumer(final Topic topic, final String name) {
+            return context().createSharedDurableConsumer(topic, name);
+        }
+
+        @Override
+        public JMSConsumer createSharedDurableConsumer(final Topic topic, final String name, final String messageSelector) {
+            return context().createSharedDurableConsumer(topic, name, messageSelector);
+        }
+
+        @Override
+        public StreamMessage createStreamMessage() {
+            return context().createStreamMessage();
+        }
+
+        @Override
+        public TemporaryQueue createTemporaryQueue() {
+            return context().createTemporaryQueue();
+        }
+
+        @Override
+        public TemporaryTopic createTemporaryTopic() {
+            return context().createTemporaryTopic();
+        }
+
+        @Override
+        public TextMessage createTextMessage() {
+            return context().createTextMessage();
+        }
+
+        @Override
+        public TextMessage createTextMessage(final String text) {
+            return context().createTextMessage(text);
+        }
+
+        @Override
+        public Topic createTopic(final String topicName) {
+            return context().createTopic(topicName);
+        }
+
+        @Override
+        public boolean getAutoStart() {
+            return context().getAutoStart();
+        }
+
+        @Override
+        public String getClientID() {
+            return context().getClientID();
+        }
+
+        @Override
+        public ExceptionListener getExceptionListener() {
+            return context().getExceptionListener();
+        }
+
+        @Override
+        public ConnectionMetaData getMetaData() {
+            return context().getMetaData();
+        }
+
+        @Override
+        public int getSessionMode() {
+            return context().getSessionMode();
+        }
+
+        @Override
+        public boolean getTransacted() {
+            return context().getTransacted();
+        }
+
+        @Override
+        public void recover() {
+            context().recover();
+        }
+
+        @Override
+        public void rollback() {
+            context().rollback();
+        }
+
+        @Override
+        public void setAutoStart(final boolean autoStart) {
+            context().setAutoStart(autoStart);
+        }
+
+        @Override
+        public void setClientID(final String clientID) {
+            context().setClientID(clientID);
+        }
+
+        @Override
+        public void setExceptionListener(final ExceptionListener listener) {
+            context().setExceptionListener(listener);
+        }
+
+        @Override
+        public void start() {
+            context().start();
+        }
+
+        @Override
+        public void stop() {
+            context().stop();
+        }
+
+        @Override
+        public void unsubscribe(final String name) {
+            context().unsubscribe(name);
+        }
+    }
+
+    public void addContextProducer(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager beanManager) {
+        beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(ContextProducer.class));
+        beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(RequestAutoContextDestruction.class));
+        beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(TransactionAutoContextDestruction.class));
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml b/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
index c15684a..c0a7301 100644
--- a/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
+++ b/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
@@ -682,7 +682,7 @@
           id="Default JMS Connection Factory"
           service="Resource"
           types="javax.jms.ConnectionFactory, javax.jms.QueueConnectionFactory, javax.jms.TopicConnectionFactory, QueueConnectionFactory, TopicConnectionFactory"
-          class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory">
+          class-name="org.apache.openejb.resource.activemq.jms2.TomEEManagedConnectionFactory">
 
     ResourceAdapter Default JMS Resource Adapter
 

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java b/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java
new file mode 100644
index 0000000..5fc8e64
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMS2AMQTest.java
@@ -0,0 +1,314 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.activemq;
+
+import org.apache.activemq.ActiveMQXAConnectionFactory;
+import org.apache.openejb.jee.MessageDrivenBean;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.testing.Configuration;
+import org.apache.openejb.testing.Module;
+import org.apache.openejb.testing.SimpleLog;
+import org.apache.openejb.testng.PropertiesBuilder;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.spi.ContextsService;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.annotation.Resource;
+import javax.ejb.ActivationConfigProperty;
+import javax.ejb.MessageDriven;
+import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSConnectionFactory;
+import javax.jms.JMSConsumer;
+import javax.jms.JMSContext;
+import javax.jms.JMSException;
+import javax.jms.JMSRuntimeException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.Queue;
+import javax.jms.TextMessage;
+import javax.jms.XAConnectionFactory;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static java.lang.Thread.sleep;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@SimpleLog
+@RunWith(ApplicationComposer.class)
+public class JMS2AMQTest {
+    private static final String TEXT = "foo";
+
+    @Configuration
+    public Properties config() {
+        return new PropertiesBuilder()
+
+            .p("amq", "new://Resource?type=ActiveMQResourceAdapter")
+            .p("amq.DataSource", "")
+            .p("amq.BrokerXmlConfig", "broker:(vm://localhost)")
+
+            .p("target", "new://Resource?type=Queue")
+
+            .p("mdbs", "new://Container?type=MESSAGE")
+            .p("mdbs.ResourceAdapter", "amq")
+
+            .p("cf", "new://Resource?type=" + ConnectionFactory.class.getName())
+            .p("cf.ResourceAdapter", "amq")
+
+            .p("xaCf", "new://Resource?class-name=" + ActiveMQXAConnectionFactory.class.getName())
+            .p("xaCf.BrokerURL", "vm://localhost")
+
+            .build();
+    }
+
+    @Module
+    public MessageDrivenBean jar() {
+        return new MessageDrivenBean(Listener.class);
+    }
+
+    @Resource(name = "target")
+    private Queue destination;
+
+    @Resource(name = "target2")
+    private Queue destination2;
+
+    @Resource(name = "target3")
+    private Queue destination3;
+
+    @Resource(name = "xaCf")
+    private XAConnectionFactory xacf;
+
+    @Resource(name = "cf")
+    private ConnectionFactory cf;
+
+    @Inject
+    @JMSConnectionFactory("cf")
+    private JMSContext context;
+
+    @Before
+    public void resetLatch() {
+        Listener.reset();
+    }
+
+    @Test
+    public void cdi() throws InterruptedException {
+        final String text = TEXT + "3";
+
+        final AtomicReference<Throwable> error = new AtomicReference<>();
+        final CountDownLatch ready = new CountDownLatch(1);
+        final CountDownLatch over = new CountDownLatch(1);
+        new Thread() {
+            {
+                setName(JMS2AMQTest.class.getName() + ".cdi#receiver");
+            }
+
+            @Override
+            public void run() {
+                final ContextsService contextsService = WebBeansContext.currentInstance().getContextsService();
+                contextsService.startContext(RequestScoped.class, null); // spec defines it for request scope an transaction scope
+                try {
+                    ready.countDown();
+                    assertEquals(text, context.createConsumer(destination3).receiveBody(String.class, TimeUnit.MINUTES.toMillis(1)));
+                } catch (final Throwable t) {
+                    error.set(t);
+                } finally {
+                    contextsService.endContext(RequestScoped.class, null);
+                    over.countDown();
+                }
+            }
+        }.start();
+
+        ready.await(1, TimeUnit.MINUTES);
+        sleep(150); // just to ensure we called receive already
+
+        // now send the message
+        try (final JMSContext context = cf.createContext()) {
+            context.createProducer().send(destination3, text);
+        } catch (final JMSRuntimeException ex) {
+            fail(ex.getMessage());
+        }
+
+        over.await(1, TimeUnit.MINUTES);
+
+        // ensure we got the message and no exception
+        final Throwable exception = error.get();
+        if (exception != null) {
+            exception.printStackTrace();
+        }
+        assertNull(exception == null ? "ok" : exception.getMessage(), exception);
+    }
+
+    @Test
+    public void cdiListenerAPI() throws InterruptedException {
+        final String text = TEXT + "4";
+
+        final AtomicReference<Throwable> error = new AtomicReference<>();
+        final CountDownLatch ready = new CountDownLatch(1);
+        final CountDownLatch over = new CountDownLatch(1);
+        new Thread() {
+            {
+                setName(JMS2AMQTest.class.getName() + ".cdiListenerAPI#receiver");
+            }
+
+            @Override
+            public void run() {
+                final ContextsService contextsService = WebBeansContext.currentInstance().getContextsService();
+                contextsService.startContext(RequestScoped.class, null);
+                try {
+                    final JMSConsumer consumer = context.createConsumer(destination3);
+                    consumer.setMessageListener(new MessageListener() {
+                        @Override
+                        public void onMessage(final Message message) {
+                            try {
+                                assertEquals(text, message.getBody(String.class));
+                            } catch (final Throwable e) {
+                                error.set(e);
+                            } finally {
+                                over.countDown();
+                                consumer.close();
+                            }
+                        }
+                    });
+                    ready.countDown();
+                } catch (final Throwable t) {
+                    error.set(t);
+                } finally {
+                    try {
+                        over.await(1, TimeUnit.MINUTES);
+                    } catch (final InterruptedException e) {
+                        Thread.interrupted();
+                    }
+                    contextsService.endContext(RequestScoped.class, null);
+                }
+            }
+        }.start();
+
+        ready.await(1, TimeUnit.MINUTES);
+
+        // now send the message
+        try (final JMSContext context = cf.createContext()) {
+            context.createProducer().send(destination3, text);
+        } catch (final JMSRuntimeException ex) {
+            fail(ex.getMessage());
+        }
+
+        over.await(1, TimeUnit.MINUTES);
+
+        // ensure we got the message and no exception
+        final Throwable exception = error.get();
+        if (exception != null) {
+            exception.printStackTrace();
+        }
+        assertNull(exception == null ? "ok" : exception.getMessage(), exception);
+    }
+
+    @Test
+    public void sendToMdb() throws Exception {
+        try (final JMSContext context = cf.createContext()) {
+            context.createProducer().send(destination, TEXT);
+            assertTrue(Listener.sync());
+        } catch (final JMSRuntimeException ex) {
+            fail(ex.getMessage());
+        }
+    }
+
+    @Test
+    public void receive() throws InterruptedException {
+        final String text = TEXT + "2";
+        final AtomicReference<Throwable> error = new AtomicReference<>();
+        final CountDownLatch ready = new CountDownLatch(1);
+        final CountDownLatch over = new CountDownLatch(1);
+        new Thread() {
+            @Override
+            public void run() {
+                {
+                    setName(JMS2AMQTest.class.getName() + ".receive#receiver");
+                }
+
+                try (final JMSContext context = cf.createContext()) {
+                    try (final JMSConsumer consumer = context.createConsumer(destination2)) {
+                        ready.countDown();
+                        assertEquals(text, consumer.receiveBody(String.class, TimeUnit.MINUTES.toMillis(1)));
+                    }
+                } catch (final Throwable ex) {
+                    error.set(ex);
+                } finally {
+                    over.countDown();
+                }
+            }
+        }.start();
+
+        ready.await(1, TimeUnit.MINUTES);
+        sleep(150); // just to ensure we called receive already
+
+        // now send the message
+        try (final JMSContext context = cf.createContext()) {
+            context.createProducer().send(destination2, text);
+        } catch (final JMSRuntimeException ex) {
+            fail(ex.getMessage());
+        }
+
+        over.await(1, TimeUnit.MINUTES);
+
+        // ensure we got the message and no exception
+        final Throwable exception = error.get();
+        if (exception != null) {
+            exception.printStackTrace();
+        }
+        assertNull(exception == null ? "ok" : exception.getMessage(), exception);
+    }
+
+    @MessageDriven(activationConfig = {
+        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
+        @ActivationConfigProperty(propertyName = "destination", propertyValue = "target")
+    })
+    public static class Listener implements MessageListener {
+        public static volatile CountDownLatch latch;
+        public static volatile boolean ok = false;
+
+        @Override
+        public void onMessage(final Message message) {
+            try {
+                try {
+                    ok = TextMessage.class.isInstance(message) && TEXT.equals(TextMessage.class.cast(message).getText());
+                } catch (final JMSException e) {
+                    // no-op
+                }
+            } finally {
+                latch.countDown();
+            }
+        }
+
+        public static void reset() {
+            latch = new CountDownLatch(1);
+            ok = false;
+        }
+
+        public static boolean sync() throws InterruptedException {
+            latch.await(1, TimeUnit.MINUTES);
+            return ok;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/tomee/blob/1bf768b7/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMSConnectionFactoryTest.java
----------------------------------------------------------------------
diff --git a/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMSConnectionFactoryTest.java b/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMSConnectionFactoryTest.java
new file mode 100644
index 0000000..8c22d6f
--- /dev/null
+++ b/container/openejb-core/src/test/java/org/apache/openejb/activemq/JMSConnectionFactoryTest.java
@@ -0,0 +1,74 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.activemq;
+
+import org.apache.openejb.assembler.classic.OpenEjbConfiguration;
+import org.apache.openejb.assembler.classic.ResourceInfo;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.testing.Classes;
+import org.apache.openejb.testing.SimpleLog;
+import org.apache.openejb.util.reflection.Reflections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.jms.JMSConnectionFactoryDefinition;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+@SimpleLog
+@Classes(cdi = true, innerClassesAsBean = true)
+@RunWith(ApplicationComposer.class)
+public class JMSConnectionFactoryTest {
+    @JMSConnectionFactoryDefinition(name = "testConnectionFactory", maxPoolSize = 5, user = "test", password = "still a test")
+    public static class JMSConfiguration {
+    }
+
+    @Test
+    public void checkConnectionFactoryIsThere() throws NamingException {
+        // auto created
+        assertNotNull(SystemInstance.get().getComponent(ContainerSystem.class).getContainer("Default Managed Container"));
+
+        final List<ResourceInfo> resources = SystemInstance.get().getComponent(OpenEjbConfiguration.class).facilities.resources;
+        boolean found = false;
+        for (final ResourceInfo r : resources) {
+            if (r.id.equals("JMSConnectionFactoryTest/testConnectionFactory")) { // prefixed with app name
+                found = true;
+                break;
+            }
+        }
+        assertTrue(found);
+
+        // these lookup must pass
+        final Context jndiContext = SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext();
+
+        final Object directLookup = jndiContext.lookup("openejb:Resource/testConnectionFactory");
+        assertNotNull(directLookup);
+
+        final Object appLookup = jndiContext.lookup("openejb:Resource/JMSConnectionFactoryTest/testConnectionFactory");
+        assertNotNull(appLookup);
+
+        // facade are not the same but the underlying connection factory should be
+        assertEquals(Reflections.get(directLookup, "factory"), Reflections.get(appLookup, "factory"));
+    }
+}