You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2017/08/02 12:11:08 UTC

[1/6] karaf git commit: [KARAF-5131] XA + JMS support

Repository: karaf
Updated Branches:
  refs/heads/master f7ea3e0cb -> 7a84233c0


http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/JmsService.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/JmsService.java b/jms/src/main/java/org/apache/karaf/jms/JmsService.java
new file mode 100644
index 0000000..0902e33
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/JmsService.java
@@ -0,0 +1,171 @@
+/*
+ * 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.karaf.jms;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JMS Service.
+ */
+public interface JmsService {
+
+    /**
+     * List the JMS connection factories.
+     *
+     * @return The {@link List} of JMS connection factory names.
+     * @throws Exception If the service fails.
+     */
+    List<String> connectionFactories() throws Exception;
+
+    /**
+     * List the JMS connection factories file names.
+     *
+     * @return The {@link List} of JMS connection factory file names.
+     * @throws Exception If the service fails.
+     */
+    List<String> connectionFactoryFileNames() throws Exception;
+
+    /**
+     * Create a new JMS connection factory.
+     *
+     * @param name The JMS connection factory name.
+     * @param type The JMS connection factory type (ActiveMQ, WebsphereMQ, ...).
+     * @param url The JMS URL to use.
+     * @throws Exception If the service fails.
+     */
+    void create(String name, String type, String url) throws Exception;
+
+    /**
+     * Create a new JMS connection factory.
+     *
+     * @param name The JMS connection factory name.
+     * @param type The JMS connection factory type (ActiveMQ, WebsphereMQ, ...).
+     * @param url The JMS URL to use.
+     * @param username The username to use.
+     * @param password The password to use.
+     * @throws Exception If the service fails.
+     */
+    void create(String name, String type, String url, String username, String password) throws Exception;
+
+    /**
+     * Delete a JMS connection factory.
+     *
+     * @param name The JMS connection factory name.
+     * @throws Exception If the service fails.
+     */
+    void delete(String name) throws Exception;
+
+    /**
+     * Get details about a given JMS connection factory.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return A {@link Map} (property/value) containing details.
+     * @throws Exception If the service fails.
+     */
+    Map<String, String> info(String connectionFactory, String username, String password) throws Exception;
+
+    /**
+     * Count the number of messages in a JMS queue.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The queue name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The number of messages in a JMS queue.
+     * @throws Exception If the service fails.
+     */
+    int count(String connectionFactory, String queue, String username, String password) throws Exception;
+
+    /**
+     * List the queues.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The {@link List} of queues.
+     * @throws Exception If the service fails.
+     */
+    List<String> queues(String connectionFactory, String username, String password) throws Exception;
+
+    /**
+     * List the topics.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The {@link List} of topics.
+     * @throws Exception If the service fails.
+     */
+    List<String> topics(String connectionFactory, String username, String password) throws Exception;
+
+    /**
+     * Browse a destination.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The queue name.
+     * @param selector The selector.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The {@link List} of messages.
+     * @throws Exception If the service fails.
+     */
+    List<JmsMessage> browse(String connectionFactory, String queue, String selector, String username, String password) throws Exception;
+
+    /**
+     * Send a message on the given queue.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The queue name.
+     * @param body The message body.
+     * @param replyTo The message replyTo header.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @throws Exception If the service fails.
+     */
+    void send(String connectionFactory, String queue, String body, String replyTo, String username, String password) throws Exception;
+
+    /**
+     * Consume messages from a given destination.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The queue name.
+     * @param selector The messages selector.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The number of messages consumed.
+     * @throws Exception If the service fails.
+     */
+    int consume(String connectionFactory, String queue, String selector, String username, String password) throws Exception;
+
+    /**
+     * Move messages from a destination to another.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param sourceQueue The source queue.
+     * @param targetQueue The target queue.
+     * @param selector The messages selector on the source queue.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The number of messages moved.
+     * @throws Exception If the service fails.
+     */
+    int move(String connectionFactory, String sourceQueue, String targetQueue, String selector, String username, String password) throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java
new file mode 100644
index 0000000..cb86aa6
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java
@@ -0,0 +1,104 @@
+/*
+ * 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.karaf.jms.command;
+
+import java.util.List;
+
+import org.apache.karaf.jms.JmsMessage;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "jms", name = "browse", description = "Browse a JMS queue")
+@Service
+public class BrowseCommand extends JmsConnectionCommandSupport {
+
+    @Argument(index = 1, name = "queue", description = "The JMS queue to browse", required = true, multiValued = false)
+    String queue;
+
+    @Option(name = "-s", aliases = { "--selector" }, description = "The selector to select the messages to browse", required = false, multiValued = false)
+    String selector;
+
+    @Option(name = "-v", aliases = { "--verbose" }, description = "Display JMS properties", required = false, multiValued = false)
+    boolean verbose = false;
+
+    @Override
+    public Object execute() throws Exception {
+
+        ShellTable table = new ShellTable();
+        table.column("Message ID");
+        table.column("Content").maxSize(80);
+        table.column("Charset");
+        table.column("Type");
+        table.column("Correlation ID");
+        table.column("Delivery Mode");
+        table.column("Destination");
+        table.column("Expiration");
+        table.column("Priority");
+        table.column("Redelivered");
+        table.column("ReplyTo");
+        table.column("Timestamp");
+        if (verbose) {
+            table.column("Properties");
+        }
+
+        List<JmsMessage> messages = getJmsService().browse(connectionFactory, queue, selector, username, password);
+        for (JmsMessage message : messages) {
+            if (verbose) {
+                StringBuilder properties = new StringBuilder();
+                for (String property : message.getProperties().keySet()) {
+                    properties.append(property).append("=").append(message.getProperties().get(property)).append("\n");
+                }
+                table.addRow().addContent(
+                        message.getMessageId(),
+                        message.getContent(),
+                        message.getCharset(),
+                        message.getType(),
+                        message.getCorrelationID(),
+                        message.getDeliveryMode(),
+                        message.getDestination(),
+                        message.getExpiration(),
+                        message.getPriority(),
+                        message.isRedelivered(),
+                        message.getReplyTo(),
+                        message.getTimestamp(),
+                        properties.toString());
+            } else {
+                table.addRow().addContent(
+                        message.getMessageId(),
+                        message.getContent(),
+                        message.getCharset(),
+                        message.getType(),
+                        message.getCorrelationID(),
+                        message.getDeliveryMode(),
+                        message.getDestination(),
+                        message.getExpiration(),
+                        message.getPriority(),
+                        message.isRedelivered(),
+                        message.getReplyTo(),
+                        message.getTimestamp());
+            }
+        }
+
+        table.print(System.out);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java
new file mode 100644
index 0000000..b698336
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.karaf.jms.command;
+
+import java.util.List;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "jms", name = "connectionfactories", description = "List the JMS connection factories")
+@Service
+public class ConnectionFactoriesCommand extends JmsCommandSupport {
+
+    @Override
+    public Object execute() throws Exception {
+
+        ShellTable table = new ShellTable();
+        table.column("JMS Connection Factory");
+
+        List<String> connectionFactories = getJmsService().connectionFactories();
+        for (String connectionFactory : connectionFactories) {
+            table.addRow().addContent(connectionFactory);
+        }
+
+        table.print(System.out);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java
new file mode 100644
index 0000000..cd8caaf
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.karaf.jms.command;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jms", name = "consume", description = "Consume messages from a JMS queue.")
+@Service
+public class ConsumeCommand extends JmsConnectionCommandSupport {
+
+    @Argument(index = 1, name = "queue", description = "The JMS queue where to consume messages", required = true, multiValued = false)
+    String queue;
+
+    @Option(name = "-s", aliases = { "--selector" }, description = "The selector to use to select the messages to consume", required = false, multiValued = false)
+    String selector;
+
+    @Override
+    public Object execute() throws Exception {
+        System.out.println(getJmsService().consume(connectionFactory, queue, selector, username, password) + " message(s) consumed");
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/CountCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/CountCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/CountCommand.java
new file mode 100644
index 0000000..576e8dd
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/CountCommand.java
@@ -0,0 +1,41 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "jms", name = "count", description = "Count the number of messages on a JMS queue.")
+@Service
+public class CountCommand extends JmsConnectionCommandSupport {
+
+    @Argument(index = 1, name = "queue", description = "The JMS queue name", required = true, multiValued = false)
+    String queue;
+
+    @Override
+    public Object execute() throws Exception {
+        ShellTable table = new ShellTable();
+        table.column("Messages Count");
+        table.addRow().addContent(getJmsService().count(connectionFactory, queue, username, password));
+        table.print(System.out);
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/CreateCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/CreateCommand.java
new file mode 100644
index 0000000..64ccf02
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/CreateCommand.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.karaf.jms.command;
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+@Command(scope = "jms", name = "create", description = "Create a JMS connection factory.")
+@Service
+public class CreateCommand extends JmsCommandSupport {
+
+    @Argument(index = 0, name = "name", description = "The JMS connection factory name", required = true, multiValued = false)
+    String name;
+
+    @Option(name = "-t", aliases = { "--type" }, description = "The JMS connection factory type (ActiveMQ, Artemis or WebsphereMQ)", required = false, multiValued = false)
+    @Completion(value = StringsCompleter.class, values = { "activemq", "artemis", "webspheremq" })
+    String type = "ActiveMQ";
+
+    @Option(name = "--url", description = "URL of the JMS broker. For WebsphereMQ type, the URL is hostname/port/queuemanager/channel", required = false, multiValued = false)
+    String url = "tcp://localhost:61616";
+
+    @Option(name = "-u", aliases = { "--username" }, description = "Username to connect to the JMS broker", required = false, multiValued = false)
+    String username = "karaf";
+
+    @Option(name = "-p", aliases = { "--password" }, description = "Password to connect to the JMS broker", required = false, multiValued = false)
+    String password = "karaf";
+
+    @Override
+    public Object execute() throws Exception {
+        getJmsService().create(name, type, url, username, password);
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java
new file mode 100644
index 0000000..cab3123
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java
@@ -0,0 +1,40 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import org.apache.karaf.jms.command.completers.ConnectionFactoriesFileNameCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jms", name = "delete", description = "Delete a JMS connection factory")
+@Service
+public class DeleteCommand extends JmsCommandSupport {
+
+    @Argument(index = 0, name = "name", description = "The JMS connection factory name", required = true, multiValued = false)
+    @Completion(ConnectionFactoriesFileNameCompleter.class)
+    String name;
+
+    @Override
+    public Object execute() throws Exception {
+        getJmsService().delete(name);
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/InfoCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/InfoCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/InfoCommand.java
new file mode 100644
index 0000000..354db39
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/InfoCommand.java
@@ -0,0 +1,46 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import java.util.Map;
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "jms", name = "info", description = "Provides details about a JMS connection factory.")
+@Service
+public class InfoCommand extends JmsConnectionCommandSupport {
+
+    @Override
+    public Object execute() throws Exception {
+        ShellTable table = new ShellTable();
+        table.column("Property");
+        table.column("Value");
+
+        Map<String, String> info = getJmsService().info(connectionFactory, username, password);
+        for (String key : info.keySet()) {
+            table.addRow().addContent(key, info.get(key));
+        }
+
+        table.print(System.out);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java b/jms/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java
new file mode 100644
index 0000000..2f5df8f
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java
@@ -0,0 +1,36 @@
+/*
+ * 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.karaf.jms.command;
+
+import org.apache.karaf.jms.JmsService;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+
+public abstract class JmsCommandSupport implements Action {
+
+    @Reference
+    private JmsService jmsService;
+
+    public JmsService getJmsService() {
+        return jmsService;
+    }
+
+    public void setJmsService(JmsService jmsService) {
+        this.jmsService = jmsService;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java b/jms/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java
new file mode 100644
index 0000000..64adfe4
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.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.karaf.jms.command;
+
+import org.apache.karaf.jms.command.completers.ConnectionFactoriesNameCompleter;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Completion;
+import org.apache.karaf.shell.api.action.Option;
+
+/**
+ * For commands that need a connection factory and authentication information 
+ */
+public abstract class JmsConnectionCommandSupport extends JmsCommandSupport {
+
+    @Argument(index = 0, name = "connectionFactory", description = "The JMS connection factory name", required = true, multiValued = false)
+    @Completion(ConnectionFactoriesNameCompleter.class)
+    String connectionFactory;
+
+    @Option(name = "-u", aliases = { "--username" }, description = "Username to connect to the JMS broker", required = false, multiValued = false)
+    String username = "karaf";
+
+    @Option(name = "-p", aliases = { "--password" }, description = "Password to connect to the JMS broker", required = false, multiValued = false)
+    String password = "karaf";
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/MoveCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/MoveCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/MoveCommand.java
new file mode 100644
index 0000000..a4c8d12
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/MoveCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jms", name = "move", description = "Move messages from one JMS queue to another one.")
+@Service
+public class MoveCommand extends JmsConnectionCommandSupport {
+
+    @Argument(index = 1, name = "source", description = "The source JMS queue", required = true, multiValued = false)
+    String source;
+
+    @Argument(index = 2, name = "destination", description = "The destination JMS queue", required = true, multiValued = false)
+    String destination;
+
+    @Option(name = "-s", aliases = { "--selector" }, description = "Selector to move only some messages", required = false, multiValued = false)
+    String selector;
+
+    @Override
+    public Object execute() throws Exception {
+        System.out.println(getJmsService().move(connectionFactory, source, destination, selector, username, password) + " message(s) moved");
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java
new file mode 100644
index 0000000..7cf1dac
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java
@@ -0,0 +1,43 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "jms", name = "queues", description = "List the JMS queues.")
+@Service
+public class QueuesCommand extends JmsConnectionCommandSupport {
+
+    @Override
+    public Object execute() throws Exception {
+        ShellTable table = new ShellTable();
+
+        table.column("JMS Queues");
+
+        for (String queue : getJmsService().queues(connectionFactory, username, password)) {
+            table.addRow().addContent(queue);
+        }
+
+        table.print(System.out);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/SendCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/SendCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/SendCommand.java
new file mode 100644
index 0000000..63d3f4a
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/SendCommand.java
@@ -0,0 +1,44 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+
+@Command(scope = "jms", name = "send", description = "Send a message to ")
+@Service
+public class SendCommand extends JmsConnectionCommandSupport {
+
+    @Argument(index = 1, name = "queue", description = "The JMS queue name", required = true, multiValued = false)
+    String queue;
+
+    @Argument(index = 2, name = "message", description = "The JMS message content", required = true, multiValued = false)
+    String message;
+
+    @Option(name = "-r", aliases = { "--replyTo" }, description = "Set the message ReplyTo", required = false, multiValued = false)
+    String replyTo;
+
+    @Override
+    public Object execute() throws Exception {
+        getJmsService().send(connectionFactory, queue, message, replyTo, username, password);
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java b/jms/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java
new file mode 100644
index 0000000..b583bc4
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java
@@ -0,0 +1,43 @@
+/*
+ * 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.karaf.jms.command;
+
+
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.support.table.ShellTable;
+
+@Command(scope = "jms", name = "topics", description = "List the JMS topics.")
+@Service
+public class TopicsCommand extends JmsConnectionCommandSupport {
+
+    @Override
+    public Object execute() throws Exception {
+        ShellTable table = new ShellTable();
+
+        table.column("JMS Topics");
+
+        for (String topic : getJmsService().topics(connectionFactory, username, password)) {
+            table.addRow().addContent(topic);
+        }
+
+        table.print(System.out);
+
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java b/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java
new file mode 100644
index 0000000..c33ff62
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java
@@ -0,0 +1,59 @@
+/*
+ * 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.karaf.jms.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.jms.JmsService;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+/**
+ * Completer on the JMS connection factory file names.
+ */
+@Service
+public class ConnectionFactoriesFileNameCompleter implements Completer {
+
+    @Reference
+    private JmsService jmsService;
+
+    @Override
+    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+        StringsCompleter delegate = new StringsCompleter();
+        try {
+            for (String connectionFactory : jmsService.connectionFactoryFileNames()) {
+                delegate.getStrings().add(connectionFactory.replace("connectionfactory-", "").replace(".xml", ""));
+            }
+        } catch (Exception e) {
+            // nothing to do
+        }
+        return delegate.complete(session, commandLine, candidates);
+    }
+
+    public JmsService getJmsService() {
+        return jmsService;
+    }
+
+    public void setJmsService(JmsService jmsService) {
+        this.jmsService = jmsService;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java b/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java
new file mode 100644
index 0000000..2fd8d2a
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java
@@ -0,0 +1,59 @@
+/*
+ * 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.karaf.jms.command.completers;
+
+import java.util.List;
+
+import org.apache.karaf.jms.JmsService;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.CommandLine;
+import org.apache.karaf.shell.api.console.Completer;
+import org.apache.karaf.shell.api.console.Session;
+import org.apache.karaf.shell.support.completers.StringsCompleter;
+
+/**
+ * Completer on the JMS connection factories name.
+ */
+@Service
+public class ConnectionFactoriesNameCompleter implements Completer {
+
+    @Reference
+    private JmsService jmsService;
+
+    @Override
+    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+        StringsCompleter delegate = new StringsCompleter();
+        try {
+            for (String connectionFactory : jmsService.connectionFactories()) {
+                delegate.getStrings().add(connectionFactory + " ");
+            }
+        } catch (Exception e) {
+            // nothing to do
+        }
+        return delegate.complete(session, commandLine, candidates);
+    }
+
+    public JmsService getJmsService() {
+        return jmsService;
+    }
+
+    public void setJmsService(JmsService jmsService) {
+        this.jmsService = jmsService;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java b/jms/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java
new file mode 100644
index 0000000..5d87d01
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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.karaf.jms.internal;
+
+import javax.jms.ConnectionMetaData;
+import javax.jms.Destination;
+import javax.jms.JMSConsumer;
+import javax.jms.JMSContext;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.Topic;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+class ActiveMQDestinationSourceFactory implements DestinationSource.Factory {
+
+    @Override
+    public DestinationSource create(JMSContext context) {
+        try {
+            ConnectionMetaData cmd = context.getMetaData();
+            if (cmd.getJMSProviderName().equals("ActiveMQ") && cmd.getProviderVersion().startsWith("5.")) {
+                return type -> getNames(context, type);
+            }
+        } catch (Throwable t) {
+            // Ignore
+        }
+        return null;
+    }
+
+    private List<String> getNames(JMSContext context, DestinationSource.DestinationType type) {
+        try {
+            List<String> names = new ArrayList<>();
+            context.start();
+            String dest = "ActiveMQ.Advisory." +
+                    (type == DestinationSource.DestinationType.Queue ? "Queue" : "Topic");
+            try (JMSConsumer consumer = context.createConsumer(context.createTopic(dest))) {
+                while (true) {
+                    Message message = consumer.receive(100);
+                    if (message == null) {
+                        return names;
+                    }
+                    Destination destination = (Destination) getField(message, "super.dataStructure", "destination");
+                    if (destination instanceof Queue) {
+                        names.add(((Queue) destination).getQueueName());
+                    } else {
+                        names.add(((Topic) destination).getTopicName());
+                    }
+                }
+
+            }
+        } catch (Exception e) {
+            // Ignore
+            String msg = e.toString();
+        }
+        return Collections.emptyList();
+    }
+
+    private static Object getField(Object context, String... fields) throws NoSuchFieldException, IllegalAccessException {
+        Object obj = context;
+        for (String field : fields) {
+            Class cl = obj.getClass();
+            while (field.startsWith("super.")) {
+                cl = cl.getSuperclass();
+                field = field.substring("super.".length());
+            }
+            Field f = cl.getDeclaredField(field);
+            f.setAccessible(true);
+            obj = f.get(obj);
+        }
+        return obj;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java b/jms/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java
new file mode 100644
index 0000000..b81bf64
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java
@@ -0,0 +1,69 @@
+/*
+ * 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.karaf.jms.internal;
+
+import org.apache.karaf.util.json.JsonReader;
+
+import javax.jms.ConnectionMetaData;
+import javax.jms.JMSConsumer;
+import javax.jms.JMSContext;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.TextMessage;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.List;
+
+class ArtemisDestinationSourceFactory implements DestinationSource.Factory {
+
+    @Override
+    public DestinationSource create(JMSContext context) {
+        try {
+            ConnectionMetaData cmd = context.getMetaData();
+            if (cmd.getJMSProviderName().equals("ActiveMQ") && cmd.getProviderVersion().startsWith("2.")) {
+                return type -> getNames(context, type);
+            }
+        } catch (Throwable t) {
+            // Ignore
+        }
+        return null;
+    }
+
+    private List<String> getNames(JMSContext context, DestinationSource.DestinationType type) {
+        try {
+            Queue managementQueue = context.createQueue("activemq.management");
+            Queue replyTo = context.createTemporaryQueue();
+
+            context.start();
+
+            String routing = type == DestinationSource.DestinationType.Queue ? "ANYCAST" : "MULTICAST";
+            context.createProducer()
+                    .setProperty("_AMQ_ResourceName", "broker")
+                    .setProperty("_AMQ_OperationName", "getQueueNames")
+                    .setJMSReplyTo(replyTo)
+                    .send(managementQueue, "[\"" + routing + "\"]");
+            try (JMSConsumer consumer = context.createConsumer(replyTo)) {
+                Message reply = consumer.receive(500);
+                String json = ((TextMessage) reply).getText();
+                List<?> array = (List<?>) JsonReader.read(new StringReader(json));
+                return (List<String>) array.get(0);
+            }
+        } catch (Exception e) {
+            return Collections.emptyList();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java b/jms/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java
new file mode 100644
index 0000000..0593bc4
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java
@@ -0,0 +1,36 @@
+/*
+ * 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.karaf.jms.internal;
+
+import javax.jms.Connection;
+import javax.jms.JMSContext;
+import javax.jms.JMSException;
+import java.util.List;
+
+interface DestinationSource {
+
+    enum DestinationType {
+        Queue, Topic
+    }
+
+    interface Factory {
+
+        DestinationSource create(JMSContext context);
+    }
+
+    List<String> getNames(DestinationType type);
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java b/jms/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java
new file mode 100644
index 0000000..e3b7801
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java
@@ -0,0 +1,164 @@
+/*
+ * 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.karaf.jms.internal;
+
+import org.apache.karaf.jms.JmsMBean;
+import org.apache.karaf.jms.JmsMessage;
+import org.apache.karaf.jms.JmsService;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.*;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Default implementation of the JMS MBean.
+ */
+public class JmsMBeanImpl implements JmsMBean {
+
+    private JmsService jmsService;
+
+    @Override
+    public List<String> getConnectionfactories() throws MBeanException {
+        try {
+            return jmsService.connectionFactories();
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public void create(String name, String type, String url) throws MBeanException {
+        try {
+            jmsService.create(name, type, url);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public void create(String name, String type, String url, String username, String password) throws MBeanException {
+        try {
+            jmsService.create(name, type, url, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public void delete(String name) throws MBeanException {
+        try {
+            jmsService.delete(name);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public Map<String, String> info(String connectionFactory, String username, String password) throws MBeanException {
+        try {
+            return jmsService.info(connectionFactory, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public int count(String connectionFactory, String queue, String username, String password) throws MBeanException {
+        try {
+            return jmsService.count(connectionFactory, queue, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public List<String> queues(String connectionFactory, String username, String password) throws MBeanException {
+        try {
+            return jmsService.queues(connectionFactory, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public List<String> topics(String connectionFactory, String username, String password) throws MBeanException {
+        try {
+            return jmsService.topics(connectionFactory, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public void send(String connectionFactory, String queue, String content, String replyTo, String username, String password) throws MBeanException {
+        try {
+            jmsService.send(connectionFactory, queue, content, replyTo, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public int consume(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException {
+        try {
+            return jmsService.consume(connectionFactory, queue, selector, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public int move(String connectionFactory, String source, String destination, String selector, String username, String password) throws MBeanException {
+        try {
+            return jmsService.move(connectionFactory, source, destination, selector, username, password);
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    @Override
+    public TabularData browse(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException {
+        try {
+            CompositeType type = new CompositeType("message", "JMS Message",
+                    new String[]{ "id", "content", "charset", "type", "correlation", "delivery", "destination", "expiration", "priority", "redelivered", "replyto", "timestamp" },
+                    new String[]{ "Message ID", "Content", "Charset", "Type", "Correlation ID", "Delivery Mode", "Destination", "Expiration Date", "Priority", "Redelivered", "Reply-To", "Timestamp" },
+                    new OpenType[]{ SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.STRING });
+            TabularType tableType = new TabularType("messages", "JMS Messages", type, new String[]{ "id" });
+            TabularData table = new TabularDataSupport(tableType);
+            for (JmsMessage message : getJmsService().browse(connectionFactory, queue, selector, username, password)) {
+                CompositeData data = new CompositeDataSupport(type,
+                        new String[]{ "id", "content", "charset", "type", "correlation", "delivery", "destination", "expiration", "priority", "redelivered", "replyto", "timestamp" },
+                        new Object[]{ message.getMessageId(), message.getContent(), message.getCharset(), message.getType(), message.getCorrelationID(), message.getDeliveryMode(), message.getDestination(), message.getExpiration(), message.getPriority(), message.isRedelivered(), message.getReplyTo(), message.getTimestamp() }
+                        );
+                table.put(data);
+            }
+            return table;
+        } catch (Throwable t) {
+            throw new MBeanException(null, t.getMessage());
+        }
+    }
+
+    public JmsService getJmsService() {
+        return jmsService;
+    }
+
+    public void setJmsService(JmsService jmsService) {
+        this.jmsService = jmsService;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java b/jms/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java
new file mode 100644
index 0000000..8dcbf94
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java
@@ -0,0 +1,285 @@
+/*
+ * 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.karaf.jms.internal;
+
+import org.apache.karaf.jms.JmsMessage;
+import org.apache.karaf.jms.JmsService;
+import org.ops4j.pax.jms.service.ConnectionFactoryFactory;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+import javax.jms.*;
+import javax.jms.Queue;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Default implementation of the JMS Service.
+ */
+public class JmsServiceImpl implements JmsService {
+
+    private BundleContext bundleContext;
+    private ConfigurationAdmin configAdmin;
+    private Path deployFolder;
+    
+    public JmsServiceImpl() {
+        deployFolder = Paths.get(System.getProperty("karaf.base"), "deploy");
+    }
+
+    @Override
+    public void create(String name, String type, String url) throws Exception {
+        create(name, type, url, null, null);
+    }
+
+    @Override
+    public void create(String name, String type, String url, String username, String password) throws Exception {
+        if (type == null) {
+            throw new IllegalArgumentException("JMS connection factory type not known");
+        }
+
+        if (connectionFactories().contains(name)) {
+            throw new IllegalArgumentException("There is already a ConnectionFactory with the name " + name);
+        }
+
+        Dictionary<String, String> properties = new Hashtable<>();
+        properties.put("osgi.jndi.service.name", "jms/" + name);
+        properties.put(ConnectionFactoryFactory.JMS_CONNECTIONFACTORY_NAME, name);
+        properties.put(ConnectionFactoryFactory.JMS_CONNECTIONFACTORY_TYPE, type);
+        put(properties, ConnectionFactoryFactory.JMS_URL, url);
+        put(properties, ConnectionFactoryFactory.JMS_USER, username);
+        put(properties, ConnectionFactoryFactory.JMS_PASSWORD, password);
+        Configuration config = configAdmin.createFactoryConfiguration("org.ops4j.connectionfactory", null);
+        config.update(properties);
+    }
+
+    private void put(Dictionary<String, String> properties, String key, String value) {
+        if (value != null) {
+            properties.put(key, value);
+        }
+    }
+
+    @Override
+    public void delete(String name) throws Exception {
+        String filter = String.format("(&(service.factoryPid=org.ops4j.connectionfactory)(%s=%s))", ConnectionFactoryFactory.JMS_CONNECTIONFACTORY_NAME, name);
+        Configuration[] configs = configAdmin.listConfigurations(filter);
+        for (Configuration config : configs) {
+            config.delete();
+        }
+    }
+
+    @Override
+    public List<String> connectionFactories() throws Exception {
+        return bundleContext.getServiceReferences(ConnectionFactory.class, null).stream()
+                .map(this::getConnectionFactoryName)
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
+    private String getConnectionFactoryName(ServiceReference<ConnectionFactory> reference) {
+        if (reference.getProperty("osgi.jndi.service.name") != null) {
+            return (String) reference.getProperty("osgi.jndi.service.name");
+        } else if (reference.getProperty("name") != null) {
+            return (String) reference.getProperty("name");
+        } else {
+            return reference.getProperty(Constants.SERVICE_ID).toString();
+        }
+    }
+
+    @Override
+    public List<String> connectionFactoryFileNames() throws Exception {
+        return Files.list(deployFolder)
+                .map(Path::getFileName)
+                .map(Path::toString)
+                .filter(name -> name.startsWith("connectionfactory-") && name.endsWith(".xml"))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Map<String, String> info(String connectionFactory, String username, String password) throws IOException, JMSException {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            ConnectionMetaData metaData = context.getMetaData();
+            Map<String, String> map = new HashMap<>();
+            map.put("product", metaData.getJMSProviderName());
+            map.put("version", metaData.getProviderVersion());
+            return map;
+        }
+    }
+
+    @Override
+    public int count(String connectionFactory, final String destination, String username, String password) throws IOException, JMSException {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            try (QueueBrowser browser = context.createBrowser(context.createQueue(destination))) {
+                @SuppressWarnings("unchecked")
+                Enumeration<Message> enumeration = browser.getEnumeration();
+                int count = 0;
+                while (enumeration.hasMoreElements()) {
+                    enumeration.nextElement();
+                    count++;
+                }
+                return count;
+            }
+        }
+    }
+
+    private JMSContext createContext(String name, String username, String password) {
+        return createContext(name, username, password, JMSContext.AUTO_ACKNOWLEDGE);
+    }
+
+    private JMSContext createContext(String name, String username, String password, int sessionMode) {
+        ServiceReference<ConnectionFactory> sr = lookupConnectionFactory(name);
+        ConnectionFactory cf = bundleContext.getService(sr);
+        try {
+            return cf.createContext(username, password, sessionMode);
+        } finally {
+            bundleContext.ungetService(sr);
+        }
+    }
+
+    private ServiceReference<ConnectionFactory> lookupConnectionFactory(String name) {
+        try {
+            Collection<ServiceReference<ConnectionFactory>> references = bundleContext.getServiceReferences(
+                    ConnectionFactory.class,
+                    "(|(osgi.jndi.service.name=" + name + ")(name=" + name + ")(service.id=" + name + "))");
+            return references.stream()
+                    .sorted(Comparator.<ServiceReference<?>>naturalOrder().reversed())
+                    .findFirst()
+                    .orElseThrow(() -> new IllegalArgumentException("No JMS connection factory found for " + name));
+        } catch (InvalidSyntaxException e) {
+            throw new RuntimeException("Error finding connection factory service " + name, e);
+        }
+    }
+
+    private DestinationSource getDestinationSource(JMSContext context) throws JMSException {
+        List<DestinationSource.Factory> factories = Arrays.asList(
+                new ActiveMQDestinationSourceFactory(),
+                new ArtemisDestinationSourceFactory()
+        );
+        DestinationSource source = null;
+        for (DestinationSource.Factory factory : factories) {
+            source = factory.create(context);
+            if (source != null) {
+                break;
+            }
+        }
+        if (source == null) {
+            source = d -> Collections.emptyList();
+        }
+        return source;
+    }
+    
+    @Override
+    public List<String> queues(String connectionFactory, String username, String password) throws JMSException, IOException {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            return getDestinationSource(context).getNames(DestinationSource.DestinationType.Queue);
+        }
+    }
+
+    @Override
+    public List<String> topics(String connectionFactory, String username, String password) throws IOException, JMSException {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            return getDestinationSource(context).getNames(DestinationSource.DestinationType.Topic);
+        }
+    }
+
+    @Override
+    public List<JmsMessage> browse(String connectionFactory, final String queue, final String filter,
+                                   String username, String password) throws JMSException, IOException {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            try (QueueBrowser browser = context.createBrowser(context.createQueue(queue), filter)) {
+                List<JmsMessage> messages = new ArrayList<>();
+                @SuppressWarnings("unchecked")
+                Enumeration<Message> enumeration = browser.getEnumeration();
+                while (enumeration.hasMoreElements()) {
+                    Message message = enumeration.nextElement();
+
+                    messages.add(new JmsMessage(message));
+                }
+                return messages;
+            }
+        }
+    }
+
+    @Override
+    public void send(String connectionFactory, final String queue, final String body, final String replyTo,
+                     String username, String password) throws IOException, JMSException {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            JMSProducer producer = context.createProducer();
+            if (replyTo != null) {
+                producer.setJMSReplyTo(context.createQueue(replyTo));
+            }
+            producer.send(context.createQueue(queue), body);
+        }
+    }
+
+    @Override
+    public int consume(String connectionFactory, final String queue, final String selector, String username,
+                       String password) throws Exception {
+        try (JMSContext context = createContext(connectionFactory, username, password)) {
+            try (JMSConsumer consumer = context.createConsumer(context.createQueue(queue), selector)) {
+                int count = 0;
+                Message message;
+                do {
+                    message = consumer.receive(500L);
+                    if (message != null) {
+                        count++;
+                    }
+                } while (message != null);
+                return count;
+            }
+        }
+    }
+
+    @Override
+    public int move(String connectionFactory, final String sourceQueue, final String targetQueue,
+                    final String selector, String username, String password) throws IOException, JMSException {
+        try (JMSContext context = createContext(connectionFactory, username, password, JMSContext.SESSION_TRANSACTED)) {
+            Queue source = context.createQueue(sourceQueue);
+            Queue target = context.createQueue(targetQueue);
+            try (JMSConsumer consumer = context.createConsumer(source, selector)) {
+                int count = 0;
+                while (true) {
+                    Message message = consumer.receive(500L);
+                    if (message != null) {
+                        context.createProducer().send(target, message);
+                        context.commit();
+                        count++;
+                    } else {
+                        break;
+                    }
+                }
+                return count;
+            }
+        }
+   }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
+        this.configAdmin = configAdmin;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java b/jms/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java
new file mode 100644
index 0000000..16ac799
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java
@@ -0,0 +1,38 @@
+package org.apache.karaf.jms.internal.osgi;
+
+import org.apache.karaf.jms.JmsService;
+import org.apache.karaf.jms.internal.JmsMBeanImpl;
+import org.apache.karaf.jms.internal.JmsServiceImpl;
+import org.apache.karaf.shell.api.console.CommandLoggingFilter;
+import org.apache.karaf.shell.support.RegexCommandLoggingFilter;
+import org.apache.karaf.util.tracker.BaseActivator;
+import org.apache.karaf.util.tracker.annotation.ProvideService;
+import org.apache.karaf.util.tracker.annotation.RequireService;
+import org.apache.karaf.util.tracker.annotation.Services;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+@Services(
+        provides = @ProvideService(JmsService.class),
+        requires = @RequireService(ConfigurationAdmin.class)
+)
+public class Activator extends BaseActivator {
+    @Override
+    protected void doStart() throws Exception {
+        ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
+
+        JmsServiceImpl service = new JmsServiceImpl();
+        service.setBundleContext(bundleContext);
+        service.setConfigAdmin(configurationAdmin);
+        register(JmsService.class, service);
+
+        JmsMBeanImpl mbean = new JmsMBeanImpl();
+        mbean.setJmsService(service);
+        registerMBean(mbean, "type=jms");
+
+        RegexCommandLoggingFilter filter = new RegexCommandLoggingFilter();
+        filter.addRegEx("create +.*?--password ([^ ]+)", 2);
+        filter.addRegEx("create +.*?-p ([^ ]+)", 2);
+        register(CommandLoggingFilter.class, filter);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/jms/src/main/resources/OSGI-INF/bundle.info b/jms/src/main/resources/OSGI-INF/bundle.info
new file mode 100644
index 0000000..3624846
--- /dev/null
+++ b/jms/src/main/resources/OSGI-INF/bundle.info
@@ -0,0 +1,41 @@
+#
+#
+#    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.
+#
+#
+h1. Synopsis
+
+	${project.name}
+
+	${project.description}
+
+	Maven URL:
+		[mvn:${project.groupId}/${project.artifactId}/${project.version}]
+
+h1. Description
+
+	This bundle is the core implementation of the JMS service support.
+
+	The JMS service allows you to create connection factories, and send/browse/consume messages.
+
+h1. Commands
+
+	The bundle contains the following commands:
+\${command-list|jms|indent=8,list,cyan}
+
+h1. See also
+
+	JMS - section of the Karaf User Guide

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index f66ec96..53e1e81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -242,7 +242,9 @@
         <aries.transaction.blueprint.version>1.1.1</aries.transaction.blueprint.version>
         <aries.transaction.blueprint.version2>2.1.0</aries.transaction.blueprint.version2>
         <aries.util.version>1.1.3</aries.util.version>
+        <atomikos.version>4.0.4</atomikos.version>
 
+        <geronimo.transaction.manager.version>3.1.3</geronimo.transaction.manager.version>
         <guava.version>20.0</guava.version>
         <narayana.version>5.6.3.Final</narayana.version>
         <hibernate.annotations.common.version>3.3.0.ga</hibernate.annotations.common.version>
@@ -273,7 +275,9 @@
         <pax.url.version>2.5.2</pax.url.version>
         <pax.web.version>6.0.6</pax.web.version>
         <pax.tinybundle.version>2.1.1</pax.tinybundle.version>
-        <pax.jdbc.version>1.1.0</pax.jdbc.version>
+        <pax.jdbc.version>1.2.0-SNAPSHOT</pax.jdbc.version>
+        <pax.jms.version>0.0.1-SNAPSHOT</pax.jms.version>
+        <pax.transx.version>0.2.0-SNAPSHOT</pax.transx.version>
 
         <portlet-api.version>2.0</portlet-api.version>
         <slf4j.version>1.7.12</slf4j.version>


[4/6] karaf git commit: [KARAF-5131] XA + JMS support

Posted by gn...@apache.org.
[KARAF-5131] XA + JMS support

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/7a84233c
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/7a84233c
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/7a84233c

Branch: refs/heads/master
Commit: 7a84233c0eb13568ee797c1e623285af427fdcdf
Parents: d1ce154
Author: Guillaume Nodet <gn...@apache.org>
Authored: Wed Aug 2 10:36:31 2017 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Wed Aug 2 14:10:48 2017 +0200

----------------------------------------------------------------------
 .../src/main/feature/feature.xml                |   2 +-
 assemblies/features/enterprise/pom.xml          |   5 -
 .../enterprise/src/main/feature/feature.xml     |  57 +-
 .../standard/src/main/feature/feature.xml       |   2 +
 .../java/org/apache/karaf/itests/JmsTest.java   |   2 +-
 .../karaf/jdbc/internal/JdbcServiceImpl.java    |   2 +-
 jms/NOTICE                                      |  67 +++
 jms/core/NOTICE                                 |  67 ---
 jms/core/pom.xml                                | 123 -----
 .../java/org/apache/karaf/jms/JmsMBean.java     | 165 ------
 .../java/org/apache/karaf/jms/JmsMessage.java   | 164 ------
 .../java/org/apache/karaf/jms/JmsService.java   | 171 ------
 .../apache/karaf/jms/command/BrowseCommand.java | 104 ----
 .../jms/command/ConnectionFactoriesCommand.java |  45 --
 .../karaf/jms/command/ConsumeCommand.java       |  40 --
 .../apache/karaf/jms/command/CountCommand.java  |  41 --
 .../apache/karaf/jms/command/CreateCommand.java |  52 --
 .../apache/karaf/jms/command/DeleteCommand.java |  40 --
 .../apache/karaf/jms/command/InfoCommand.java   |  46 --
 .../karaf/jms/command/JmsCommandSupport.java    |  36 --
 .../command/JmsConnectionCommandSupport.java    |  39 --
 .../apache/karaf/jms/command/MoveCommand.java   |  44 --
 .../apache/karaf/jms/command/QueuesCommand.java |  43 --
 .../apache/karaf/jms/command/SendCommand.java   |  44 --
 .../apache/karaf/jms/command/TopicsCommand.java |  43 --
 .../ConnectionFactoriesFileNameCompleter.java   |  59 --
 .../ConnectionFactoriesNameCompleter.java       |  59 --
 .../ActiveMQDestinationSourceFactory.java       |  68 ---
 .../ArtemisDestinationSourceFactory.java        |  63 ---
 .../karaf/jms/internal/DestinationSource.java   |  35 --
 .../apache/karaf/jms/internal/JmsConnector.java | 108 ----
 .../apache/karaf/jms/internal/JmsMBeanImpl.java | 164 ------
 .../karaf/jms/internal/JmsServiceImpl.java      | 285 ----------
 .../karaf/jms/internal/osgi/Activator.java      |  32 --
 .../src/main/resources/OSGI-INF/bundle.info     |  41 --
 .../jms/internal/connectionfactory-activemq.xml |  34 --
 .../jms/internal/connectionfactory-artemis.xml  |  35 --
 .../internal/connectionfactory-webspheremq.xml  |  35 --
 jms/pom.xml                                     | 111 +++-
 jms/pool/pom.xml                                | 104 ----
 .../karaf/jms/pool/internal/ConnectionKey.java  |  75 ---
 .../karaf/jms/pool/internal/ConnectionPool.java | 315 -----------
 .../jms/pool/internal/IntrospectionSupport.java | 123 -----
 .../jms/pool/internal/PooledConnection.java     | 285 ----------
 .../pool/internal/PooledConnectionFactory.java  | 538 -------------------
 .../pool/internal/PooledMessageConsumer.java    |  76 ---
 .../karaf/jms/pool/internal/PooledProducer.java | 168 ------
 .../jms/pool/internal/PooledQueueSender.java    |  51 --
 .../karaf/jms/pool/internal/PooledSession.java  | 497 -----------------
 .../internal/PooledSessionEventListener.java    |  48 --
 .../jms/pool/internal/PooledTopicPublisher.java |  57 --
 .../karaf/jms/pool/internal/SessionKey.java     |  65 ---
 .../karaf/jms/pool/internal/osgi/Activator.java | 180 -------
 .../java/org/apache/karaf/jms/JmsMBean.java     | 165 ++++++
 .../java/org/apache/karaf/jms/JmsMessage.java   | 164 ++++++
 .../java/org/apache/karaf/jms/JmsService.java   | 171 ++++++
 .../apache/karaf/jms/command/BrowseCommand.java | 104 ++++
 .../jms/command/ConnectionFactoriesCommand.java |  45 ++
 .../karaf/jms/command/ConsumeCommand.java       |  40 ++
 .../apache/karaf/jms/command/CountCommand.java  |  41 ++
 .../apache/karaf/jms/command/CreateCommand.java |  52 ++
 .../apache/karaf/jms/command/DeleteCommand.java |  40 ++
 .../apache/karaf/jms/command/InfoCommand.java   |  46 ++
 .../karaf/jms/command/JmsCommandSupport.java    |  36 ++
 .../command/JmsConnectionCommandSupport.java    |  39 ++
 .../apache/karaf/jms/command/MoveCommand.java   |  44 ++
 .../apache/karaf/jms/command/QueuesCommand.java |  43 ++
 .../apache/karaf/jms/command/SendCommand.java   |  44 ++
 .../apache/karaf/jms/command/TopicsCommand.java |  43 ++
 .../ConnectionFactoriesFileNameCompleter.java   |  59 ++
 .../ConnectionFactoriesNameCompleter.java       |  59 ++
 .../ActiveMQDestinationSourceFactory.java       |  89 +++
 .../ArtemisDestinationSourceFactory.java        |  69 +++
 .../karaf/jms/internal/DestinationSource.java   |  36 ++
 .../apache/karaf/jms/internal/JmsMBeanImpl.java | 164 ++++++
 .../karaf/jms/internal/JmsServiceImpl.java      | 285 ++++++++++
 .../karaf/jms/internal/osgi/Activator.java      |  38 ++
 jms/src/main/resources/OSGI-INF/bundle.info     |  41 ++
 pom.xml                                         |   6 +-
 79 files changed, 2168 insertions(+), 4950 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/assemblies/features/enterprise-legacy/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise-legacy/src/main/feature/feature.xml b/assemblies/features/enterprise-legacy/src/main/feature/feature.xml
index 8d221b6..56cd7ae 100644
--- a/assemblies/features/enterprise-legacy/src/main/feature/feature.xml
+++ b/assemblies/features/enterprise-legacy/src/main/feature/feature.xml
@@ -29,7 +29,7 @@
 
     <feature name="transaction" description="OSGi Transaction Manager" version="${aries.transaction.manager.version}">
         <details>JTA implementation provided by Apache Aries Transaction</details>
-        <feature version="${aries.transaction.manager.version}">transaction-manager-geronimo</feature>
+        <feature version="${geronimo.transaction.manager.version}">transaction-manager-geronimo</feature>
     </feature>
 
     <feature name="jpa" description="OSGi Persistence Container" version="${aries.jpa.container.context.version}">

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/assemblies/features/enterprise/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/pom.xml b/assemblies/features/enterprise/pom.xml
index 8557860..8f6c0b6 100644
--- a/assemblies/features/enterprise/pom.xml
+++ b/assemblies/features/enterprise/pom.xml
@@ -53,11 +53,6 @@
             <artifactId>org.apache.aries.transaction.blueprint</artifactId>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.aries.transaction</groupId>
-            <artifactId>org.apache.aries.transaction.manager</artifactId>
-            <scope>provided</scope>
-        </dependency>
 
         <!-- jpa deps -->
         <dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/assemblies/features/enterprise/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/src/main/feature/feature.xml b/assemblies/features/enterprise/src/main/feature/feature.xml
index 6b6fa04..f9b6ab7 100644
--- a/assemblies/features/enterprise/src/main/feature/feature.xml
+++ b/assemblies/features/enterprise/src/main/feature/feature.xml
@@ -24,6 +24,8 @@
     <repository>mvn:org.hibernate/hibernate-osgi/${hibernate.version}/xml/karaf</repository>
     <repository>mvn:org.ops4j.pax.cdi/pax-cdi-features/${pax.cdi.version}/xml/features</repository>
     <repository>mvn:org.ops4j.pax.jdbc/pax-jdbc-features/${pax.jdbc.version}/xml/features</repository>
+    <repository>mvn:org.ops4j.pax.jms/pax-jms-features/${pax.jms.version}/xml/features</repository>
+    <repository>mvn:org.ops4j.pax.transx/pax-transx-features/${pax.transx.version}/xml/features</repository>
     <repository>mvn:org.apache.karaf.features/standard/${project.version}/xml/features</repository>
     <repository>mvn:org.apache.aries.jpa/jpa-features/${aries.jpa.version}/xml/features</repository>
     
@@ -33,21 +35,21 @@
         <bundle dependency="true">mvn:javax.el/javax.el-api/3.0.0</bundle>
         <bundle dependency="true">mvn:javax.enterprise/cdi-api/1.2</bundle>
         <bundle>mvn:javax.transaction/javax.transaction-api/1.2</bundle>
+        <feature>pax-transx-tm-api</feature>
     </feature>
 
-    <feature name="transaction-manager-geronimo" description="Geronimo Transaction Manager" version="${aries.transaction.manager.version}">
+    <feature name="transaction-manager-geronimo" description="Geronimo Transaction Manager" version="${geronimo.transaction.manager.version}">
         <details>JTA implementation provided by Apache Aries Transaction</details>
-        <config name="org.apache.aries.transaction">
-            aries.transaction.recoverable = true
-            aries.transaction.timeout = 600
-            aries.transaction.howl.logFileDir = ${karaf.data}/txlog
-            aries.transaction.howl.maxLogFiles = 2
-            aries.transaction.howl.maxBlocksPerFile = 512
-            aries.transaction.howl.bufferSize = 4
+        <config name="org.ops4j.pax.transx.tm.geronimo">
+            org.apache.geronimo.tm.recoverable = true
+            org.apache.geronimo.tm.timeout = 600
+            org.apache.geronimo.tm.howl.logFileDir = ${karaf.data}/txlog
+            org.apache.geronimo.tm.howl.maxLogFiles = 2
+            org.apache.geronimo.tm.howl.maxBlocksPerFile = 512
+            org.apache.geronimo.tm.howl.bufferSize = 4
         </config>
         <feature version="[1.1,2)">transaction-api</feature>
-        <bundle dependency="true">mvn:org.apache.aries/org.apache.aries.util/${aries.util.version}</bundle>
-        <bundle>mvn:org.apache.aries.transaction/org.apache.aries.transaction.manager/${aries.transaction.manager.version}</bundle>
+        <feature>pax-transx-tm-geronimo</feature>
         <capability>
             transaction-manager;provider:=geronimo
         </capability>
@@ -55,17 +57,30 @@
 
     <feature name="transaction-manager-narayana" description="Narayana Transaction Manager" version="${narayana.version}">
         <details>JTA implementation provided by Narayana</details>
-        <config name="org.jboss.narayana">
-            ObjectStoreEnvironmentBean.objectStoreDir=${karaf.data}/narayana
-            ObjectStoreEnvironmentBean.communicationStore.objectStoreDir=${karaf.data}/narayana
-            HornetqJournalEnvironmentBean.storeDir=${karaf.data}/narayana/hornetq
+        <config name="org.ops4j.pax.transx.tm.narayana">
+            com.arjuna.ats.arjuna.objectstore.objectStoreDir=${karaf.data}/narayana
+            com.arjuna.ats.arjuna.objectstore.communicationStore.objectStoreDir=${karaf.data}/narayana
+            com.arjuna.ats.arjuna.hornetqjournal.storeDir=${karaf.data}/narayana/hornetq
         </config>
-        <bundle>mvn:org.jboss.narayana.osgi/narayana-osgi-jta/${narayana.version}</bundle>
+        <feature version="[1.1,2)">transaction-api</feature>
+        <feature>pax-transx-tm-narayana</feature>
         <capability>
             transaction-manager;provider:=narayana
         </capability>
     </feature>
 
+    <feature name="transaction-manager-atomikos" description="Atomikos Transaction Manager" version="${atomikos.version}">
+        <details>JTA implementation provided by Atomikos</details>
+        <config name="org.ops4j.pax.transx.tm.atomikos">
+            com.atomikos.icatch.log_base_dir=${karaf.data}/atomikos
+        </config>
+        <feature version="[1.1,2)">transaction-api</feature>
+        <feature>pax-transx-tm-atomikos</feature>
+        <capability>
+            transaction-manager;provider:=atomikos
+        </capability>
+    </feature>
+
     <feature name="transaction" description="OSGi Transaction Manager" version="2.0">
         <details>JTA Support</details>
         <feature dependency="true">transaction-manager-geronimo</feature>
@@ -158,21 +173,13 @@
 
     <feature name="jms" description="JMS service and commands" version="${project.version}">
         <details>JMS support provinding service, commands, and MBean.</details>
-        <feature dependency="true">aries-blueprint</feature>
+        <feature>pax-jms-pool</feature>
+        <feature>transaction</feature>
         <bundle dependency="true">mvn:javax.jms/javax.jms-api/2.0</bundle>
         <bundle dependency="true">mvn:org.apache.geronimo.specs/geronimo-jta_1.1_spec/${geronimo.jta-spec.version}</bundle>
         <bundle dependency="true">mvn:org.apache.geronimo.specs/geronimo-jms_1.1_spec/${geronimo.jms-spec.version}</bundle>
         <bundle dependency="true">mvn:org.apache.commons/commons-pool2/2.4.2</bundle>
         <bundle>mvn:org.apache.karaf.jms/org.apache.karaf.jms.core/${project.version}</bundle>
-        <bundle>mvn:org.apache.karaf.jms/org.apache.karaf.jms.pool/${project.version}</bundle>
-        <!--
-            Requirement on Blueprint.
-            We don't use a feature dependency to allow the choice between aries-blueprint and gemini-blueprint.
-            This means that you need to install one of the above to be able to install the jdbc feature.
-        -->
-        <requirement>
-            osgi.extender;filter:="(&amp;(osgi.extender=osgi.blueprint)(version>=1.0))"
-        </requirement>
     </feature>
 
     <feature name="application-without-isolation" description="Provide EBA archive support" version="${aries.application.version}">

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index 32aaa9d..61f13bf 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -79,7 +79,9 @@
             hawtio=mvn:io.hawt/hawtio-karaf/RELEASE/xml/features
             pax-cdi=mvn:org.ops4j.pax.cdi/pax-cdi-features/RELEASE/xml/features
             pax-jdbc=mvn:org.ops4j.pax.jdbc/pax-jdbc-features/RELEASE/xml/features
+            pax-jms=mvn:org.ops4j.pax.jms/pax-jms-features/RELEASE/xml/features
             pax-jpa=mvn:org.ops4j.pax.jpa/pax-jpa-features/RELEASE/xml/features
+            pax-transx=mvn:org.ops4j.pax.transx/pax-transx-features/RELEASE/xml/features
             pax-web=mvn:org.ops4j.pax.web/pax-web-features/RELEASE/xml/features
             pax-wicket=mvn:org.ops4j.pax.wicket/pax-wicket-features/RELEASE/xml/features
             ecf=http://download.eclipse.org/rt/ecf/RELEASE/site.p2/karaf-features.xml

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/itests/src/test/java/org/apache/karaf/itests/JmsTest.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/JmsTest.java b/itests/src/test/java/org/apache/karaf/itests/JmsTest.java
index 21487de..417b9e5 100644
--- a/itests/src/test/java/org/apache/karaf/itests/JmsTest.java
+++ b/itests/src/test/java/org/apache/karaf/itests/JmsTest.java
@@ -72,7 +72,7 @@ public class JmsTest extends KarafTestSupport {
 
     @Test(timeout = 60000)
     public void testCommands() throws Exception {
-        execute("jms:create -t ActiveMQ -u karaf -p karaf --url tcp://localhost:61616 test");
+        execute("jms:create -t activemq -u karaf -p karaf --url tcp://localhost:61616 test");
         waitForConnectionFactory("name=test");
 
         assertThat(execute("jms:connectionfactories"), containsString("jms/test"));

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
----------------------------------------------------------------------
diff --git a/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java b/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
index bcaa016..aa367c9 100644
--- a/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
+++ b/jdbc/src/main/java/org/apache/karaf/jdbc/internal/JdbcServiceImpl.java
@@ -82,7 +82,7 @@ public class JdbcServiceImpl implements JdbcService {
 
     @Override
     public void delete(String name) throws Exception {
-        String filter = String.format("(%s=%s)", DataSourceFactory.JDBC_DATASOURCE_NAME, name);
+        String filter = String.format("(&(service.factoryPid=org.ops4j.datasource)(%s=%s))", DataSourceFactory.JDBC_DATASOURCE_NAME, name);
         Configuration[] configs = configAdmin.listConfigurations(filter);
         for (Configuration config : configs) {
             config.delete();

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/NOTICE
----------------------------------------------------------------------
diff --git a/jms/NOTICE b/jms/NOTICE
new file mode 100644
index 0000000..ec9092f
--- /dev/null
+++ b/jms/NOTICE
@@ -0,0 +1,67 @@
+Apache Karaf
+Copyright 2010-2014 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+OW2 (http://www.ow2.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+OPS4J (http://www.ops4j.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Eclipse Foundation (http://www.eclipse.org/).
+Licensed under the EPL.
+
+This product includes software written by
+Antony Lesuisse.
+Licensed under Public Domain.
+
+
+II. Used Software
+
+This product uses software developed at
+FUSE Source (http://www.fusesource.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+AOP Alliance (http://aopalliance.sourceforge.net/).
+Licensed under the Public Domain.
+
+This product uses software developed at
+Tanuki Software (http://www.tanukisoftware.com/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+Jasypt (http://jasypt.sourceforge.net/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+JLine (https://github.com/jline/).
+Licensed under the BSD License.
+
+This product uses software developed at
+SLF4J (http://www.slf4j.org/).
+Licensed under the MIT License.
+
+This product uses software developed at
+SpringSource (http://www.springsource.org/).
+Licensed under the Apache License 2.0.
+
+III. License Summary
+- Apache License 2.0
+- BSD License
+- EPL License
+- MIT License

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/NOTICE
----------------------------------------------------------------------
diff --git a/jms/core/NOTICE b/jms/core/NOTICE
deleted file mode 100644
index f1f81e0..0000000
--- a/jms/core/NOTICE
+++ /dev/null
@@ -1,67 +0,0 @@
-Apache Karaf
-Copyright 2010-2014 The Apache Software Foundation
-
-
-I. Included Software
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-The OSGi Alliance (http://www.osgi.org/).
-Copyright (c) OSGi Alliance (2000, 2010).
-Licensed under the Apache License 2.0.
-
-This product includes software developed at
-OW2 (http://www.ow2.org/).
-Licensed under the BSD License.
-
-This product includes software developed at
-OPS4J (http://www.ops4j.org/).
-Licensed under the Apache License 2.0.
-
-This product includes software developed at
-Eclipse Foundation (http://www.eclipse.org/).
-Licensed under the EPL.
-
-This product includes software written by
-Antony Lesuisse.
-Licensed under Public Domain.
-
-
-II. Used Software
-
-This product uses software developed at
-FUSE Source (http://www.fusesource.org/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-AOP Alliance (http://aopalliance.sourceforge.net/).
-Licensed under the Public Domain.
-
-This product uses software developed at
-Tanuki Software (http://www.tanukisoftware.com/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-Jasypt (http://jasypt.sourceforge.net/).
-Licensed under the Apache License 2.0.
-
-This product uses software developed at
-JLine (https://github.com/jline/).
-Licensed under the BSD License.
-
-This product uses software developed at
-SLF4J (http://www.slf4j.org/).
-Licensed under the MIT License.
-
-This product uses software developed at
-SpringSource (http://www.springsource.org/).
-Licensed under the Apache License 2.0.
-
-III. License Summary
-- Apache License 2.0
-- BSD License
-- EPL License
-- MIT License

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/pom.xml
----------------------------------------------------------------------
diff --git a/jms/core/pom.xml b/jms/core/pom.xml
deleted file mode 100644
index 8d2d485..0000000
--- a/jms/core/pom.xml
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <!--
-
-        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.
-    -->
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.karaf</groupId>
-        <artifactId>karaf</artifactId>
-        <version>4.2.0-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.apache.karaf.jms</groupId>
-    <artifactId>org.apache.karaf.jms.core</artifactId>
-    <packaging>bundle</packaging>
-    <name>Apache Karaf :: JMS :: Core</name>
-    <description>This bundle provides core implementation of the JMS service.</description>
-
-    <properties>
-        <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-jms_1.1_spec</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.activemq</groupId>
-            <artifactId>activemq-pool</artifactId>
-            <version>5.9.0</version>
-            <scope>provided</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.karaf</groupId>
-            <artifactId>org.apache.karaf.util</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.karaf.shell</groupId>
-            <artifactId>org.apache.karaf.shell.core</artifactId>
-            <optional>true</optional>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>${project.basedir}/src/main/resources</directory>
-                <includes>
-                    <include>**/*</include>
-                </includes>
-            </resource>
-            <resource>
-                <directory>${project.basedir}/src/main/resources</directory>
-                <filtering>true</filtering>
-                <includes>
-                    <include>**/*.info</include>
-                </includes>
-            </resource>
-        </resources>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.karaf.tooling</groupId>
-                <artifactId>karaf-services-maven-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Export-Package>
-                            org.apache.karaf.jms;-noimport:=true
-                        </Export-Package>
-                        <Import-Package>
-                            javax.jms;version="[1.1,3)",
-                            org.apache.activemq*;resolution:=optional,
-                            *
-                        </Import-Package>
-                        <Private-Package>
-                            org.apache.karaf.jms.command,
-                            org.apache.karaf.jms.command.completers,
-                            org.apache.karaf.jms.internal,
-                            org.apache.karaf.jms.internal.osgi,
-                            org.apache.karaf.util,
-                            org.apache.karaf.util.json
-                        </Private-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/JmsMBean.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/JmsMBean.java b/jms/core/src/main/java/org/apache/karaf/jms/JmsMBean.java
deleted file mode 100644
index d62a9ba..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/JmsMBean.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * 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.karaf.jms;
-
-import javax.management.MBeanException;
-import javax.management.openmbean.TabularData;
-import java.util.List;
-import java.util.Map;
-
-/**
- * JMS MBean.
- */
-public interface JmsMBean {
-
-    /**
-     * List the JMS connection factories.
-     *
-     * @return The {@link List} of the JMS connection factories name.
-     * @throws MBeanException If the MBean fails.
-     */
-    List<String> getConnectionfactories() throws MBeanException;
-
-    /**
-     * Create a JMS connection factory.
-     *
-     * @param name The JMS connection factory name.
-     * @param type The JMS connection factory type (ActiveMQ or WebsphereMQ).
-     * @param url The JMS connection factory URL. NB: when type is WebsphereMQ, the URL has the format host/port/queuemanager/channel.
-     * @throws MBeanException If the MBean fails.
-     */
-    void create(String name, String type, String url) throws MBeanException;
-
-    /**
-     * Create a JMS connection factory.
-     *
-     * @param name The JMS connection factory name.
-     * @param type The JMS connection factory type (ActiveMQ or WebsphereMQ).
-     * @param url The JMS connection factory URL. NB: when type is WebsphereMQ, the URL has the format host/port/queuemanager/channel.
-     * @param username The JMS connection factory authentication username.
-     * @param password The JMS connection factory authentication password.
-     * @throws MBeanException If the MBean fails.
-     */
-    void create(String name, String type, String url, String username, String password) throws MBeanException;
-
-    /**
-     * Delete a JMS connection factory.
-     *
-     * @param name The JMS connection factory name.
-     * @throws MBeanException If the MBean fails.
-     */
-    void delete(String name) throws MBeanException;
-
-    /**
-     * Get details about a JMS connection factory.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return A {@link Map} (property/value) containing details.
-     * @throws MBeanException If the MBean fails.
-     */
-    Map<String, String> info(String connectionFactory, String username, String password) throws MBeanException;
-
-    /**
-     * Count the messages on a given JMS queue.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The JMS queue name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The number of messages in the queue.
-     * @throws MBeanException If the MBean fails.
-     */
-    int count(String connectionFactory, String queue, String username, String password) throws MBeanException;
-
-    /**
-     * List the JMS queues.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The {@link List} of JMS queues.
-     * @throws MBeanException If the MBean fails.
-     */
-    List<String> queues(String connectionFactory, String username, String password) throws MBeanException;
-
-    /**
-     * List the JMS topics.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The @link List} of JMS topics.
-     * @throws MBeanException If the MBean fails.
-     */
-    List<String> topics(String connectionFactory, String username, String password) throws MBeanException;
-
-    /**
-     * Browse the messages in a JMS queue.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The JMS queue name.
-     * @param selector A selector to use to browse only certain messages.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return A {@link TabularData} containing messages details.
-     * @throws MBeanException If the MBean fails.
-     */
-    TabularData browse(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException;
-
-    /**
-     * Send a JMS message to given queue.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The JMS queue name.
-     * @param content The message content.
-     * @param replyTo The message ReplyTo.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @throws MBeanException If the MBean fails.
-     */
-    void send(String connectionFactory, String queue, String content, String replyTo, String username, String password) throws MBeanException;
-
-    /**
-     * Consume JMS messages from a given queue.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The JMS queue name.
-     * @param selector A selector to use to consume only certain messages.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The number of messages consumed.
-     * @throws MBeanException If the MBean fails.
-     */
-    int consume(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException;
-
-    /**
-     * Move JMS messages from one queue to another.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param source The source JMS queue name.
-     * @param destination The destination JMS queue name.
-     * @param selector A selector to move only certain messages.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The number of messages moved.
-     * @throws MBeanException If the MBean fails.
-     */
-    int move(String connectionFactory, String source, String destination, String selector, String username, String password) throws MBeanException;
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/JmsMessage.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/JmsMessage.java b/jms/core/src/main/java/org/apache/karaf/jms/JmsMessage.java
deleted file mode 100644
index acf13bf..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/JmsMessage.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.karaf.jms;
-
-import javax.jms.*;
-import java.io.UnsupportedEncodingException;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Describe a JMS message is more human readable way.
- */
-public class JmsMessage {
-
-    private Map<String, Object> properties = new HashMap<>();
-
-    private String content;
-    private String charset = "UTF-8";
-    private String correlationID;
-    private String deliveryMode;
-    private String destination;
-    private String expiration;
-    private String messageId;
-    private int priority;
-    private boolean redelivered;
-    private String replyTo;
-    private String timestamp;
-    private String type;
-
-    public JmsMessage(Message message) {
-        try {
-            initFromMessage(message);
-        } catch (JMSException e) {
-            throw new RuntimeException(e.getMessage(), e);
-        }
-    }
-
-    public void initFromMessage(Message message) throws JMSException {
-        @SuppressWarnings("unchecked")
-        Enumeration<String> names = message.getPropertyNames();
-        while (names.hasMoreElements()) {
-            String key = names.nextElement();
-            Object value = message.getObjectProperty(key);
-            properties.put(key, value);
-        }
-
-        correlationID = message.getJMSCorrelationID();
-        if (message.getJMSDeliveryMode() == DeliveryMode.NON_PERSISTENT) {
-            deliveryMode = "Non Persistent";
-        } else {
-            deliveryMode = "Persistent";
-        }
-        Destination destinationDest = message.getJMSDestination();
-        if (destinationDest != null) {
-            destination = destinationDest.toString();
-        }
-        if (message.getJMSExpiration() > 0) {
-            expiration = new Date(message.getJMSExpiration()).toString();
-        } else {
-            expiration = "Never";
-        }
-        messageId = message.getJMSMessageID();
-        priority = message.getJMSPriority();
-        redelivered = message.getJMSRedelivered();
-        Destination replyToDest = message.getJMSReplyTo();
-        if (replyToDest != null) {
-            replyTo = replyToDest.toString();
-        }
-        if (message.getJMSTimestamp() > 0) {
-            timestamp = new Date(message.getJMSTimestamp()).toString();
-        } else {
-            timestamp = "";
-        }
-        type = message.getJMSType();
-        content = getMessageContent(message);
-    }
-
-
-    private String getMessageContent(Message message) throws JMSException {
-        if (message instanceof TextMessage) {
-            return ((TextMessage) message).getText();
-        } else if (message instanceof BytesMessage) {
-            BytesMessage bMessage = (BytesMessage) message;
-            long length = bMessage.getBodyLength();
-            byte[] content = new byte[(int) length];
-            bMessage.readBytes(content);
-            try {
-                return new String(content, charset);
-            } catch (UnsupportedEncodingException e) {
-                throw new RuntimeException(e.getMessage(), e);
-            }
-        }
-        return "";
-    }
-
-    public Map<String, Object> getProperties() {
-        return properties;
-    }
-
-    public String getContent() {
-        return content;
-    }
-
-    public String getCharset() {
-        return charset;
-    }
-
-    public String getCorrelationID() {
-        return correlationID;
-    }
-
-    public String getDeliveryMode() {
-        return deliveryMode;
-    }
-
-    public String getDestination() {
-        return destination;
-    }
-
-    public String getExpiration() {
-        return expiration;
-    }
-
-    public String getMessageId() {
-        return messageId;
-    }
-
-    public int getPriority() {
-        return priority;
-    }
-
-    public boolean isRedelivered() {
-        return redelivered;
-    }
-
-    public String getReplyTo() {
-        return replyTo;
-    }
-
-    public String getTimestamp() {
-        return timestamp;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/JmsService.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/JmsService.java b/jms/core/src/main/java/org/apache/karaf/jms/JmsService.java
deleted file mode 100644
index 0902e33..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/JmsService.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.karaf.jms;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * JMS Service.
- */
-public interface JmsService {
-
-    /**
-     * List the JMS connection factories.
-     *
-     * @return The {@link List} of JMS connection factory names.
-     * @throws Exception If the service fails.
-     */
-    List<String> connectionFactories() throws Exception;
-
-    /**
-     * List the JMS connection factories file names.
-     *
-     * @return The {@link List} of JMS connection factory file names.
-     * @throws Exception If the service fails.
-     */
-    List<String> connectionFactoryFileNames() throws Exception;
-
-    /**
-     * Create a new JMS connection factory.
-     *
-     * @param name The JMS connection factory name.
-     * @param type The JMS connection factory type (ActiveMQ, WebsphereMQ, ...).
-     * @param url The JMS URL to use.
-     * @throws Exception If the service fails.
-     */
-    void create(String name, String type, String url) throws Exception;
-
-    /**
-     * Create a new JMS connection factory.
-     *
-     * @param name The JMS connection factory name.
-     * @param type The JMS connection factory type (ActiveMQ, WebsphereMQ, ...).
-     * @param url The JMS URL to use.
-     * @param username The username to use.
-     * @param password The password to use.
-     * @throws Exception If the service fails.
-     */
-    void create(String name, String type, String url, String username, String password) throws Exception;
-
-    /**
-     * Delete a JMS connection factory.
-     *
-     * @param name The JMS connection factory name.
-     * @throws Exception If the service fails.
-     */
-    void delete(String name) throws Exception;
-
-    /**
-     * Get details about a given JMS connection factory.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return A {@link Map} (property/value) containing details.
-     * @throws Exception If the service fails.
-     */
-    Map<String, String> info(String connectionFactory, String username, String password) throws Exception;
-
-    /**
-     * Count the number of messages in a JMS queue.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The queue name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The number of messages in a JMS queue.
-     * @throws Exception If the service fails.
-     */
-    int count(String connectionFactory, String queue, String username, String password) throws Exception;
-
-    /**
-     * List the queues.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The {@link List} of queues.
-     * @throws Exception If the service fails.
-     */
-    List<String> queues(String connectionFactory, String username, String password) throws Exception;
-
-    /**
-     * List the topics.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The {@link List} of topics.
-     * @throws Exception If the service fails.
-     */
-    List<String> topics(String connectionFactory, String username, String password) throws Exception;
-
-    /**
-     * Browse a destination.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The queue name.
-     * @param selector The selector.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The {@link List} of messages.
-     * @throws Exception If the service fails.
-     */
-    List<JmsMessage> browse(String connectionFactory, String queue, String selector, String username, String password) throws Exception;
-
-    /**
-     * Send a message on the given queue.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The queue name.
-     * @param body The message body.
-     * @param replyTo The message replyTo header.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @throws Exception If the service fails.
-     */
-    void send(String connectionFactory, String queue, String body, String replyTo, String username, String password) throws Exception;
-
-    /**
-     * Consume messages from a given destination.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param queue The queue name.
-     * @param selector The messages selector.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The number of messages consumed.
-     * @throws Exception If the service fails.
-     */
-    int consume(String connectionFactory, String queue, String selector, String username, String password) throws Exception;
-
-    /**
-     * Move messages from a destination to another.
-     *
-     * @param connectionFactory The JMS connection factory name.
-     * @param sourceQueue The source queue.
-     * @param targetQueue The target queue.
-     * @param selector The messages selector on the source queue.
-     * @param username The (optional) username to connect to the JMS broker.
-     * @param password The (optional) password to connect to the JMS broker.
-     * @return The number of messages moved.
-     * @throws Exception If the service fails.
-     */
-    int move(String connectionFactory, String sourceQueue, String targetQueue, String selector, String username, String password) throws Exception;
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java
deleted file mode 100644
index cb86aa6..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/BrowseCommand.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-import java.util.List;
-
-import org.apache.karaf.jms.JmsMessage;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "jms", name = "browse", description = "Browse a JMS queue")
-@Service
-public class BrowseCommand extends JmsConnectionCommandSupport {
-
-    @Argument(index = 1, name = "queue", description = "The JMS queue to browse", required = true, multiValued = false)
-    String queue;
-
-    @Option(name = "-s", aliases = { "--selector" }, description = "The selector to select the messages to browse", required = false, multiValued = false)
-    String selector;
-
-    @Option(name = "-v", aliases = { "--verbose" }, description = "Display JMS properties", required = false, multiValued = false)
-    boolean verbose = false;
-
-    @Override
-    public Object execute() throws Exception {
-
-        ShellTable table = new ShellTable();
-        table.column("Message ID");
-        table.column("Content").maxSize(80);
-        table.column("Charset");
-        table.column("Type");
-        table.column("Correlation ID");
-        table.column("Delivery Mode");
-        table.column("Destination");
-        table.column("Expiration");
-        table.column("Priority");
-        table.column("Redelivered");
-        table.column("ReplyTo");
-        table.column("Timestamp");
-        if (verbose) {
-            table.column("Properties");
-        }
-
-        List<JmsMessage> messages = getJmsService().browse(connectionFactory, queue, selector, username, password);
-        for (JmsMessage message : messages) {
-            if (verbose) {
-                StringBuilder properties = new StringBuilder();
-                for (String property : message.getProperties().keySet()) {
-                    properties.append(property).append("=").append(message.getProperties().get(property)).append("\n");
-                }
-                table.addRow().addContent(
-                        message.getMessageId(),
-                        message.getContent(),
-                        message.getCharset(),
-                        message.getType(),
-                        message.getCorrelationID(),
-                        message.getDeliveryMode(),
-                        message.getDestination(),
-                        message.getExpiration(),
-                        message.getPriority(),
-                        message.isRedelivered(),
-                        message.getReplyTo(),
-                        message.getTimestamp(),
-                        properties.toString());
-            } else {
-                table.addRow().addContent(
-                        message.getMessageId(),
-                        message.getContent(),
-                        message.getCharset(),
-                        message.getType(),
-                        message.getCorrelationID(),
-                        message.getDeliveryMode(),
-                        message.getDestination(),
-                        message.getExpiration(),
-                        message.getPriority(),
-                        message.isRedelivered(),
-                        message.getReplyTo(),
-                        message.getTimestamp());
-            }
-        }
-
-        table.print(System.out);
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java
deleted file mode 100644
index b698336..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/ConnectionFactoriesCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-import java.util.List;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "jms", name = "connectionfactories", description = "List the JMS connection factories")
-@Service
-public class ConnectionFactoriesCommand extends JmsCommandSupport {
-
-    @Override
-    public Object execute() throws Exception {
-
-        ShellTable table = new ShellTable();
-        table.column("JMS Connection Factory");
-
-        List<String> connectionFactories = getJmsService().connectionFactories();
-        for (String connectionFactory : connectionFactories) {
-            table.addRow().addContent(connectionFactory);
-        }
-
-        table.print(System.out);
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java
deleted file mode 100644
index cd8caaf..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/ConsumeCommand.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jms", name = "consume", description = "Consume messages from a JMS queue.")
-@Service
-public class ConsumeCommand extends JmsConnectionCommandSupport {
-
-    @Argument(index = 1, name = "queue", description = "The JMS queue where to consume messages", required = true, multiValued = false)
-    String queue;
-
-    @Option(name = "-s", aliases = { "--selector" }, description = "The selector to use to select the messages to consume", required = false, multiValued = false)
-    String selector;
-
-    @Override
-    public Object execute() throws Exception {
-        System.out.println(getJmsService().consume(connectionFactory, queue, selector, username, password) + " message(s) consumed");
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/CountCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/CountCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/CountCommand.java
deleted file mode 100644
index 576e8dd..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/CountCommand.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "jms", name = "count", description = "Count the number of messages on a JMS queue.")
-@Service
-public class CountCommand extends JmsConnectionCommandSupport {
-
-    @Argument(index = 1, name = "queue", description = "The JMS queue name", required = true, multiValued = false)
-    String queue;
-
-    @Override
-    public Object execute() throws Exception {
-        ShellTable table = new ShellTable();
-        table.column("Messages Count");
-        table.addRow().addContent(getJmsService().count(connectionFactory, queue, username, password));
-        table.print(System.out);
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/CreateCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/CreateCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/CreateCommand.java
deleted file mode 100644
index 64ccf02..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/CreateCommand.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-@Command(scope = "jms", name = "create", description = "Create a JMS connection factory.")
-@Service
-public class CreateCommand extends JmsCommandSupport {
-
-    @Argument(index = 0, name = "name", description = "The JMS connection factory name", required = true, multiValued = false)
-    String name;
-
-    @Option(name = "-t", aliases = { "--type" }, description = "The JMS connection factory type (ActiveMQ, Artemis or WebsphereMQ)", required = false, multiValued = false)
-    @Completion(value = StringsCompleter.class, values = { "activemq", "artemis", "webspheremq" })
-    String type = "ActiveMQ";
-
-    @Option(name = "--url", description = "URL of the JMS broker. For WebsphereMQ type, the URL is hostname/port/queuemanager/channel", required = false, multiValued = false)
-    String url = "tcp://localhost:61616";
-
-    @Option(name = "-u", aliases = { "--username" }, description = "Username to connect to the JMS broker", required = false, multiValued = false)
-    String username = "karaf";
-
-    @Option(name = "-p", aliases = { "--password" }, description = "Password to connect to the JMS broker", required = false, multiValued = false)
-    String password = "karaf";
-
-    @Override
-    public Object execute() throws Exception {
-        getJmsService().create(name, type, url, username, password);
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java
deleted file mode 100644
index cab3123..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/DeleteCommand.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import org.apache.karaf.jms.command.completers.ConnectionFactoriesFileNameCompleter;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jms", name = "delete", description = "Delete a JMS connection factory")
-@Service
-public class DeleteCommand extends JmsCommandSupport {
-
-    @Argument(index = 0, name = "name", description = "The JMS connection factory name", required = true, multiValued = false)
-    @Completion(ConnectionFactoriesFileNameCompleter.class)
-    String name;
-
-    @Override
-    public Object execute() throws Exception {
-        getJmsService().delete(name);
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/InfoCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/InfoCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/InfoCommand.java
deleted file mode 100644
index 354db39..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/InfoCommand.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import java.util.Map;
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "jms", name = "info", description = "Provides details about a JMS connection factory.")
-@Service
-public class InfoCommand extends JmsConnectionCommandSupport {
-
-    @Override
-    public Object execute() throws Exception {
-        ShellTable table = new ShellTable();
-        table.column("Property");
-        table.column("Value");
-
-        Map<String, String> info = getJmsService().info(connectionFactory, username, password);
-        for (String key : info.keySet()) {
-            table.addRow().addContent(key, info.get(key));
-        }
-
-        table.print(System.out);
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java b/jms/core/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java
deleted file mode 100644
index 2f5df8f..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/JmsCommandSupport.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-import org.apache.karaf.jms.JmsService;
-import org.apache.karaf.shell.api.action.Action;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-
-public abstract class JmsCommandSupport implements Action {
-
-    @Reference
-    private JmsService jmsService;
-
-    public JmsService getJmsService() {
-        return jmsService;
-    }
-
-    public void setJmsService(JmsService jmsService) {
-        this.jmsService = jmsService;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java b/jms/core/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java
deleted file mode 100644
index 64adfe4..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/JmsConnectionCommandSupport.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-import org.apache.karaf.jms.command.completers.ConnectionFactoriesNameCompleter;
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Completion;
-import org.apache.karaf.shell.api.action.Option;
-
-/**
- * For commands that need a connection factory and authentication information 
- */
-public abstract class JmsConnectionCommandSupport extends JmsCommandSupport {
-
-    @Argument(index = 0, name = "connectionFactory", description = "The JMS connection factory name", required = true, multiValued = false)
-    @Completion(ConnectionFactoriesNameCompleter.class)
-    String connectionFactory;
-
-    @Option(name = "-u", aliases = { "--username" }, description = "Username to connect to the JMS broker", required = false, multiValued = false)
-    String username = "karaf";
-
-    @Option(name = "-p", aliases = { "--password" }, description = "Password to connect to the JMS broker", required = false, multiValued = false)
-    String password = "karaf";
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/MoveCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/MoveCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/MoveCommand.java
deleted file mode 100644
index a4c8d12..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/MoveCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jms", name = "move", description = "Move messages from one JMS queue to another one.")
-@Service
-public class MoveCommand extends JmsConnectionCommandSupport {
-
-    @Argument(index = 1, name = "source", description = "The source JMS queue", required = true, multiValued = false)
-    String source;
-
-    @Argument(index = 2, name = "destination", description = "The destination JMS queue", required = true, multiValued = false)
-    String destination;
-
-    @Option(name = "-s", aliases = { "--selector" }, description = "Selector to move only some messages", required = false, multiValued = false)
-    String selector;
-
-    @Override
-    public Object execute() throws Exception {
-        System.out.println(getJmsService().move(connectionFactory, source, destination, selector, username, password) + " message(s) moved");
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java
deleted file mode 100644
index 7cf1dac..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/QueuesCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "jms", name = "queues", description = "List the JMS queues.")
-@Service
-public class QueuesCommand extends JmsConnectionCommandSupport {
-
-    @Override
-    public Object execute() throws Exception {
-        ShellTable table = new ShellTable();
-
-        table.column("JMS Queues");
-
-        for (String queue : getJmsService().queues(connectionFactory, username, password)) {
-            table.addRow().addContent(queue);
-        }
-
-        table.print(System.out);
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/SendCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/SendCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/SendCommand.java
deleted file mode 100644
index 63d3f4a..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/SendCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import org.apache.karaf.shell.api.action.Argument;
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.Option;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-
-@Command(scope = "jms", name = "send", description = "Send a message to ")
-@Service
-public class SendCommand extends JmsConnectionCommandSupport {
-
-    @Argument(index = 1, name = "queue", description = "The JMS queue name", required = true, multiValued = false)
-    String queue;
-
-    @Argument(index = 2, name = "message", description = "The JMS message content", required = true, multiValued = false)
-    String message;
-
-    @Option(name = "-r", aliases = { "--replyTo" }, description = "Set the message ReplyTo", required = false, multiValued = false)
-    String replyTo;
-
-    @Override
-    public Object execute() throws Exception {
-        getJmsService().send(connectionFactory, queue, message, replyTo, username, password);
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java b/jms/core/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java
deleted file mode 100644
index b583bc4..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/TopicsCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.karaf.jms.command;
-
-
-import org.apache.karaf.shell.api.action.Command;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.support.table.ShellTable;
-
-@Command(scope = "jms", name = "topics", description = "List the JMS topics.")
-@Service
-public class TopicsCommand extends JmsConnectionCommandSupport {
-
-    @Override
-    public Object execute() throws Exception {
-        ShellTable table = new ShellTable();
-
-        table.column("JMS Topics");
-
-        for (String topic : getJmsService().topics(connectionFactory, username, password)) {
-            table.addRow().addContent(topic);
-        }
-
-        table.print(System.out);
-
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java b/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java
deleted file mode 100644
index c33ff62..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesFileNameCompleter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.karaf.jms.command.completers;
-
-import java.util.List;
-
-import org.apache.karaf.jms.JmsService;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-/**
- * Completer on the JMS connection factory file names.
- */
-@Service
-public class ConnectionFactoriesFileNameCompleter implements Completer {
-
-    @Reference
-    private JmsService jmsService;
-
-    @Override
-    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
-        StringsCompleter delegate = new StringsCompleter();
-        try {
-            for (String connectionFactory : jmsService.connectionFactoryFileNames()) {
-                delegate.getStrings().add(connectionFactory.replace("connectionfactory-", "").replace(".xml", ""));
-            }
-        } catch (Exception e) {
-            // nothing to do
-        }
-        return delegate.complete(session, commandLine, candidates);
-    }
-
-    public JmsService getJmsService() {
-        return jmsService;
-    }
-
-    public void setJmsService(JmsService jmsService) {
-        this.jmsService = jmsService;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java b/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java
deleted file mode 100644
index 98f97b3..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/command/completers/ConnectionFactoriesNameCompleter.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.karaf.jms.command.completers;
-
-import java.util.List;
-
-import org.apache.karaf.jms.JmsService;
-import org.apache.karaf.shell.api.action.lifecycle.Reference;
-import org.apache.karaf.shell.api.action.lifecycle.Service;
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.support.completers.StringsCompleter;
-
-/**
- * Completer on the JMS connection factories name.
- */
-@Service
-public class ConnectionFactoriesNameCompleter implements Completer {
-
-    @Reference
-    private JmsService jmsService;
-
-    @Override
-    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
-        StringsCompleter delegate = new StringsCompleter();
-        try {
-            for (String connectionFactory : jmsService.connectionFactories()) {
-                delegate.getStrings().add(connectionFactory);
-            }
-        } catch (Exception e) {
-            // nothing to do
-        }
-        return delegate.complete(session, commandLine, candidates);
-    }
-
-    public JmsService getJmsService() {
-        return jmsService;
-    }
-
-    public void setJmsService(JmsService jmsService) {
-        this.jmsService = jmsService;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java
deleted file mode 100644
index a6e5cb7..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/ActiveMQDestinationSourceFactory.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.karaf.jms.internal;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import javax.jms.Queue;
-import javax.jms.Topic;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-class ActiveMQDestinationSourceFactory implements DestinationSource.Factory {
-
-    @Override
-    public DestinationSource create(Connection connection) throws JMSException {
-        if (connection.getClass().getName().matches("org\\.apache\\.activemq\\.ActiveMQ(XA)?Connection")) {
-            try {
-                final Object destSource = connection.getClass().getMethod("getDestinationSource").invoke(connection);
-                return type -> getNames(destSource, type);
-            } catch (Exception e) {
-                // Ignore
-            }
-        }
-        return null;
-    }
-
-    private List<String> getNames(Object destSource, DestinationSource.DestinationType type) {
-        try {
-            if (type == DestinationSource.DestinationType.Queue) {
-                @SuppressWarnings("unchecked")
-                Set<Queue> queues = (Set) destSource.getClass().getMethod("getQueues").invoke(destSource);
-                List<String> names = new ArrayList<>();
-                for (Queue queue : queues) {
-                    names.add(queue.getQueueName());
-                }
-                return names;
-            }
-            if (type == DestinationSource.DestinationType.Topic) {
-                @SuppressWarnings("unchecked")
-                Set<Topic> topics = (Set) destSource.getClass().getMethod("getTopics").invoke(destSource);
-                List<String> names = new ArrayList<>();
-                for (Topic topic : topics) {
-                    names.add(topic.getTopicName());
-                }
-                return names;
-            }
-        } catch (Exception e) {
-            // Ignore
-        }
-        return Collections.emptyList();
-    }
-}


[5/6] karaf git commit: Better integration with fileinstall and configs

Posted by gn...@apache.org.
Better integration with fileinstall and configs

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/d1ce154d
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/d1ce154d
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/d1ce154d

Branch: refs/heads/master
Commit: d1ce154d27c8416911deec29f04594ff805d90df
Parents: b2d3708
Author: Guillaume Nodet <gn...@apache.org>
Authored: Mon Jul 31 21:30:21 2017 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Wed Aug 2 14:10:48 2017 +0200

----------------------------------------------------------------------
 .../features/internal/service/FeatureConfigInstaller.java | 10 ++++++++++
 1 file changed, 10 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/d1ce154d/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
index e1f0ca8..d1fc525 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
@@ -115,6 +115,16 @@ public class FeatureConfigInstaller {
 				cfg = createConfiguration(configAdmin, pid[0], pid[1]);
 				String key = createConfigurationKey(pid[0], pid[1]);
 				cfgProps.put(CONFIG_KEY, key);
+				props.put(CONFIG_KEY, key);
+                if (storage != null && configCfgStore) {
+                    File cfgFile;
+                    if (pid[1] != null) {
+                        cfgFile = new File(storage, pid[0] + "-" + pid[1] + ".cfg");
+                    } else {
+                        cfgFile = new File(storage, pid[0] + ".cfg");
+                    }
+                    cfgProps.put(FILEINSTALL_FILE_NAME, cfgFile.getAbsoluteFile().toURI().toString());
+                }
 				cfg.update(cfgProps);
                 try {
                     updateStorage(pid[0], pid[1], props, false);


[3/6] karaf git commit: [KARAF-5131] XA + JMS support

Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java
deleted file mode 100644
index b3ea458..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/ArtemisDestinationSourceFactory.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.karaf.jms.internal;
-
-import org.apache.karaf.util.json.JsonReader;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueRequestor;
-import javax.jms.QueueSession;
-import javax.jms.Session;
-import javax.jms.TextMessage;
-import java.io.StringReader;
-import java.util.Collections;
-import java.util.List;
-
-class ArtemisDestinationSourceFactory implements DestinationSource.Factory {
-
-    @Override
-    public DestinationSource create(Connection connection) throws JMSException {
-        if (connection.getClass().getName().matches("org\\.apache\\.activemq\\.artemis\\.jms\\.client\\.ActiveMQ(XA)?Connection")) {
-            return type -> getNames(connection, type);
-        }
-        return null;
-    }
-
-    private List<String> getNames(Connection connection, DestinationSource.DestinationType type) {
-        try {
-            QueueSession session = ((QueueConnection) connection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
-            Queue managementQueue = session.createQueue("activemq.management");
-            QueueRequestor requestor = new QueueRequestor(session, managementQueue);
-            connection.start();
-            TextMessage m = session.createTextMessage();
-            m.setStringProperty("_AMQ_ResourceName", "broker");
-            m.setStringProperty("_AMQ_OperationName", "getQueueNames");
-            String routing = type == DestinationSource.DestinationType.Queue ? "ANYCAST" : "MULTICAST";
-            m.setText("[\"" + routing + "\"]");
-            Message reply = requestor.request(m);
-            String json = ((TextMessage) reply).getText();
-            List<?> array = (List<?>) JsonReader.read(new StringReader(json));
-            return (List<String>) array.get(0);
-        } catch (Exception e) {
-            return Collections.emptyList();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java
deleted file mode 100644
index efc7bcd..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/DestinationSource.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.karaf.jms.internal;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import java.util.List;
-
-interface DestinationSource {
-
-    enum DestinationType {
-        Queue, Topic
-    }
-
-    interface Factory {
-
-        DestinationSource create(Connection connection) throws JMSException;
-    }
-
-    List<String> getNames(DestinationType type);
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsConnector.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsConnector.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsConnector.java
deleted file mode 100644
index 75c52ce..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsConnector.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * 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.karaf.jms.internal;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Comparator;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.JMSException;
-import javax.jms.Session;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-
-public class JmsConnector implements Closeable {
-    private BundleContext bc;
-    private ServiceReference<ConnectionFactory> reference;
-    private Connection connection;
-    private Session session;
-    private String connectionFactoryName;
-    private String username;
-    private String password;
-
-    public JmsConnector(BundleContext bc, String connectionFactoryName, String username, String password) throws JMSException {
-        this.bc = bc;
-        this.connectionFactoryName = connectionFactoryName;
-        this.username = username;
-        this.password = password;
-    }
-    
-    private ServiceReference<ConnectionFactory> lookupConnectionFactory(String name) {
-        try {
-            Collection<ServiceReference<ConnectionFactory>> references = bc.getServiceReferences(
-                    ConnectionFactory.class,
-                    "(|(osgi.jndi.service.name=" + name + ")(name=" + name + ")(service.id=" + name + "))");
-            return references.stream()
-                    .sorted(Comparator.<ServiceReference<?>>naturalOrder().reversed())
-                    .findFirst()
-                    .orElseThrow(() -> new IllegalArgumentException("No JMS connection factory found for " + name));
-        } catch (InvalidSyntaxException e) {
-            throw new RuntimeException("Error finding connection factory service " + name, e);
-        }
-    }
-
-    @Override
-    public void close() throws IOException {
-        if (session != null) {
-            try {
-                session.close();
-            } catch (JMSException e) {
-                // Ignore
-            }
-        }
-        if (connection != null) {
-            try {
-                connection.close();
-            } catch (JMSException e) {
-                // Ignore
-            }
-        }
-        if (reference != null) {
-            bc.ungetService(reference);
-        }
-    }
-
-    public Connection connect() throws JMSException {
-        reference = this.lookupConnectionFactory(connectionFactoryName);
-        ConnectionFactory cf = bc.getService(reference);
-        connection = cf.createConnection(username, password);
-        connection.start();
-        return connection;
-    }
-
-    public Session createSession() throws JMSException {
-        return createSession(Session.AUTO_ACKNOWLEDGE);
-    }
-
-    public Session createSession(int acknowledgeMode) throws JMSException {
-        if (connection == null) {
-            connect();
-        }
-        if (acknowledgeMode == Session.SESSION_TRANSACTED) {
-            session = connection.createSession(true, acknowledgeMode);
-        } else {
-            session = connection.createSession(false, acknowledgeMode);
-        }
-        return session;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java
deleted file mode 100644
index e3b7801..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsMBeanImpl.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.karaf.jms.internal;
-
-import org.apache.karaf.jms.JmsMBean;
-import org.apache.karaf.jms.JmsMessage;
-import org.apache.karaf.jms.JmsService;
-
-import javax.management.MBeanException;
-import javax.management.openmbean.*;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Default implementation of the JMS MBean.
- */
-public class JmsMBeanImpl implements JmsMBean {
-
-    private JmsService jmsService;
-
-    @Override
-    public List<String> getConnectionfactories() throws MBeanException {
-        try {
-            return jmsService.connectionFactories();
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public void create(String name, String type, String url) throws MBeanException {
-        try {
-            jmsService.create(name, type, url);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public void create(String name, String type, String url, String username, String password) throws MBeanException {
-        try {
-            jmsService.create(name, type, url, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public void delete(String name) throws MBeanException {
-        try {
-            jmsService.delete(name);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public Map<String, String> info(String connectionFactory, String username, String password) throws MBeanException {
-        try {
-            return jmsService.info(connectionFactory, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public int count(String connectionFactory, String queue, String username, String password) throws MBeanException {
-        try {
-            return jmsService.count(connectionFactory, queue, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public List<String> queues(String connectionFactory, String username, String password) throws MBeanException {
-        try {
-            return jmsService.queues(connectionFactory, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public List<String> topics(String connectionFactory, String username, String password) throws MBeanException {
-        try {
-            return jmsService.topics(connectionFactory, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public void send(String connectionFactory, String queue, String content, String replyTo, String username, String password) throws MBeanException {
-        try {
-            jmsService.send(connectionFactory, queue, content, replyTo, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public int consume(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException {
-        try {
-            return jmsService.consume(connectionFactory, queue, selector, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public int move(String connectionFactory, String source, String destination, String selector, String username, String password) throws MBeanException {
-        try {
-            return jmsService.move(connectionFactory, source, destination, selector, username, password);
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    @Override
-    public TabularData browse(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException {
-        try {
-            CompositeType type = new CompositeType("message", "JMS Message",
-                    new String[]{ "id", "content", "charset", "type", "correlation", "delivery", "destination", "expiration", "priority", "redelivered", "replyto", "timestamp" },
-                    new String[]{ "Message ID", "Content", "Charset", "Type", "Correlation ID", "Delivery Mode", "Destination", "Expiration Date", "Priority", "Redelivered", "Reply-To", "Timestamp" },
-                    new OpenType[]{ SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.INTEGER, SimpleType.BOOLEAN, SimpleType.STRING, SimpleType.STRING });
-            TabularType tableType = new TabularType("messages", "JMS Messages", type, new String[]{ "id" });
-            TabularData table = new TabularDataSupport(tableType);
-            for (JmsMessage message : getJmsService().browse(connectionFactory, queue, selector, username, password)) {
-                CompositeData data = new CompositeDataSupport(type,
-                        new String[]{ "id", "content", "charset", "type", "correlation", "delivery", "destination", "expiration", "priority", "redelivered", "replyto", "timestamp" },
-                        new Object[]{ message.getMessageId(), message.getContent(), message.getCharset(), message.getType(), message.getCorrelationID(), message.getDeliveryMode(), message.getDestination(), message.getExpiration(), message.getPriority(), message.isRedelivered(), message.getReplyTo(), message.getTimestamp() }
-                        );
-                table.put(data);
-            }
-            return table;
-        } catch (Throwable t) {
-            throw new MBeanException(null, t.getMessage());
-        }
-    }
-
-    public JmsService getJmsService() {
-        return jmsService;
-    }
-
-    public void setJmsService(JmsService jmsService) {
-        this.jmsService = jmsService;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java
deleted file mode 100644
index f460018..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/JmsServiceImpl.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * 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.karaf.jms.internal;
-
-import org.apache.karaf.jms.JmsMessage;
-import org.apache.karaf.jms.JmsService;
-import org.apache.karaf.util.TemplateUtils;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-
-import javax.jms.*;
-
-import java.io.*;
-import java.lang.IllegalStateException;
-import java.lang.reflect.Method;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.*;
-import java.util.stream.Collectors;
-
-/**
- * Default implementation of the JMS Service.
- */
-public class JmsServiceImpl implements JmsService {
-
-    private BundleContext bundleContext;
-    private Path deployFolder;
-    
-    public JmsServiceImpl() {
-        deployFolder = Paths.get(System.getProperty("karaf.base"), "deploy");
-    }
-
-    @Override
-    public void create(String name, String type, String url) throws Exception {
-        create(name, type, url, null, null);
-    }
-
-    @Override
-    public void create(String name, String type, String url, String username, String password) throws Exception {
-        if (!type.equalsIgnoreCase("activemq")
-                && !type.equalsIgnoreCase("artemis")
-                && !type.equalsIgnoreCase("webspheremq")) {
-            throw new IllegalArgumentException("JMS connection factory type not known");
-        }
-
-        Path outFile = getConnectionFactoryFile(name);
-        String template;
-        HashMap<String, String> properties = new HashMap<>();
-        properties.put("name", name);
-
-        if (type.equalsIgnoreCase("activemq")) {
-            // activemq
-            properties.put("url", url);
-            properties.put("username", username);
-            properties.put("password", password);
-            template = "connectionfactory-activemq.xml";
-        } else if (type.equalsIgnoreCase("artemis")) {
-            // artemis
-            properties.put("url", url);
-            properties.put("username", username);
-            properties.put("password", password);
-            template = "connectionfactory-artemis.xml";
-        } else {
-            // webspheremq
-            String[] splitted = url.split("/");
-            if (splitted.length != 4) {
-                throw new IllegalStateException("WebsphereMQ URI should be in the following format: host/port/queuemanager/channel");
-            }
-            
-            properties.put("host", splitted[0]);
-            properties.put("port", splitted[1]);
-            properties.put("queuemanager", splitted[2]);
-            properties.put("channel", splitted[3]);
-            template = "connectionfactory-webspheremq.xml";
-        }
-        InputStream is = this.getClass().getResourceAsStream(template);
-        if (is == null) {
-            throw new IllegalArgumentException("Template resource " + template + " doesn't exist");
-        }
-        TemplateUtils.createFromTemplate(outFile.toFile(), is, properties);
-    }
-
-    private Path getConnectionFactoryFile(String name) {
-        return deployFolder.resolve("connectionfactory-" + name + ".xml");
-    }
-
-    @Override
-    public void delete(String name) throws Exception {
-        Path connectionFactoryFile = getConnectionFactoryFile(name);
-        if (!Files.isRegularFile(connectionFactoryFile)) {
-            throw new IllegalStateException("The JMS connection factory file " + connectionFactoryFile + " doesn't exist");
-        }
-        Files.delete(connectionFactoryFile);
-    }
-
-    @Override
-    public List<String> connectionFactories() throws Exception {
-        return bundleContext.getServiceReferences(ConnectionFactory.class, null).stream()
-                .map(this::getConnectionFactoryName)
-                .distinct()
-                .collect(Collectors.toList());
-    }
-
-    private String getConnectionFactoryName(ServiceReference<ConnectionFactory> reference) {
-        if (reference.getProperty("osgi.jndi.service.name") != null) {
-            return (String) reference.getProperty("osgi.jndi.service.name");
-        } else if (reference.getProperty("name") != null) {
-            return (String) reference.getProperty("name");
-        } else {
-            return reference.getProperty(Constants.SERVICE_ID).toString();
-        }
-    }
-
-    @Override
-    public List<String> connectionFactoryFileNames() throws Exception {
-        return Files.list(deployFolder)
-                .map(Path::getFileName)
-                .map(Path::toString)
-                .filter(name -> name.startsWith("connectionfactory-") && name.endsWith(".xml"))
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    public Map<String, String> info(String connectionFactory, String username, String password) throws IOException, JMSException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            ConnectionMetaData metaData = connector.connect().getMetaData();
-            Map<String, String> map = new HashMap<>();
-            map.put("product", metaData.getJMSProviderName());
-            map.put("version", metaData.getProviderVersion());
-            return map;
-        }
-    }
-
-    @Override
-    public int count(String connectionFactory, final String destination, String username, String password) throws IOException, JMSException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            Session session = connector.createSession();
-            QueueBrowser browser = session.createBrowser(session.createQueue(destination));
-            @SuppressWarnings("unchecked")
-            Enumeration<Message> enumeration = browser.getEnumeration();
-            int count = 0;
-            while (enumeration.hasMoreElements()) {
-                enumeration.nextElement();
-                count++;
-            }
-            browser.close();
-            return count;
-        }
-    }
-
-    private DestinationSource getDestinationSource(Connection connection) throws JMSException {
-        while (true) {
-            try {
-                Method mth = connection.getClass().getMethod("getConnection");
-                connection = (Connection) mth.invoke(connection);
-            } catch (Throwable e) {
-                break;
-            }
-        }
-        List<DestinationSource.Factory> factories = Arrays.asList(
-                new ActiveMQDestinationSourceFactory(),
-                new ArtemisDestinationSourceFactory()
-        );
-        DestinationSource source = null;
-        for (DestinationSource.Factory factory : factories) {
-            source = factory.create(connection);
-            if (source != null) {
-                break;
-            }
-        }
-        if (source == null) {
-            source = d -> Collections.emptyList();
-        }
-        return source;
-    }
-    
-    @Override
-    public List<String> queues(String connectionFactory, String username, String password) throws JMSException, IOException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            return getDestinationSource(connector.connect()).getNames(DestinationSource.DestinationType.Queue);
-        }
-    }
-
-    @Override
-    public List<String> topics(String connectionFactory, String username, String password) throws IOException, JMSException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            return getDestinationSource(connector.connect()).getNames(DestinationSource.DestinationType.Topic);
-        }
-    }
-
-    @Override
-    public List<JmsMessage> browse(String connectionFactory, final String queue, final String filter,
-                                   String username, String password) throws JMSException, IOException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            List<JmsMessage> messages = new ArrayList<>();
-            Session session = connector.createSession();
-            QueueBrowser browser = session.createBrowser(session.createQueue(queue), filter);
-            @SuppressWarnings("unchecked")
-            Enumeration<Message> enumeration = browser.getEnumeration();
-            while (enumeration.hasMoreElements()) {
-                Message message = enumeration.nextElement();
-
-                messages.add(new JmsMessage(message));
-            }
-            browser.close();
-            return messages;
-        }
-    }
-
-    @Override
-    public void send(String connectionFactory, final String queue, final String body, final String replyTo,
-                     String username, String password) throws IOException, JMSException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            Session session = connector.createSession();
-            Message message = session.createTextMessage(body);
-            if (replyTo != null) {
-                message.setJMSReplyTo(session.createQueue(replyTo));
-            }
-            MessageProducer producer = session.createProducer(session.createQueue(queue));
-            producer.send(message);
-            producer.close();
-        }
-    }
-
-    @Override
-    public int consume(String connectionFactory, final String queue, final String selector, String username,
-                       String password) throws Exception {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            int count = 0;
-            Session session = connector.createSession();
-            MessageConsumer consumer = session.createConsumer(session.createQueue(queue), selector);
-            Message message;
-            do {
-                message = consumer.receive(500L);
-                if (message != null) {
-                    count++;
-                }
-            } while (message != null);
-            return count;
-        }
-    }
-
-    @Override
-    public int move(String connectionFactory, final String sourceQueue, final String targetQueue,
-                    final String selector, String username, String password) throws IOException, JMSException {
-        try (JmsConnector connector = new JmsConnector(bundleContext, connectionFactory, username, password)) {
-            int count = 0;
-            Session session = connector.createSession(Session.SESSION_TRANSACTED);
-            MessageConsumer consumer = session.createConsumer(session.createQueue(sourceQueue), selector);
-            Message message;
-            do {
-                message = consumer.receive(500L);
-                if (message != null) {
-                    MessageProducer producer = session.createProducer(session.createQueue(targetQueue));
-                    producer.send(message);
-                    count++;
-                }
-            } while (message != null);
-            session.commit();
-            consumer.close();
-            return count;
-        }
-    }
-
-    public void setBundleContext(BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
-    }
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/jms/core/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java b/jms/core/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java
deleted file mode 100644
index 1dd1c09..0000000
--- a/jms/core/src/main/java/org/apache/karaf/jms/internal/osgi/Activator.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.apache.karaf.jms.internal.osgi;
-
-import org.apache.karaf.jms.JmsService;
-import org.apache.karaf.jms.internal.JmsMBeanImpl;
-import org.apache.karaf.jms.internal.JmsServiceImpl;
-import org.apache.karaf.shell.api.console.CommandLoggingFilter;
-import org.apache.karaf.shell.support.RegexCommandLoggingFilter;
-import org.apache.karaf.util.tracker.BaseActivator;
-import org.apache.karaf.util.tracker.annotation.ProvideService;
-import org.apache.karaf.util.tracker.annotation.Services;
-
-@Services(
-        provides = @ProvideService(JmsService.class)
-)
-public class Activator extends BaseActivator {
-    @Override
-    protected void doStart() throws Exception {
-        JmsServiceImpl service = new JmsServiceImpl();
-        service.setBundleContext(bundleContext);
-        register(JmsService.class, service);
-
-        JmsMBeanImpl mbean = new JmsMBeanImpl();
-        mbean.setJmsService(service);
-        registerMBean(mbean, "type=jms");
-
-        RegexCommandLoggingFilter filter = new RegexCommandLoggingFilter();
-        filter.addRegEx("create +.*?--password ([^ ]+)", 2);
-        filter.addRegEx("create +.*?-p ([^ ]+)", 2);
-        register(CommandLoggingFilter.class, filter);
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/resources/OSGI-INF/bundle.info
----------------------------------------------------------------------
diff --git a/jms/core/src/main/resources/OSGI-INF/bundle.info b/jms/core/src/main/resources/OSGI-INF/bundle.info
deleted file mode 100644
index 9d83749..0000000
--- a/jms/core/src/main/resources/OSGI-INF/bundle.info
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-#
-#    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.
-#
-#
-h1. Synopsis
-
-	${project.name}
-
-	${project.description}
-
-	Maven URL:
-		[mvn:${project.groupId}/${project.artifactId}/${project.version}]
-
-h1. Description
-
-	This bundle is the core implementation of the JMS service support.
-
-	The JMS service allows you to create connection factories, and send/browse/consume messages.
-
-h1. Commands
-
-	The bundle contains the following commands:
-\${command-list|jms|indent=8,list,cyan}
-
-h1. See also
-
-	JMS - section of the Karaf User Guide

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-activemq.xml
----------------------------------------------------------------------
diff --git a/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-activemq.xml b/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-activemq.xml
deleted file mode 100644
index da2ad1a..0000000
--- a/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-activemq.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements. See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version
-    2.0 (the "License"); you may not use this file except in compliance
-    with the License. You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0 Unless required by
-    applicable law or agreed to in writing, software distributed under the
-    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-    CONDITIONS OF ANY KIND, either express or implied. See the License for
-    the specific language governing permissions and limitations under the
-    License.
-    -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-
-    <service interface="javax.jms.ConnectionFactory">
-        <service-properties>
-            <entry key="name" value="${name}" />
-            <entry key="osgi.jndi.service.name" value="jms/${name}" />
-            <entry key="karaf.jms.wrap" value="true" />
-            <entry key="karaf.jms.pool.maxConnections" value="8" />
-        </service-properties>
-        <bean class="org.apache.activemq.ActiveMQConnectionFactory">
-            <property name="brokerURL" value="${url}" />
-            <property name="userName" value="${username}" />
-            <property name="password" value="${password}" />
-        </bean>
-    </service>
-
-</blueprint>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-artemis.xml
----------------------------------------------------------------------
diff --git a/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-artemis.xml b/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-artemis.xml
deleted file mode 100644
index 67b1f54..0000000
--- a/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-artemis.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements. See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version
-    2.0 (the "License"); you may not use this file except in compliance
-    with the License. You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0 Unless required by
-    applicable law or agreed to in writing, software distributed under the
-    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-    CONDITIONS OF ANY KIND, either express or implied. See the License for
-    the specific language governing permissions and limitations under the
-    License.
-    -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-
-    <service interface="javax.jms.ConnectionFactory">
-        <service-properties>
-            <entry key="name" value="${name}" />
-            <entry key="osgi.jndi.service.name" value="jms/${name}" />
-            <entry key="karaf.jms.wrap" value="true" />
-            <entry key="karaf.jms.pool.maxConnections" value="8" />
-        </service-properties>
-        <bean class="org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory">
-            <argument value="${url}" />
-            <argument value="${username}" />
-            <argument value="${password}" />
-            <property name="producerWindowSize" value="-1" />
-        </bean>
-    </service>
-
-</blueprint>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-webspheremq.xml
----------------------------------------------------------------------
diff --git a/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-webspheremq.xml b/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-webspheremq.xml
deleted file mode 100644
index 999c85b..0000000
--- a/jms/core/src/main/resources/org/apache/karaf/jms/internal/connectionfactory-webspheremq.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements. See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version
-    2.0 (the "License"); you may not use this file except in compliance
-    with the License. You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0 Unless required by
-    applicable law or agreed to in writing, software distributed under the
-    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-    CONDITIONS OF ANY KIND, either express or implied. See the License for
-    the specific language governing permissions and limitations under the
-    License.
-    -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-
-    <service interface="javax.jms.ConnectionFactory">
-        <service-properties>
-            <entry key="name" value="${name}"/>
-            <entry key="osgi.jndi.service.name" value="jms/${name}"/>
-            <entry key="karaf.jms.wrap" value="true" />
-        </service-properties>
-        <bean class="com.ibm.mq.jms.MQQueueConnectionFactory">
-            <property name="transportType" value="1" />
-            <property name="hostName" value="${hostname}" />
-            <property name="port" value="${port}" />
-            <property name="queueManager" value="${queuemanager}" />
-            <property name="channel" value="${channel}" />
-        </bean>
-    </service>
-
-</blueprint>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pom.xml
----------------------------------------------------------------------
diff --git a/jms/pom.xml b/jms/pom.xml
index 3b3b185..dd7155c 100644
--- a/jms/pom.xml
+++ b/jms/pom.xml
@@ -25,16 +25,109 @@
         <groupId>org.apache.karaf</groupId>
         <artifactId>karaf</artifactId>
         <version>4.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
+        <relativePath>../../pom.xml</relativePath>
     </parent>
 
     <groupId>org.apache.karaf.jms</groupId>
-    <artifactId>parent</artifactId>
-    <packaging>pom</packaging>
-    <name>Apache Karaf :: Features</name>
-
-	<modules>
-        <module>core</module>
-        <module>pool</module>
-	</modules>
+    <artifactId>org.apache.karaf.jms.core</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Karaf :: JMS :: Core</name>
+    <description>This bundle provides core implementation of the JMS service.</description>
+
+    <properties>
+        <appendedResourcesDirectory>${basedir}/../etc/appended-resources</appendedResourcesDirectory>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.jms</groupId>
+            <artifactId>javax.jms-api</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.jms</groupId>
+            <artifactId>pax-jms-api</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.activemq</groupId>
+            <artifactId>activemq-pool</artifactId>
+            <version>5.9.0</version>
+            <scope>provided</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.geronimo.specs</groupId>
+                    <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf</groupId>
+            <artifactId>org.apache.karaf.util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.karaf.shell</groupId>
+            <artifactId>org.apache.karaf.shell.core</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${project.basedir}/src/main/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>${project.basedir}/src/main/resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>**/*.info</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-services-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.apache.karaf.jms;-noimport:=true
+                        </Export-Package>
+                        <Import-Package>
+                            javax.jms;version="[1.1,3)",
+                            org.apache.activemq*;resolution:=optional,
+                            *
+                        </Import-Package>
+                        <Private-Package>
+                            org.apache.karaf.jms.command,
+                            org.apache.karaf.jms.command.completers,
+                            org.apache.karaf.jms.internal,
+                            org.apache.karaf.jms.internal.osgi,
+                            org.apache.karaf.util,
+                            org.apache.karaf.util.json
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
 </project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/pom.xml
----------------------------------------------------------------------
diff --git a/jms/pool/pom.xml b/jms/pool/pom.xml
deleted file mode 100644
index 21278d2..0000000
--- a/jms/pool/pom.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <!--
-
-        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.
-    -->
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.karaf</groupId>
-        <artifactId>karaf</artifactId>
-        <version>4.2.0-SNAPSHOT</version>
-        <relativePath>../../pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.apache.karaf.jms</groupId>
-    <artifactId>org.apache.karaf.jms.pool</artifactId>
-    <packaging>bundle</packaging>
-    <name>Apache Karaf :: JMS :: Pool</name>
-    <description>This bundle provides pooling implementation of the JMS service.</description>
-
-    <properties>
-        <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
-    </properties>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.geronimo.specs</groupId>
-            <artifactId>geronimo-jms_1.1_spec</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-pool2</artifactId>
-            <version>2.4.2</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <resources>
-            <resource>
-                <directory>${project.basedir}/src/main/resources</directory>
-                <includes>
-                    <include>**/*</include>
-                </includes>
-            </resource>
-            <resource>
-                <directory>${project.basedir}/src/main/resources</directory>
-                <filtering>true</filtering>
-                <includes>
-                    <include>**/*.info</include>
-                </includes>
-            </resource>
-        </resources>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Export-Package>
-                        </Export-Package>
-                        <Import-Package>
-                            javax.jms;version="[1.1,3)",
-                            *
-                        </Import-Package>
-                        <Private-Package>
-                            org.apache.karaf.jms.pool.internal,
-                            org.apache.karaf.jms.pool.internal.osgi
-                        </Private-Package>
-                        <Bundle-Activator>
-                            org.apache.karaf.jms.pool.internal.osgi.Activator
-                        </Bundle-Activator>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionKey.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionKey.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionKey.java
deleted file mode 100644
index 9dab2fc..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionKey.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-/**
- * A cache key for the connection details
- * 
- * 
- */
-public class ConnectionKey {
-    private String userName;
-    private String password;
-    private int hash;
-
-    public ConnectionKey(String userName, String password) {
-        this.password = password;
-        this.userName = userName;
-        hash = 31;
-        if (userName != null) {
-            hash += userName.hashCode();
-        }
-        hash *= 31;
-        if (password != null) {
-            hash += password.hashCode();
-        }
-    }
-
-    public int hashCode() {
-        return hash;
-    }
-
-    public boolean equals(Object that) {
-        if (this == that) {
-            return true;
-        }
-        if (that instanceof ConnectionKey) {
-            return equals((ConnectionKey)that);
-        }
-        return false;
-    }
-
-    public boolean equals(ConnectionKey that) {
-        return isEqual(this.userName, that.userName) && isEqual(this.password, that.password);
-    }
-
-    public String getPassword() {
-        return password;
-    }
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public static boolean isEqual(Object o1, Object o2) {
-        if (o1 == o2) {
-            return true;
-        }
-        return o1 != null && o2 != null && o1.equals(o2);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionPool.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionPool.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionPool.java
deleted file mode 100644
index fbf0384..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/ConnectionPool.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import org.apache.commons.pool2.KeyedPooledObjectFactory;
-import org.apache.commons.pool2.PooledObject;
-import org.apache.commons.pool2.impl.DefaultPooledObject;
-import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
-
-import javax.jms.Connection;
-import javax.jms.IllegalStateException;
-import javax.jms.JMSException;
-import javax.jms.Session;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Holds a real JMS connection along with the session pools associated with it.
- * <p/>
- * Instances of this class are shared amongst one or more PooledConnection object and must
- * track the session objects that are loaned out for cleanup on close as well as ensuring
- * that the temporary destinations of the managed Connection are purged when all references
- * to this ConnectionPool are released.
- */
-public class ConnectionPool {
-    protected Connection connection;
-    private int referenceCount;
-    private long lastUsed = System.currentTimeMillis();
-    private final long firstUsed = lastUsed;
-    private boolean hasExpired;
-    private int idleTimeout = 30 * 1000;
-    private long expiryTimeout = 0l;
-    private boolean useAnonymousProducers = true;
-
-    private final AtomicBoolean started = new AtomicBoolean(false);
-    private final GenericKeyedObjectPool<SessionKey, PooledSession> sessionPool;
-    private final List<PooledSession> loanedSessions = new CopyOnWriteArrayList<>();
-
-    public ConnectionPool(Connection connection) {
-
-        this.connection = connection;
-
-        // Create our internal Pool of session instances.
-        this.sessionPool = new GenericKeyedObjectPool<>(
-                new KeyedPooledObjectFactory<SessionKey, PooledSession>() {
-
-                    @Override
-                    public void activateObject(SessionKey key, PooledObject<PooledSession> session) throws Exception {
-                        ConnectionPool.this.loanedSessions.add(session.getObject());
-                    }
-
-                    @Override
-                    public void destroyObject(SessionKey key, PooledObject<PooledSession> session) throws Exception {
-                        ConnectionPool.this.loanedSessions.remove(session.getObject());
-                        session.getObject().getInternalSession().close();
-                    }
-
-                    @Override
-                    public PooledObject<PooledSession> makeObject(SessionKey key) throws Exception {
-                        Session session = makeSession(key);
-                        return new DefaultPooledObject<>(new PooledSession(key, session, sessionPool, key.isTransacted(), useAnonymousProducers));
-                    }
-
-                    @Override
-                    public void passivateObject(SessionKey key, PooledObject<PooledSession> session) throws Exception {
-                        ConnectionPool.this.loanedSessions.remove(session.getObject());
-                    }
-
-                    @Override
-                    public boolean validateObject(SessionKey key, PooledObject<PooledSession> session) {
-                        return true;
-                    }
-                }
-        );
-    }
-
-    // useful when external failure needs to force expiry
-    public void setHasExpired(boolean val) {
-        hasExpired = val;
-    }
-
-    protected Session makeSession(SessionKey key) throws JMSException {
-        return connection.createSession(key.isTransacted(), key.getAckMode());
-    }
-
-    public void start() throws JMSException {
-        if (started.compareAndSet(false, true)) {
-            try {
-                connection.start();
-            } catch (JMSException e) {
-                started.set(false);
-                throw(e);
-            }
-        }
-    }
-
-    public synchronized Connection getConnection() {
-        return connection;
-    }
-
-    public Session createSession(boolean transacted, int ackMode) throws JMSException {
-        SessionKey key = new SessionKey(transacted, ackMode);
-        PooledSession session;
-        try {
-            session = sessionPool.borrowObject(key);
-        } catch (Exception e) {
-            IllegalStateException illegalStateException = new IllegalStateException(e.toString());
-            illegalStateException.initCause(e);
-            throw illegalStateException;
-        }
-        return session;
-    }
-
-    public synchronized void close() {
-        if (connection != null) {
-            try {
-                sessionPool.close();
-            } catch (Exception e) {
-            } finally {
-                try {
-                    connection.close();
-                } catch (Exception e) {
-                } finally {
-                    connection = null;
-                }
-            }
-        }
-    }
-
-    public synchronized void incrementReferenceCount() {
-        referenceCount++;
-        lastUsed = System.currentTimeMillis();
-    }
-
-    public synchronized void decrementReferenceCount() {
-        referenceCount--;
-        lastUsed = System.currentTimeMillis();
-        if (referenceCount == 0) {
-            // Loaned sessions are those that are active in the sessionPool and
-            // have not been closed by the client before closing the connection.
-            // These need to be closed so that all session's reflect the fact
-            // that the parent Connection is closed.
-            for (PooledSession session : this.loanedSessions) {
-                try {
-                    session.close();
-                } catch (Exception e) {
-                }
-            }
-            this.loanedSessions.clear();
-
-            expiredCheck();
-        }
-    }
-
-    /**
-     * Determines if this Connection has expired.
-     * <p/>
-     * A ConnectionPool is considered expired when all references to it are released AND either
-     * the configured idleTimeout has elapsed OR the configured expiryTimeout has elapsed.
-     * Once a ConnectionPool is determined to have expired its underlying Connection is closed.
-     *
-     * @return true if this connection has expired.
-     */
-    public synchronized boolean expiredCheck() {
-
-        boolean expired = false;
-
-        if (connection == null) {
-            return true;
-        }
-
-        if (hasExpired) {
-            if (referenceCount == 0) {
-                close();
-                expired = true;
-            }
-        }
-
-        if (expiryTimeout > 0 && System.currentTimeMillis() > firstUsed + expiryTimeout) {
-            hasExpired = true;
-            if (referenceCount == 0) {
-                close();
-                expired = true;
-            }
-        }
-
-        // Only set hasExpired here is no references, as a Connection with references is by
-        // definition not idle at this time.
-        if (referenceCount == 0 && idleTimeout > 0 && System.currentTimeMillis() > lastUsed + idleTimeout) {
-            hasExpired = true;
-            close();
-            expired = true;
-        }
-
-        return expired;
-    }
-
-    public int getIdleTimeout() {
-        return idleTimeout;
-    }
-
-    public void setIdleTimeout(int idleTimeout) {
-        this.idleTimeout = idleTimeout;
-    }
-
-    public void setExpiryTimeout(long expiryTimeout) {
-        this.expiryTimeout = expiryTimeout;
-    }
-
-    public long getExpiryTimeout() {
-        return expiryTimeout;
-    }
-
-    public int getMaximumActiveSessionPerConnection() {
-        return this.sessionPool.getMaxTotalPerKey();
-    }
-
-    public void setMaximumActiveSessionPerConnection(int maximumActiveSessionPerConnection) {
-        this.sessionPool.setMaxTotalPerKey(maximumActiveSessionPerConnection);
-    }
-
-    public boolean isUseAnonymousProducers() {
-        return this.useAnonymousProducers;
-    }
-
-    public void setUseAnonymousProducers(boolean value) {
-        this.useAnonymousProducers = value;
-    }
-
-    /**
-     * @return the total number of Pooled session including idle sessions that are not
-     *          currently loaned out to any client.
-     */
-    public int getNumSessions() {
-        return this.sessionPool.getNumIdle() + this.sessionPool.getNumActive();
-    }
-
-    /**
-     * @return the total number of Sessions that are in the Session pool but not loaned out.
-     */
-    public int getNumIdleSessions() {
-        return this.sessionPool.getNumIdle();
-    }
-
-    /**
-     * @return the total number of Session's that have been loaned to PooledConnection instances.
-     */
-    public int getNumActiveSessions() {
-        return this.sessionPool.getNumActive();
-    }
-
-    /**
-     * Configure whether the createSession method should block when there are no more idle sessions and the
-     * pool already contains the maximum number of active sessions.  If false the create method will fail
-     * and throw an exception.
-     *
-     * @param block
-     * 		Indicates whether blocking should be used to wait for more space to create a session.
-     */
-    public void setBlockIfSessionPoolIsFull(boolean block) {
-        this.sessionPool.setBlockWhenExhausted(block);
-    }
-
-    public boolean isBlockIfSessionPoolIsFull() {
-        return this.sessionPool.getBlockWhenExhausted();
-    }
-
-    /**
-     * Returns the timeout to use for blocking creating new sessions
-     *
-     * @return true if the pooled Connection createSession method will block when the limit is hit.
-     * @see #setBlockIfSessionPoolIsFull(boolean)
-     */
-    public long getBlockIfSessionPoolIsFullTimeout() {
-        return this.sessionPool.getMaxWaitMillis();
-    }
-
-    /**
-     * Controls the behavior of the internal session pool. By default the call to
-     * Connection.getSession() will block if the session pool is full.  This setting
-     * will affect how long it blocks and throws an exception after the timeout.
-     *
-     * The size of the session pool is controlled by the @see #maximumActive
-     * property.
-     *
-     * Whether or not the call to create session blocks is controlled by the @see #blockIfSessionPoolIsFull
-     * property
-     *
-     * @param blockIfSessionPoolIsFullTimeout - if blockIfSessionPoolIsFullTimeout is true,
-     *                                        then use this setting to configure how long to block before retry
-     */
-    public void setBlockIfSessionPoolIsFullTimeout(long blockIfSessionPoolIsFullTimeout) {
-        this.sessionPool.setMaxWaitMillis(blockIfSessionPoolIsFullTimeout);
-    }
-
-    @Override
-    public String toString() {
-        return "ConnectionPool[" + connection + "]";
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/IntrospectionSupport.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/IntrospectionSupport.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/IntrospectionSupport.java
deleted file mode 100755
index c5900d1..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/IntrospectionSupport.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.net.ssl.SSLServerSocket;
-import java.lang.reflect.Method;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public final class IntrospectionSupport {
-
-    private static final Logger LOG = LoggerFactory.getLogger(IntrospectionSupport.class);
-
-    private IntrospectionSupport() {
-    }
-
-    @SuppressWarnings("rawtypes")
-    public static boolean setProperties(Object target, Map props) {
-        boolean rc = false;
-
-        if (target == null) {
-            throw new IllegalArgumentException("target was null.");
-        }
-        if (props == null) {
-            throw new IllegalArgumentException("props was null.");
-        }
-
-        for (Iterator<?> iter = props.entrySet().iterator(); iter.hasNext();) {
-            Entry<?,?> entry = (Entry<?,?>)iter.next();
-            if (setProperty(target, (String)entry.getKey(), entry.getValue())) {
-                iter.remove();
-                rc = true;
-            }
-        }
-
-        return rc;
-    }
-
-    public static boolean setProperty(Object target, String name, Object value) {
-        try {
-            Class<?> clazz = target.getClass();
-            if (target instanceof SSLServerSocket) {
-                // overcome illegal access issues with internal implementation class
-                clazz = SSLServerSocket.class;
-            }
-            Method setter = findSetterMethod(clazz, name);
-            if (setter == null) {
-                return false;
-            }
-
-            // If the type is null or it matches the needed type, just use the
-            // value directly
-            if (value == null || value.getClass() == setter.getParameterTypes()[0]) {
-                setter.invoke(target, value);
-            } else {
-                // We need to convert it
-                setter.invoke(target, convert(value, setter.getParameterTypes()[0]));
-            }
-            return true;
-        } catch (Exception e) {
-            LOG.error(String.format("Could not set property %s on %s", name, target), e);
-            return false;
-        }
-    }
-
-    @SuppressWarnings({
-        "rawtypes", "unchecked"
-    })
-    private static Object convert(Object value, Class to) {
-        if (value == null) {
-            // lets avoid NullPointerException when converting to boolean for null values
-            if (boolean.class.isAssignableFrom(to)) {
-                return Boolean.FALSE;
-            }
-            return null;
-        }
-
-        // eager same instance type test to avoid the overhead of invoking the type converter
-        // if already same type
-        if (to.isAssignableFrom(value.getClass())) {
-            return to.cast(value);
-        }
-
-        if (boolean.class.isAssignableFrom(to) && value instanceof String) {
-            return Boolean.valueOf((String) value);
-        }
-
-        throw new IllegalArgumentException("Cannot convert from " + value.getClass()
-                    + " to " + to + " with value " + value);
-    }
-
-    private static Method findSetterMethod(Class<?> clazz, String name) {
-        // Build the method name.
-        name = "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
-        Method[] methods = clazz.getMethods();
-        for (Method method : methods) {
-            Class<?> params[] = method.getParameterTypes();
-            if (method.getName().equals(name) && params.length == 1 ) {
-                return method;
-            }
-        }
-        return null;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnection.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnection.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnection.java
deleted file mode 100755
index 38ccf6a..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnection.java
+++ /dev/null
@@ -1,285 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionConsumer;
-import javax.jms.ConnectionMetaData;
-import javax.jms.Destination;
-import javax.jms.ExceptionListener;
-import javax.jms.JMSException;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueSession;
-import javax.jms.ServerSessionPool;
-import javax.jms.Session;
-import javax.jms.TemporaryQueue;
-import javax.jms.TemporaryTopic;
-import javax.jms.Topic;
-import javax.jms.TopicConnection;
-import javax.jms.TopicSession;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-/**
- * Represents a proxy {@link Connection} which is-a {@link TopicConnection} and
- * {@link QueueConnection} which is pooled and on {@link #close()} will return
- * itself to the sessionPool.
- *
- * <b>NOTE</b> this implementation is only intended for use when sending
- * messages. It does not deal with pooling of consumers; for that look at a
- * library like <a href="http://jencks.org/">Jencks</a> such as in <a
- * href="http://jencks.org/Message+Driven+POJOs">this example</a>
- *
- */
-public class PooledConnection implements TopicConnection, QueueConnection, PooledSessionEventListener {
-    private static final transient Logger LOG = LoggerFactory.getLogger(PooledConnection.class);
-
-    protected ConnectionPool pool;
-    private volatile boolean stopped;
-    private final List<TemporaryQueue> connTempQueues = new CopyOnWriteArrayList<>();
-    private final List<TemporaryTopic> connTempTopics = new CopyOnWriteArrayList<>();
-    private final List<PooledSession> loanedSessions = new CopyOnWriteArrayList<>();
-
-    /**
-     * Creates a new PooledConnection instance that uses the given ConnectionPool to create
-     * and manage its resources.  The ConnectionPool instance can be shared amongst many
-     * PooledConnection instances.
-     *
-     * @param pool
-     *      The connection and pool manager backing this proxy connection object.
-     */
-    public PooledConnection(ConnectionPool pool) {
-        this.pool = pool;
-    }
-
-    /**
-     * Factory method to create a new instance.
-     */
-    public PooledConnection newInstance() {
-        return new PooledConnection(pool);
-    }
-
-    @Override
-    public void close() throws JMSException {
-        this.cleanupConnectionTemporaryDestinations();
-        this.cleanupAllLoanedSessions();
-        if (this.pool != null) {
-            this.pool.decrementReferenceCount();
-            this.pool = null;
-        }
-    }
-
-    @Override
-    public void start() throws JMSException {
-        assertNotClosed();
-        pool.start();
-    }
-
-    @Override
-    public void stop() throws JMSException {
-        stopped = true;
-    }
-
-    @Override
-    public ConnectionConsumer createConnectionConsumer(Destination destination, String selector, ServerSessionPool serverSessionPool, int maxMessages) throws JMSException {
-        return getConnection().createConnectionConsumer(destination, selector, serverSessionPool, maxMessages);
-    }
-
-    @Override
-    public ConnectionConsumer createConnectionConsumer(Topic topic, String s, ServerSessionPool serverSessionPool, int maxMessages) throws JMSException {
-        return getConnection().createConnectionConsumer(topic, s, serverSessionPool, maxMessages);
-    }
-
-    @Override
-    public ConnectionConsumer createDurableConnectionConsumer(Topic topic, String selector, String s1, ServerSessionPool serverSessionPool, int i) throws JMSException {
-        return getConnection().createDurableConnectionConsumer(topic, selector, s1, serverSessionPool, i);
-    }
-
-    @Override
-    public String getClientID() throws JMSException {
-        return getConnection().getClientID();
-    }
-
-    @Override
-    public ExceptionListener getExceptionListener() throws JMSException {
-        return getConnection().getExceptionListener();
-    }
-
-    @Override
-    public ConnectionMetaData getMetaData() throws JMSException {
-        return getConnection().getMetaData();
-    }
-
-    @Override
-    public void setExceptionListener(ExceptionListener exceptionListener) throws JMSException {
-        getConnection().setExceptionListener(exceptionListener);
-    }
-
-    @Override
-    public void setClientID(String clientID) throws JMSException {
-        // ignore repeated calls to setClientID() with the same client id
-        // this could happen when a JMS component such as Spring that uses a
-        // PooledConnectionFactory shuts down and reinitializes.
-        if (this.getConnection().getClientID() == null || !this.getClientID().equals(clientID)) {
-            getConnection().setClientID(clientID);
-        }
-    }
-
-    @Override
-    public ConnectionConsumer createConnectionConsumer(Queue queue, String selector, ServerSessionPool serverSessionPool, int maxMessages) throws JMSException {
-        return getConnection().createConnectionConsumer(queue, selector, serverSessionPool, maxMessages);
-    }
-
-    // Session factory methods
-    // -------------------------------------------------------------------------
-    @Override
-    public QueueSession createQueueSession(boolean transacted, int ackMode) throws JMSException {
-        return (QueueSession) createSession(transacted, ackMode);
-    }
-
-    @Override
-    public TopicSession createTopicSession(boolean transacted, int ackMode) throws JMSException {
-        return (TopicSession) createSession(transacted, ackMode);
-    }
-
-    @Override
-    public Session createSession(boolean transacted, int ackMode) throws JMSException {
-        PooledSession result;
-        result = (PooledSession) pool.createSession(transacted, ackMode);
-
-        // Store the session so we can close the sessions that this PooledConnection
-        // created in order to ensure that consumers etc are closed per the JMS contract.
-        loanedSessions.add(result);
-
-        // Add a event listener to the session that notifies us when the session
-        // creates / destroys temporary destinations and closes etc.
-        result.addSessionEventListener(this);
-        return result;
-    }
-
-    // Implementation methods
-    // -------------------------------------------------------------------------
-
-    @Override
-    public void onTemporaryQueueCreate(TemporaryQueue tempQueue) {
-        connTempQueues.add(tempQueue);
-    }
-
-    @Override
-    public void onTemporaryTopicCreate(TemporaryTopic tempTopic) {
-        connTempTopics.add(tempTopic);
-    }
-
-    @Override
-    public void onSessionClosed(PooledSession session) {
-        if (session != null) {
-            this.loanedSessions.remove(session);
-        }
-    }
-
-    public Connection getConnection() throws JMSException {
-        assertNotClosed();
-        return pool.getConnection();
-    }
-
-    protected void assertNotClosed() throws javax.jms.IllegalStateException {
-        if (stopped || pool == null) {
-            throw new javax.jms.IllegalStateException("Connection closed");
-        }
-    }
-
-    protected Session createSession(SessionKey key) throws JMSException {
-        return getConnection().createSession(key.isTransacted(), key.getAckMode());
-    }
-
-    @Override
-    public String toString() {
-        return "PooledConnection { " + pool + " }";
-    }
-
-    /**
-     * Remove all of the temporary destinations created for this connection.
-     * This is important since the underlying connection may be reused over a
-     * long period of time, accumulating all of the temporary destinations from
-     * each use. However, from the perspective of the lifecycle from the
-     * client's view, close() closes the connection and, therefore, deletes all
-     * of the temporary destinations created.
-     */
-    protected void cleanupConnectionTemporaryDestinations() {
-
-        for (TemporaryQueue tempQueue : connTempQueues) {
-            try {
-                tempQueue.delete();
-            } catch (JMSException ex) {
-                LOG.info("failed to delete Temporary Queue \"" + tempQueue.toString() + "\" on closing pooled connection: " + ex.getMessage());
-            }
-        }
-        connTempQueues.clear();
-
-        for (TemporaryTopic tempTopic : connTempTopics) {
-            try {
-                tempTopic.delete();
-            } catch (JMSException ex) {
-                LOG.info("failed to delete Temporary Topic \"" + tempTopic.toString() + "\" on closing pooled connection: " + ex.getMessage());
-            }
-        }
-        connTempTopics.clear();
-    }
-
-    /**
-     * The PooledSession tracks all Sessions that it created and now we close them.  Closing the
-     * PooledSession will return the internal Session to the Pool of Session after cleaning up
-     * all the resources that the Session had allocated for this PooledConnection.
-     */
-    protected void cleanupAllLoanedSessions() {
-
-        for (PooledSession session : loanedSessions) {
-            try {
-                session.close();
-            } catch (JMSException ex) {
-                LOG.info("failed to close laoned Session \"" + session + "\" on closing pooled connection: " + ex.getMessage());
-            }
-        }
-        loanedSessions.clear();
-    }
-
-    /**
-     * @return the total number of Pooled session including idle sessions that are not
-     *          currently loaned out to any client.
-     */
-    public int getNumSessions() {
-        return this.pool.getNumSessions();
-    }
-
-    /**
-     * @return the number of Sessions that are currently checked out of this Connection's session pool.
-     */
-    public int getNumActiveSessions() {
-        return this.pool.getNumActiveSessions();
-    }
-
-    /**
-     * @return the number of Sessions that are idle in this Connection's sessions pool.
-     */
-    public int getNumtIdleSessions() {
-        return this.pool.getNumIdleSessions();
-    }
-}


[2/6] karaf git commit: [KARAF-5131] XA + JMS support

Posted by gn...@apache.org.
http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnectionFactory.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnectionFactory.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnectionFactory.java
deleted file mode 100644
index ba36c1c..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledConnectionFactory.java
+++ /dev/null
@@ -1,538 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import org.apache.commons.pool2.KeyedPooledObjectFactory;
-import org.apache.commons.pool2.PooledObject;
-import org.apache.commons.pool2.impl.DefaultPooledObject;
-import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.JMSException;
-import javax.jms.QueueConnection;
-import javax.jms.QueueConnectionFactory;
-import javax.jms.TopicConnection;
-import javax.jms.TopicConnectionFactory;
-import java.util.Objects;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A JMS provider which pools Connection, Session and MessageProducer instances
- * so it can be used with tools like <a href="http://camel.apache.org/activemq.html">Camel</a> and Spring's
- * <a href="http://activemq.apache.org/spring-support.html">JmsTemplate and MessagListenerContainer</a>.
- * Connections, sessions and producers are returned to a pool after use so that they can be reused later
- * without having to undergo the cost of creating them again.
- *
- * b>NOTE:</b> while this implementation does allow the creation of a collection of active consumers,
- * it does not 'pool' consumers. Pooling makes sense for connections, sessions and producers, which
- * are expensive to create and can remain idle a minimal cost. Consumers, on the other hand, are usually
- * just created at startup and left active, handling incoming messages as they come. When a consumer is
- * complete, it is best to close it rather than return it to a pool for later reuse: this is because,
- * even if a consumer is idle, ActiveMQ will keep delivering messages to the consumer's prefetch buffer,
- * where they'll get held until the consumer is active again.
- *
- * If you are creating a collection of consumers (for example, for multi-threaded message consumption), you
- * might want to consider using a lower prefetch value for each consumer (e.g. 10 or 20), to ensure that
- * all messages don't end up going to just one of the consumers. See this FAQ entry for more detail:
- * http://activemq.apache.org/i-do-not-receive-messages-in-my-second-consumer.html
- *
- * Optionally, one may configure the pool to examine and possibly evict objects as they sit idle in the
- * pool. This is performed by an "idle object eviction" thread, which runs asynchronously. Caution should
- * be used when configuring this optional feature. Eviction runs contend with client threads for access
- * to objects in the pool, so if they run too frequently performance issues may result. The idle object
- * eviction thread may be configured using the {@link PooledConnectionFactory#setTimeBetweenExpirationCheckMillis} method.  By
- * default the value is -1 which means no eviction thread will be run.  Set to a non-negative value to
- * configure the idle eviction thread to run.
- */
-public class PooledConnectionFactory implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory {
-
-    private static final transient Logger LOG = LoggerFactory.getLogger(PooledConnectionFactory.class);
-
-    private final AtomicBoolean stopped = new AtomicBoolean(false);
-    private GenericKeyedObjectPool<ConnectionKey, ConnectionPool> connectionsPool;
-
-    private final ConnectionFactory connectionFactory;
-
-    private int maximumActiveSessionPerConnection = 500;
-    private int idleTimeout = 30 * 1000;
-    private boolean blockIfSessionPoolIsFull = true;
-    private long blockIfSessionPoolIsFullTimeout = -1L;
-    private long expiryTimeout = 0L;
-    private boolean createConnectionOnStartup = true;
-    private boolean useAnonymousProducers = true;
-
-    public PooledConnectionFactory(ConnectionFactory connectionFactory) {
-        this.connectionFactory = Objects.requireNonNull(connectionFactory, "connectionFactory must be set");
-    }
-
-    public void initConnectionsPool() {
-        if (this.connectionsPool == null) {
-            this.connectionsPool = new GenericKeyedObjectPool<>(
-                    new KeyedPooledObjectFactory<ConnectionKey, ConnectionPool>() {
-                        @Override
-                        public void activateObject(ConnectionKey key, PooledObject<ConnectionPool> connection) throws Exception {
-                        }
-                        @Override
-                        public void destroyObject(ConnectionKey key, PooledObject<ConnectionPool> connection) throws Exception {
-                            try {
-                                if (LOG.isTraceEnabled()) {
-                                    LOG.trace("Destroying connection: {}", connection);
-                                }
-                                connection.getObject().close();
-                            } catch (Exception e) {
-                                LOG.warn("Close connection failed for connection: " + connection + ". This exception will be ignored.",e);
-                            }
-                        }
-                        @Override
-                        public PooledObject<ConnectionPool> makeObject(ConnectionKey key) throws Exception {
-                            Connection delegate = createConnection(key);
-
-                            ConnectionPool connection = createConnectionPool(delegate);
-                            connection.setIdleTimeout(getIdleTimeout());
-                            connection.setExpiryTimeout(getExpiryTimeout());
-                            connection.setMaximumActiveSessionPerConnection(getMaximumActiveSessionPerConnection());
-                            connection.setBlockIfSessionPoolIsFull(isBlockIfSessionPoolIsFull());
-                            if (isBlockIfSessionPoolIsFull() && getBlockIfSessionPoolIsFullTimeout() > 0) {
-                                connection.setBlockIfSessionPoolIsFullTimeout(getBlockIfSessionPoolIsFullTimeout());
-                            }
-                            connection.setUseAnonymousProducers(isUseAnonymousProducers());
-
-                            if (LOG.isTraceEnabled()) {
-                                LOG.trace("Created new connection: {}", connection);
-                            }
-
-                            return new DefaultPooledObject<>(connection);
-                        }
-
-                        @Override
-                        public void passivateObject(ConnectionKey key, PooledObject<ConnectionPool> connection) throws Exception {
-                        }
-
-                        @Override
-                        public boolean validateObject(ConnectionKey key, PooledObject<ConnectionPool> connection) {
-                            if (connection != null && connection.getObject() != null && connection.getObject().expiredCheck()) {
-                                if (LOG.isTraceEnabled()) {
-                                    LOG.trace("Connection has expired: {} and will be destroyed", connection);
-                                }
-
-                                return false;
-                            }
-
-                            return true;
-                        }
-                    });
-
-            // Set max idle (not max active) since our connections always idle in the pool.
-            this.connectionsPool.setMaxIdlePerKey(1);
-
-            // We always want our validate method to control when idle objects are evicted.
-            this.connectionsPool.setTestOnBorrow(true);
-            this.connectionsPool.setTestWhileIdle(true);
-        }
-    }
-
-    /**
-     * @return the currently configured ConnectionFactory used to create the pooled Connections.
-     */
-    public ConnectionFactory getConnectionFactory() {
-        return connectionFactory;
-    }
-    @Override
-    public Connection createConnection() throws JMSException {
-        return createConnection(null, null);
-    }
-
-    @Override
-    public synchronized Connection createConnection(String userName, String password) throws JMSException {
-        if (stopped.get()) {
-            LOG.debug("PooledConnectionFactory is stopped, skip create new connection.");
-            return null;
-        }
-
-        ConnectionPool connection = null;
-        ConnectionKey key = new ConnectionKey(userName, password);
-
-        // This will either return an existing non-expired ConnectionPool or it
-        // will create a new one to meet the demand.
-        if (getConnectionsPool().getNumIdle(key) < getMaxConnections()) {
-            try {
-                // we want borrowObject to return the one we added.
-                connectionsPool.setLifo(true);
-                connectionsPool.addObject(key);
-            } catch (Exception e) {
-                throw createJmsException("Error while attempting to add new Connection to the pool", e);
-            }
-        } else {
-            // now we want the oldest one in the pool.
-            connectionsPool.setLifo(false);
-        }
-
-        try {
-
-            // We can race against other threads returning the connection when there is an
-            // expiration or idle timeout.  We keep pulling out ConnectionPool instances until
-            // we win and get a non-closed instance and then increment the reference count
-            // under lock to prevent another thread from triggering an expiration check and
-            // pulling the rug out from under us.
-            while (true) {
-                ConnectionPool cp = connectionsPool.borrowObject(key);
-                synchronized (cp) {
-                    if (cp.getConnection() != null) {
-                        cp.incrementReferenceCount();
-                        connection = cp;
-                        break;
-                    }
-
-                    // Return the bad one to the pool and let if get destroyed as normal.
-                    connectionsPool.returnObject(key, cp);
-                }
-            }
-        } catch (Exception e) {
-            throw createJmsException("Error while attempting to retrieve a connection from the pool", e);
-        }
-
-        try {
-            connectionsPool.returnObject(key, connection);
-        } catch (Exception e) {
-            throw createJmsException("Error when returning connection to the pool", e);
-        }
-
-        return newPooledConnection(connection);
-    }
-
-    protected Connection newPooledConnection(ConnectionPool connection) {
-        return new PooledConnection(connection);
-    }
-
-    private JMSException createJmsException(String msg, Exception cause) {
-        JMSException exception = new JMSException(msg);
-        exception.setLinkedException(cause);
-        exception.initCause(cause);
-        return exception;
-    }
-
-    protected Connection createConnection(ConnectionKey key) throws JMSException {
-        if (key.getUserName() == null && key.getPassword() == null) {
-            return connectionFactory.createConnection();
-        } else {
-            return connectionFactory.createConnection(key.getUserName(), key.getPassword());
-        }
-    }
-
-    public void start() {
-        LOG.debug("Starting the PooledConnectionFactory: create on start = {}", isCreateConnectionOnStartup());
-        stopped.set(false);
-        if (isCreateConnectionOnStartup()) {
-            try {
-                // warm the pool by creating a connection during startup
-                createConnection();
-            } catch (JMSException e) {
-                LOG.warn("Create pooled connection during start failed. This exception will be ignored.", e);
-            }
-        }
-    }
-
-    public void stop() {
-        if (stopped.compareAndSet(false, true)) {
-            LOG.debug("Stopping the PooledConnectionFactory, number of connections in cache: {}",
-                    connectionsPool != null ? connectionsPool.getNumActive() : 0);
-            try {
-                if (connectionsPool != null) {
-                    connectionsPool.close();
-                }
-            } catch (Exception e) {
-            }
-        }
-    }
-
-    /**
-     * Clears all connections from the pool.  Each connection that is currently in the pool is
-     * closed and removed from the pool.  A new connection will be created on the next call to
-     * {@link #createConnection()}.  Care should be taken when using this method as Connections that
-     * are in use be client's will be closed.
-     */
-    public void clear() {
-
-        if (stopped.get()) {
-            return;
-        }
-
-        getConnectionsPool().clear();
-    }
-
-    /**
-     * Returns the currently configured maximum number of sessions a pooled Connection will
-     * create before it either blocks or throws an exception when a new session is requested,
-     * depending on configuration.
-     *
-     * @return the number of session instances that can be taken from a pooled connection.
-     */
-    public int getMaximumActiveSessionPerConnection() {
-        return maximumActiveSessionPerConnection;
-    }
-
-    /**
-     * Sets the maximum number of active sessions per connection
-     *
-     * @param maximumActiveSessionPerConnection
-     *      The maximum number of active session per connection in the pool.
-     */
-    public void setMaximumActiveSessionPerConnection(int maximumActiveSessionPerConnection) {
-        this.maximumActiveSessionPerConnection = maximumActiveSessionPerConnection;
-    }
-
-    /**
-     * Controls the behavior of the internal session pool. By default the call to
-     * Connection.getSession() will block if the session pool is full.  If the
-     * argument false is given, it will change the default behavior and instead the
-     * call to getSession() will throw a JMSException.
-     *
-     * The size of the session pool is controlled by the @see #maximumActive
-     * property.
-     *
-     * @param block - if true, the call to getSession() blocks if the pool is full
-     * until a session object is available.  defaults to true.
-     */
-    public void setBlockIfSessionPoolIsFull(boolean block) {
-        this.blockIfSessionPoolIsFull = block;
-    }
-
-    /**
-     * Returns whether a pooled Connection will enter a blocked state or will throw an Exception
-     * once the maximum number of sessions has been borrowed from the the Session Pool.
-     *
-     * @return true if the pooled Connection createSession method will block when the limit is hit.
-     * @see #setBlockIfSessionPoolIsFull(boolean)
-     */
-    public boolean isBlockIfSessionPoolIsFull() {
-        return this.blockIfSessionPoolIsFull;
-    }
-
-    /**
-     * Returns the maximum number to pooled Connections that this factory will allow before it
-     * begins to return connections from the pool on calls to ({@link #createConnection()}.
-     *
-     * @return the maxConnections that will be created for this pool.
-     */
-    public int getMaxConnections() {
-        return getConnectionsPool().getMaxIdlePerKey();
-    }
-
-    /**
-     * Sets the maximum number of pooled Connections (defaults to one).  Each call to
-     * {@link #createConnection()} will result in a new Connection being create up to the max
-     * connections value.
-     *
-     * @param maxConnections the maxConnections to set
-     */
-    public void setMaxConnections(int maxConnections) {
-        getConnectionsPool().setMaxIdlePerKey(maxConnections);
-    }
-
-    /**
-     * Gets the Idle timeout value applied to new Connection's that are created by this pool.
-     * <p/>
-     * The idle timeout is used determine if a Connection instance has sat to long in the pool unused
-     * and if so is closed and removed from the pool.  The default value is 30 seconds.
-     *
-     * @return idle timeout value (milliseconds)
-     */
-    public int getIdleTimeout() {
-        return idleTimeout;
-    }
-
-    /**
-     * Sets the idle timeout  value for Connection's that are created by this pool in Milliseconds,
-     * defaults to 30 seconds.
-     * <p/>
-     * For a Connection that is in the pool but has no current users the idle timeout determines how
-     * long the Connection can live before it is eligible for removal from the pool.  Normally the
-     * connections are tested when an attempt to check one out occurs so a Connection instance can sit
-     * in the pool much longer than its idle timeout if connections are used infrequently.
-     *
-     * @param idleTimeout
-     *      The maximum time a pooled Connection can sit unused before it is eligible for removal.
-     */
-    public void setIdleTimeout(int idleTimeout) {
-        this.idleTimeout = idleTimeout;
-    }
-
-    /**
-     * allow connections to expire, irrespective of load or idle time. This is useful with failover
-     * to force a reconnect from the pool, to reestablish load balancing or use of the master post recovery
-     *
-     * @param expiryTimeout non zero in milliseconds
-     */
-    public void setExpiryTimeout(long expiryTimeout) {
-        this.expiryTimeout = expiryTimeout;
-    }
-
-    /**
-     * @return the configured expiration timeout for connections in the pool.
-     */
-    public long getExpiryTimeout() {
-        return expiryTimeout;
-    }
-
-    /**
-     * @return true if a Connection is created immediately on a call to {@link #start()}.
-     */
-    public boolean isCreateConnectionOnStartup() {
-        return createConnectionOnStartup;
-    }
-
-    /**
-     * Whether to create a connection on starting this {@link PooledConnectionFactory}.
-     * <p/>
-     * This can be used to warm-up the pool on startup. Notice that any kind of exception
-     * happens during startup is logged at WARN level and ignored.
-     *
-     * @param createConnectionOnStartup <tt>true</tt> to create a connection on startup
-     */
-    public void setCreateConnectionOnStartup(boolean createConnectionOnStartup) {
-        this.createConnectionOnStartup = createConnectionOnStartup;
-    }
-
-    /**
-     * Should Sessions use one anonymous producer for all producer requests or should a new
-     * MessageProducer be created for each request to create a producer object, default is true.
-     *
-     * When enabled the session only needs to allocate one MessageProducer for all requests and
-     * the MessageProducer#send(destination, message) method can be used.  Normally this is the
-     * right thing to do however it does result in the Broker not showing the producers per
-     * destination.
-     *
-     * @return true if a PooledSession will use only a single anonymous message producer instance.
-     */
-    public boolean isUseAnonymousProducers() {
-        return this.useAnonymousProducers;
-    }
-
-    /**
-     * Sets whether a PooledSession uses only one anonymous MessageProducer instance or creates
-     * a new MessageProducer for each call the create a MessageProducer.
-     *
-     * @param value
-     *      Boolean value that configures whether anonymous producers are used.
-     */
-    public void setUseAnonymousProducers(boolean value) {
-        this.useAnonymousProducers = value;
-    }
-
-    /**
-     * Gets the Pool of ConnectionPool instances which are keyed by different ConnectionKeys.
-     *
-     * @return this factories pool of ConnectionPool instances.
-     */
-    protected GenericKeyedObjectPool<ConnectionKey, ConnectionPool> getConnectionsPool() {
-        initConnectionsPool();
-        return this.connectionsPool;
-    }
-
-    /**
-     * Sets the number of milliseconds to sleep between runs of the idle Connection eviction thread.
-     * When non-positive, no idle object eviction thread will be run, and Connections will only be
-     * checked on borrow to determine if they have sat idle for too long or have failed for some
-     * other reason.
-     * <p/>
-     * By default this value is set to -1 and no expiration thread ever runs.
-     *
-     * @param timeBetweenExpirationCheckMillis
-     *      The time to wait between runs of the idle Connection eviction thread.
-     */
-    public void setTimeBetweenExpirationCheckMillis(long timeBetweenExpirationCheckMillis) {
-        getConnectionsPool().setTimeBetweenEvictionRunsMillis(timeBetweenExpirationCheckMillis);
-    }
-
-    /**
-     * @return the number of milliseconds to sleep between runs of the idle connection eviction thread.
-     */
-    public long getTimeBetweenExpirationCheckMillis() {
-        return getConnectionsPool().getTimeBetweenEvictionRunsMillis();
-    }
-
-    /**
-     * @return the number of Connections currently in the Pool
-     */
-    public int getNumConnections() {
-        return getConnectionsPool().getNumIdle();
-    }
-
-    /**
-     * Delegate that creates each instance of an ConnectionPool object.  Subclasses can override
-     * this method to customize the type of connection pool returned.
-     *
-     * @param connection
-     *
-     * @return instance of a new ConnectionPool.
-     */
-    protected ConnectionPool createConnectionPool(Connection connection) {
-        return new ConnectionPool(connection);
-    }
-
-    /**
-     * Returns the timeout to use for blocking creating new sessions
-     *
-     * @return true if the pooled Connection createSession method will block when the limit is hit.
-     * @see #setBlockIfSessionPoolIsFull(boolean)
-     */
-    public long getBlockIfSessionPoolIsFullTimeout() {
-        return blockIfSessionPoolIsFullTimeout;
-    }
-
-    /**
-     * Controls the behavior of the internal session pool. By default the call to
-     * Connection.getSession() will block if the session pool is full.  This setting
-     * will affect how long it blocks and throws an exception after the timeout.
-     *
-     * The size of the session pool is controlled by the @see #maximumActive
-     * property.
-     *
-     * Whether or not the call to create session blocks is controlled by the @see #blockIfSessionPoolIsFull
-     * property
-     *
-     * @param blockIfSessionPoolIsFullTimeout - if blockIfSessionPoolIsFullTimeout is true,
-     *                                        then use this setting to configure how long to block before retry
-     */
-    public void setBlockIfSessionPoolIsFullTimeout(long blockIfSessionPoolIsFullTimeout) {
-        this.blockIfSessionPoolIsFullTimeout = blockIfSessionPoolIsFullTimeout;
-    }
-
-    @Override
-    public QueueConnection createQueueConnection() throws JMSException {
-        return (QueueConnection) createConnection();
-    }
-
-    @Override
-    public QueueConnection createQueueConnection(String userName, String password) throws JMSException {
-        return (QueueConnection) createConnection(userName, password);
-    }
-
-    @Override
-    public TopicConnection createTopicConnection() throws JMSException {
-        return (TopicConnection) createConnection();
-    }
-
-    @Override
-    public TopicConnection createTopicConnection(String userName, String password) throws JMSException {
-        return (TopicConnection) createConnection(userName, password);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledMessageConsumer.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledMessageConsumer.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledMessageConsumer.java
deleted file mode 100644
index 9986513..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledMessageConsumer.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-
-/**
- * A {@link MessageConsumer} which was created by {@link PooledSession}.
- */
-public class PooledMessageConsumer implements MessageConsumer {
-
-    private final PooledSession session;
-    private final MessageConsumer delegate;
-
-    /**
-     * Wraps the message consumer.
-     *
-     * @param session  the pooled session
-     * @param delegate the created consumer to wrap
-     */
-    public PooledMessageConsumer(PooledSession session, MessageConsumer delegate) {
-        this.session = session;
-        this.delegate = delegate;
-    }
-
-    public void close() throws JMSException {
-        // ensure session removes consumer as its closed now
-        session.onConsumerClose(delegate);
-        delegate.close();
-    }
-
-    public MessageListener getMessageListener() throws JMSException {
-        return delegate.getMessageListener();
-    }
-
-    public String getMessageSelector() throws JMSException {
-        return delegate.getMessageSelector();
-    }
-
-    public Message receive() throws JMSException {
-        return delegate.receive();
-    }
-
-    public Message receive(long timeout) throws JMSException {
-        return delegate.receive(timeout);
-    }
-
-    public Message receiveNoWait() throws JMSException {
-        return delegate.receiveNoWait();
-    }
-
-    public void setMessageListener(MessageListener listener) throws JMSException {
-        delegate.setMessageListener(listener);
-    }
-
-    public String toString() {
-        return delegate.toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledProducer.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledProducer.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledProducer.java
deleted file mode 100644
index 53fdeba..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledProducer.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import javax.jms.Destination;
-import javax.jms.InvalidDestinationException;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageProducer;
-
-/**
- * A pooled {@link MessageProducer}
- */
-public class PooledProducer implements MessageProducer {
-
-    private final MessageProducer messageProducer;
-    private final Destination destination;
-
-    private int deliveryMode;
-    private boolean disableMessageID;
-    private boolean disableMessageTimestamp;
-    private int priority;
-    private long timeToLive;
-    private boolean anonymous = true;
-
-    public PooledProducer(MessageProducer messageProducer, Destination destination) throws JMSException {
-        this.messageProducer = messageProducer;
-        this.destination = destination;
-        this.anonymous = messageProducer.getDestination() == null;
-
-        this.deliveryMode = messageProducer.getDeliveryMode();
-        this.disableMessageID = messageProducer.getDisableMessageID();
-        this.disableMessageTimestamp = messageProducer.getDisableMessageTimestamp();
-        this.priority = messageProducer.getPriority();
-        this.timeToLive = messageProducer.getTimeToLive();
-    }
-
-    @Override
-    public void close() throws JMSException {
-        if (!anonymous) {
-            this.messageProducer.close();
-        }
-    }
-
-    @Override
-    public void send(Destination destination, Message message) throws JMSException {
-        send(destination, message, getDeliveryMode(), getPriority(), getTimeToLive());
-    }
-
-    @Override
-    public void send(Message message) throws JMSException {
-        send(destination, message, getDeliveryMode(), getPriority(), getTimeToLive());
-    }
-
-    @Override
-    public void send(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
-        send(destination, message, deliveryMode, priority, timeToLive);
-    }
-
-    @Override
-    public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException {
-
-        if (destination == null) {
-            if (messageProducer.getDestination() == null) {
-                throw new UnsupportedOperationException("A destination must be specified.");
-            }
-            throw new InvalidDestinationException("Don't understand null destinations");
-        }
-
-        MessageProducer messageProducer = getMessageProducer();
-
-        // just in case let only one thread send at once
-        synchronized (messageProducer) {
-
-            if (anonymous && this.destination != null && !this.destination.equals(destination)) {
-                throw new UnsupportedOperationException("This producer can only send messages to: " + this.destination);
-            }
-
-            // Producer will do it's own Destination validation so always use the destination
-            // based send method otherwise we might violate a JMS rule.
-            messageProducer.send(destination, message, deliveryMode, priority, timeToLive);
-        }
-    }
-
-    @Override
-    public Destination getDestination() {
-        return destination;
-    }
-
-    @Override
-    public int getDeliveryMode() {
-        return deliveryMode;
-    }
-
-    @Override
-    public void setDeliveryMode(int deliveryMode) {
-        this.deliveryMode = deliveryMode;
-    }
-
-    @Override
-    public boolean getDisableMessageID() {
-        return disableMessageID;
-    }
-
-    @Override
-    public void setDisableMessageID(boolean disableMessageID) {
-        this.disableMessageID = disableMessageID;
-    }
-
-    @Override
-    public boolean getDisableMessageTimestamp() {
-        return disableMessageTimestamp;
-    }
-
-    @Override
-    public void setDisableMessageTimestamp(boolean disableMessageTimestamp) {
-        this.disableMessageTimestamp = disableMessageTimestamp;
-    }
-
-    @Override
-    public int getPriority() {
-        return priority;
-    }
-
-    @Override
-    public void setPriority(int priority) {
-        this.priority = priority;
-    }
-
-    @Override
-    public long getTimeToLive() {
-        return timeToLive;
-    }
-
-    @Override
-    public void setTimeToLive(long timeToLive) {
-        this.timeToLive = timeToLive;
-    }
-
-    // Implementation methods
-    // -------------------------------------------------------------------------
-    protected MessageProducer getMessageProducer() {
-        return messageProducer;
-    }
-
-    protected boolean isAnonymous() {
-        return anonymous;
-    }
-
-    @Override
-    public String toString() {
-        return "PooledProducer { " + messageProducer + " }";
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledQueueSender.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledQueueSender.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledQueueSender.java
deleted file mode 100644
index f0acca2..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledQueueSender.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.Queue;
-import javax.jms.QueueSender;
-
-/**
- * 
- */
-public class PooledQueueSender extends PooledProducer implements QueueSender {
-
-    public PooledQueueSender(QueueSender messageProducer, Destination destination) throws JMSException {
-        super(messageProducer, destination);
-    }
-
-    public void send(Queue queue, Message message, int i, int i1, long l) throws JMSException {
-        getQueueSender().send(queue, message, i, i1, l);
-    }
-
-    public void send(Queue queue, Message message) throws JMSException {
-        getQueueSender().send(queue, message);
-    }
-
-    public Queue getQueue() throws JMSException {
-        return getQueueSender().getQueue();
-    }
-
-
-    protected QueueSender getQueueSender() {
-        return (QueueSender) getMessageProducer();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSession.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSession.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSession.java
deleted file mode 100644
index 941732e..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSession.java
+++ /dev/null
@@ -1,497 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import org.apache.commons.pool2.KeyedObjectPool;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jms.BytesMessage;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.MapMessage;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageListener;
-import javax.jms.MessageProducer;
-import javax.jms.ObjectMessage;
-import javax.jms.Queue;
-import javax.jms.QueueBrowser;
-import javax.jms.QueueReceiver;
-import javax.jms.QueueSender;
-import javax.jms.QueueSession;
-import javax.jms.Session;
-import javax.jms.StreamMessage;
-import javax.jms.TemporaryQueue;
-import javax.jms.TemporaryTopic;
-import javax.jms.TextMessage;
-import javax.jms.Topic;
-import javax.jms.TopicPublisher;
-import javax.jms.TopicSession;
-import javax.jms.TopicSubscriber;
-import javax.jms.XASession;
-import javax.transaction.xa.XAResource;
-import java.io.Serializable;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-public class PooledSession implements Session, TopicSession, QueueSession, XASession {
-    private static final transient Logger LOG = LoggerFactory.getLogger(PooledSession.class);
-
-    private final SessionKey key;
-    private final KeyedObjectPool<SessionKey, PooledSession> sessionPool;
-    private final CopyOnWriteArrayList<MessageConsumer> consumers = new CopyOnWriteArrayList<>();
-    private final CopyOnWriteArrayList<QueueBrowser> browsers = new CopyOnWriteArrayList<>();
-    private final CopyOnWriteArrayList<PooledSessionEventListener> sessionEventListeners = new CopyOnWriteArrayList<>();
-
-    private MessageProducer producer;
-    private TopicPublisher publisher;
-    private QueueSender sender;
-
-    private Session session;
-    private boolean transactional = true;
-    private boolean ignoreClose;
-    private boolean isXa;
-    private boolean useAnonymousProducers = true;
-
-    public PooledSession(SessionKey key, Session session, KeyedObjectPool<SessionKey, PooledSession> sessionPool, boolean transactional, boolean anonymous) {
-        this.key = key;
-        this.session = session;
-        this.sessionPool = sessionPool;
-        this.transactional = transactional;
-        this.useAnonymousProducers = anonymous;
-    }
-
-    public void addSessionEventListener(PooledSessionEventListener listener) {
-        // only add if really needed
-        if (!sessionEventListeners.contains(listener)) {
-            this.sessionEventListeners.add(listener);
-        }
-    }
-
-    protected boolean isIgnoreClose() {
-        return ignoreClose;
-    }
-
-    protected void setIgnoreClose(boolean ignoreClose) {
-        this.ignoreClose = ignoreClose;
-    }
-
-    @Override
-    public void close() throws JMSException {
-        if (!ignoreClose) {
-            boolean invalidate = false;
-            try {
-                // lets reset the session
-                getInternalSession().setMessageListener(null);
-
-                // Close any consumers and browsers that may have been created.
-                for (MessageConsumer consumer : consumers) {
-                    consumer.close();
-                }
-
-                for (QueueBrowser browser : browsers) {
-                    browser.close();
-                }
-
-                if (transactional && !isXa) {
-                    try {
-                        getInternalSession().rollback();
-                    } catch (JMSException e) {
-                        invalidate = true;
-                        LOG.warn("Caught exception trying rollback() when putting session back into the pool, will invalidate. " + e, e);
-                    }
-                }
-            } catch (JMSException ex) {
-                invalidate = true;
-                LOG.warn("Caught exception trying close() when putting session back into the pool, will invalidate. " + ex, ex);
-            } finally {
-                consumers.clear();
-                browsers.clear();
-                for (PooledSessionEventListener listener : this.sessionEventListeners) {
-                    listener.onSessionClosed(this);
-                }
-                sessionEventListeners.clear();
-            }
-
-            if (invalidate) {
-                // lets close the session and not put the session back into the pool
-                // instead invalidate it so the pool can create a new one on demand.
-                if (session != null) {
-                    try {
-                        session.close();
-                    } catch (JMSException e1) {
-                        LOG.trace("Ignoring exception on close as discarding session: " + e1, e1);
-                    }
-                    session = null;
-                }
-                try {
-                    sessionPool.invalidateObject(key, this);
-                } catch (Exception e) {
-                    LOG.trace("Ignoring exception on invalidateObject as discarding session: " + e, e);
-                }
-            } else {
-                try {
-                    sessionPool.returnObject(key, this);
-                } catch (Exception e) {
-                    javax.jms.IllegalStateException illegalStateException = new javax.jms.IllegalStateException(e.toString());
-                    illegalStateException.initCause(e);
-                    throw illegalStateException;
-                }
-            }
-        }
-    }
-
-    @Override
-    public void commit() throws JMSException {
-        getInternalSession().commit();
-    }
-
-    @Override
-    public BytesMessage createBytesMessage() throws JMSException {
-        return getInternalSession().createBytesMessage();
-    }
-
-    @Override
-    public MapMessage createMapMessage() throws JMSException {
-        return getInternalSession().createMapMessage();
-    }
-
-    @Override
-    public Message createMessage() throws JMSException {
-        return getInternalSession().createMessage();
-    }
-
-    @Override
-    public ObjectMessage createObjectMessage() throws JMSException {
-        return getInternalSession().createObjectMessage();
-    }
-
-    @Override
-    public ObjectMessage createObjectMessage(Serializable serializable) throws JMSException {
-        return getInternalSession().createObjectMessage(serializable);
-    }
-
-    @Override
-    public Queue createQueue(String s) throws JMSException {
-        return getInternalSession().createQueue(s);
-    }
-
-    @Override
-    public StreamMessage createStreamMessage() throws JMSException {
-        return getInternalSession().createStreamMessage();
-    }
-
-    @Override
-    public TemporaryQueue createTemporaryQueue() throws JMSException {
-        TemporaryQueue result;
-
-        result = getInternalSession().createTemporaryQueue();
-
-        // Notify all of the listeners of the created temporary Queue.
-        for (PooledSessionEventListener listener : this.sessionEventListeners) {
-            listener.onTemporaryQueueCreate(result);
-        }
-
-        return result;
-    }
-
-    @Override
-    public TemporaryTopic createTemporaryTopic() throws JMSException {
-        TemporaryTopic result;
-
-        result = getInternalSession().createTemporaryTopic();
-
-        // Notify all of the listeners of the created temporary Topic.
-        for (PooledSessionEventListener listener : this.sessionEventListeners) {
-            listener.onTemporaryTopicCreate(result);
-        }
-
-        return result;
-    }
-
-    @Override
-    public void unsubscribe(String s) throws JMSException {
-        getInternalSession().unsubscribe(s);
-    }
-
-    @Override
-    public TextMessage createTextMessage() throws JMSException {
-        return getInternalSession().createTextMessage();
-    }
-
-    @Override
-    public TextMessage createTextMessage(String s) throws JMSException {
-        return getInternalSession().createTextMessage(s);
-    }
-
-    @Override
-    public Topic createTopic(String s) throws JMSException {
-        return getInternalSession().createTopic(s);
-    }
-
-    @Override
-    public int getAcknowledgeMode() throws JMSException {
-        return getInternalSession().getAcknowledgeMode();
-    }
-
-    @Override
-    public boolean getTransacted() throws JMSException {
-        return getInternalSession().getTransacted();
-    }
-
-    @Override
-    public void recover() throws JMSException {
-        getInternalSession().recover();
-    }
-
-    @Override
-    public void rollback() throws JMSException {
-        getInternalSession().rollback();
-    }
-
-    @Override
-    public XAResource getXAResource() {
-        if (session instanceof XASession) {
-            return ((XASession) session).getXAResource();
-        }
-        return null;
-    }
-
-    @Override
-    public Session getSession() {
-        return this;
-    }
-
-    @Override
-    public void run() {
-        if (session != null) {
-            session.run();
-        }
-    }
-
-    // Consumer related methods
-    // -------------------------------------------------------------------------
-    @Override
-    public QueueBrowser createBrowser(Queue queue) throws JMSException {
-        return addQueueBrowser(getInternalSession().createBrowser(queue));
-    }
-
-    @Override
-    public QueueBrowser createBrowser(Queue queue, String selector) throws JMSException {
-        return addQueueBrowser(getInternalSession().createBrowser(queue, selector));
-    }
-
-    @Override
-    public MessageConsumer createConsumer(Destination destination) throws JMSException {
-        return addConsumer(getInternalSession().createConsumer(destination));
-    }
-
-    @Override
-    public MessageConsumer createConsumer(Destination destination, String selector) throws JMSException {
-        return addConsumer(getInternalSession().createConsumer(destination, selector));
-    }
-
-    @Override
-    public MessageConsumer createConsumer(Destination destination, String selector, boolean noLocal) throws JMSException {
-        return addConsumer(getInternalSession().createConsumer(destination, selector, noLocal));
-    }
-
-    @Override
-    public TopicSubscriber createDurableSubscriber(Topic topic, String selector) throws JMSException {
-        return addTopicSubscriber(getInternalSession().createDurableSubscriber(topic, selector));
-    }
-
-    @Override
-    public TopicSubscriber createDurableSubscriber(Topic topic, String name, String selector, boolean noLocal) throws JMSException {
-        return addTopicSubscriber(getInternalSession().createDurableSubscriber(topic, name, selector, noLocal));
-    }
-
-    @Override
-    public MessageListener getMessageListener() throws JMSException {
-        return getInternalSession().getMessageListener();
-    }
-
-    @Override
-    public void setMessageListener(MessageListener messageListener) throws JMSException {
-        getInternalSession().setMessageListener(messageListener);
-    }
-
-    @Override
-    public TopicSubscriber createSubscriber(Topic topic) throws JMSException {
-        return addTopicSubscriber(((TopicSession) getInternalSession()).createSubscriber(topic));
-    }
-
-    @Override
-    public TopicSubscriber createSubscriber(Topic topic, String selector, boolean local) throws JMSException {
-        return addTopicSubscriber(((TopicSession) getInternalSession()).createSubscriber(topic, selector, local));
-    }
-
-    @Override
-    public QueueReceiver createReceiver(Queue queue) throws JMSException {
-        return addQueueReceiver(((QueueSession) getInternalSession()).createReceiver(queue));
-    }
-
-    @Override
-    public QueueReceiver createReceiver(Queue queue, String selector) throws JMSException {
-        return addQueueReceiver(((QueueSession) getInternalSession()).createReceiver(queue, selector));
-    }
-
-    // Producer related methods
-    // -------------------------------------------------------------------------
-    @Override
-    public MessageProducer createProducer(Destination destination) throws JMSException {
-        return new PooledProducer(getMessageProducer(destination), destination);
-    }
-
-    @Override
-    public QueueSender createSender(Queue queue) throws JMSException {
-        return new PooledQueueSender(getQueueSender(queue), queue);
-    }
-
-    @Override
-    public TopicPublisher createPublisher(Topic topic) throws JMSException {
-        return new PooledTopicPublisher(getTopicPublisher(topic), topic);
-    }
-
-    public Session getInternalSession() throws IllegalStateException {
-        if (session == null) {
-            throw new IllegalStateException("The session has already been closed");
-        }
-        return session;
-    }
-
-    public MessageProducer getMessageProducer() throws JMSException {
-        return getMessageProducer(null);
-    }
-
-    public MessageProducer getMessageProducer(Destination destination) throws JMSException {
-        MessageProducer result = null;
-
-        if (useAnonymousProducers) {
-            if (producer == null) {
-                // Don't allow for duplicate anonymous producers.
-                synchronized (this) {
-                    if (producer == null) {
-                        producer = getInternalSession().createProducer(null);
-                    }
-                }
-            }
-
-            result = producer;
-        } else {
-            result = getInternalSession().createProducer(destination);
-        }
-
-        return result;
-    }
-
-    public QueueSender getQueueSender() throws JMSException {
-        return getQueueSender(null);
-    }
-
-    public QueueSender getQueueSender(Queue destination) throws JMSException {
-        QueueSender result = null;
-
-        if (useAnonymousProducers) {
-            if (sender == null) {
-                // Don't allow for duplicate anonymous producers.
-                synchronized (this) {
-                    if (sender == null) {
-                        sender = ((QueueSession) getInternalSession()).createSender(null);
-                    }
-                }
-            }
-
-            result = sender;
-        } else {
-            result = ((QueueSession) getInternalSession()).createSender(destination);
-        }
-
-        return result;
-    }
-
-    public TopicPublisher getTopicPublisher() throws JMSException {
-        return getTopicPublisher(null);
-    }
-
-    public TopicPublisher getTopicPublisher(Topic destination) throws JMSException {
-        TopicPublisher result = null;
-
-        if (useAnonymousProducers) {
-            if (publisher == null) {
-                // Don't allow for duplicate anonymous producers.
-                synchronized (this) {
-                    if (publisher == null) {
-                        publisher = ((TopicSession) getInternalSession()).createPublisher(null);
-                    }
-                }
-            }
-
-            result = publisher;
-        } else {
-            result = ((TopicSession) getInternalSession()).createPublisher(destination);
-        }
-
-        return result;
-    }
-
-    private QueueBrowser addQueueBrowser(QueueBrowser browser) {
-        browsers.add(browser);
-        return browser;
-    }
-
-    private MessageConsumer addConsumer(MessageConsumer consumer) {
-        consumers.add(consumer);
-        // must wrap in PooledMessageConsumer to ensure the onConsumerClose
-        // method is invoked when the returned consumer is closed, to avoid memory
-        // leak in this session class in case many consumers is created
-        return new PooledMessageConsumer(this, consumer);
-    }
-
-    private TopicSubscriber addTopicSubscriber(TopicSubscriber subscriber) {
-        consumers.add(subscriber);
-        return subscriber;
-    }
-
-    private QueueReceiver addQueueReceiver(QueueReceiver receiver) {
-        consumers.add(receiver);
-        return receiver;
-    }
-
-    public void setIsXa(boolean isXa) {
-        this.isXa = isXa;
-    }
-
-    @Override
-    public String toString() {
-        return "PooledSession { " + session + " }";
-    }
-
-    /**
-     * Callback invoked when the consumer is closed.
-     * <p/>
-     * This is used to keep track of an explicit closed consumer created by this
-     * session, by which we know do not need to keep track of the consumer, as
-     * its already closed.
-     *
-     * @param consumer
-     *            the consumer which is being closed
-     */
-    protected void onConsumerClose(MessageConsumer consumer) {
-        consumers.remove(consumer);
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSessionEventListener.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSessionEventListener.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSessionEventListener.java
deleted file mode 100644
index b9a5dd3..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledSessionEventListener.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import javax.jms.TemporaryQueue;
-import javax.jms.TemporaryTopic;
-
-interface PooledSessionEventListener {
-
-    /**
-     * Called on successful creation of a new TemporaryQueue.
-     *
-     * @param tempQueue
-     *      The TemporaryQueue just created.
-     */
-    void onTemporaryQueueCreate(TemporaryQueue tempQueue);
-
-    /**
-     * Called on successful creation of a new TemporaryTopic.
-     *
-     * @param tempTopic
-     *      The TemporaryTopic just created.
-     */
-    void onTemporaryTopicCreate(TemporaryTopic tempTopic);
-
-    /**
-     * Called when the PooledSession is closed.
-     *
-     * @param session
-     *      The PooledSession that has been closed.
-     */
-    void onSessionClosed(PooledSession session);
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledTopicPublisher.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledTopicPublisher.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledTopicPublisher.java
deleted file mode 100644
index b466151..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/PooledTopicPublisher.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.Topic;
-import javax.jms.TopicPublisher;
-
-/**
- * 
- */
-public class PooledTopicPublisher extends PooledProducer implements TopicPublisher {
-
-    public PooledTopicPublisher(TopicPublisher messageProducer, Destination destination) throws JMSException {
-        super(messageProducer, destination);
-    }
-
-    public Topic getTopic() throws JMSException {
-        return getTopicPublisher().getTopic();
-    }
-
-    public void publish(Message message) throws JMSException {
-        getTopicPublisher().publish((Topic) getDestination(), message);
-    }
-
-    public void publish(Message message, int i, int i1, long l) throws JMSException {
-        getTopicPublisher().publish((Topic) getDestination(), message, i, i1, l);
-    }
-
-    public void publish(Topic topic, Message message) throws JMSException {
-        getTopicPublisher().publish(topic, message);
-    }
-
-    public void publish(Topic topic, Message message, int i, int i1, long l) throws JMSException {
-        getTopicPublisher().publish(topic, message, i, i1, l);
-    }
-
-    protected TopicPublisher getTopicPublisher() {
-        return (TopicPublisher) getMessageProducer();
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/SessionKey.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/SessionKey.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/SessionKey.java
deleted file mode 100644
index 389438a..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/SessionKey.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal;
-
-/**
- * A cache key for the session details
- *
- * 
- */
-public class SessionKey {
-
-    private boolean transacted;
-    private int ackMode;
-
-    private int hash;
-
-    public SessionKey(boolean transacted, int ackMode) {
-        this.transacted = transacted;
-        this.ackMode = ackMode;
-        hash = ackMode;
-        if (transacted) {
-            hash = 31 * hash + 1;
-        }
-    }
-
-    public int hashCode() {
-        return hash;
-    }
-
-    public boolean equals(Object that) {
-        if (this == that) {
-            return true;
-        }
-        if (that instanceof SessionKey) {
-            return equals((SessionKey) that);
-        }
-        return false;
-    }
-
-    public boolean equals(SessionKey that) {
-        return this.transacted == that.transacted && this.ackMode == that.ackMode;
-    }
-
-    public boolean isTransacted() {
-        return transacted;
-    }
-
-    public int getAckMode() {
-        return ackMode;
-    }
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/osgi/Activator.java b/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/osgi/Activator.java
deleted file mode 100644
index dfecd1c..0000000
--- a/jms/pool/src/main/java/org/apache/karaf/jms/pool/internal/osgi/Activator.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- * 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.karaf.jms.pool.internal.osgi;
-
-import org.apache.karaf.jms.pool.internal.PooledConnectionFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jms.ConnectionFactory;
-import java.util.Hashtable;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-public class Activator implements BundleActivator, ServiceTrackerCustomizer<ConnectionFactory, Activator.ConnectionFactoryData> {
-
-    public static final String PROP_PREFIX = "karaf.jms.";
-
-    public static final String PROP_OPT_IN = PROP_PREFIX + "wrap";
-
-    public static final String PROP_POOL = PROP_PREFIX + "pool.";
-
-    private static final transient Logger LOG = LoggerFactory.getLogger(Activator.class);
-
-    private BundleContext context;
-    private ServiceTracker<ConnectionFactory, ConnectionFactoryData> cfTracker;
-
-    @Override
-    public void start(BundleContext context) throws Exception {
-        this.context = context;
-        cfTracker = new ServiceTracker<>(
-                context,
-                context.createFilter("(&(objectClass=javax.jms.ConnectionFactory)(" + PROP_OPT_IN + "=*))"),
-                this);
-        cfTracker.open();
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        cfTracker.close();
-    }
-
-    @Override
-    public ConnectionFactoryData addingService(ServiceReference<ConnectionFactory> reference) {
-        ConnectionFactoryData data = new ConnectionFactoryData(context, reference);
-        try {
-            data.init();
-            return data;
-        } catch (Throwable t) {
-            LOG.warn("Error creating pooled JMS ConnectionFactory", t);
-            data.destroy();
-            return null;
-        }
-    }
-
-    @Override
-    public void modifiedService(ServiceReference<ConnectionFactory> reference, ConnectionFactoryData service) {
-    }
-
-    @Override
-    public void removedService(ServiceReference<ConnectionFactory> reference, ConnectionFactoryData service) {
-        service.destroy();
-    }
-
-    class ConnectionFactoryData {
-
-        private final BundleContext context;
-        private final ServiceReference<ConnectionFactory> reference;
-        private ConnectionFactory connectionFactory;
-        private PooledConnectionFactory pooledConnectionFactory;
-        private ServiceRegistration<ConnectionFactory> registration;
-
-        ConnectionFactoryData(BundleContext context, ServiceReference<ConnectionFactory> reference) {
-            this.context = context;
-            this.reference = reference;
-        }
-
-        void init() throws Exception {
-            connectionFactory = context.getService(reference);
-            PooledConnectionFactory pcf = new PooledConnectionFactory(connectionFactory);
-            populate(pcf);
-            register(pcf);
-        }
-
-        void destroy() {
-            unregister();
-            if (connectionFactory != null) {
-                try {
-                    context.ungetService(reference);
-                } catch (Exception e) {
-                    // Ignore
-                } finally {
-                    connectionFactory = null;
-                }
-            }
-        }
-
-        void populate(PooledConnectionFactory pcf) {
-            setObject(PROP_POOL + "maxConnections", Integer::parseInt, pcf::setMaxConnections);
-            setObject(PROP_POOL + "maximumActiveSessionPerConnection", Integer::parseInt, pcf::setMaximumActiveSessionPerConnection);
-            setObject(PROP_POOL + "idleTimeout", Integer::parseInt, pcf::setIdleTimeout);
-            setObject(PROP_POOL + "blockIfSessionPoolIsFull", Boolean::parseBoolean, pcf::setBlockIfSessionPoolIsFull);
-            setObject(PROP_POOL + "blockIfSessionPoolIsFullTimeout", Long::parseLong, pcf::setBlockIfSessionPoolIsFullTimeout);
-            setObject(PROP_POOL + "expiryTimeout", Long::parseLong, pcf::setExpiryTimeout);
-            setObject(PROP_POOL + "createConnectionOnStartup", Boolean::parseBoolean, pcf::setCreateConnectionOnStartup);
-            setObject(PROP_POOL + "useAnonymousProducers", Boolean::parseBoolean, pcf::setUseAnonymousProducers);
-        }
-
-        <T> void setObject(String name, Function<String, T> parser, Consumer<T> setter) {
-            Object o = reference.getProperty(name);
-            if (o != null) {
-                setter.accept(parser.apply(o.toString()));
-            }
-        }
-
-        void register(PooledConnectionFactory pcf) {
-            this.pooledConnectionFactory = pcf;
-            Hashtable<String, Object> props = new Hashtable<>();
-            int ranking = 0;
-            for (String key : reference.getPropertyKeys()) {
-                Object value = reference.getProperty(key);
-                if (Constants.SERVICE_RANKING.equals(key)) {
-                    if (value instanceof Integer) {
-                        ranking = (Integer) value;
-                    }
-                } else if (!key.startsWith("service.")
-                        && !key.startsWith(PROP_PREFIX)) {
-                    props.put(key, value);
-                }
-            }
-            props.put(Constants.SERVICE_RANKING, ranking + 1);
-            pcf.start();
-            BundleContext context = reference.getBundle().getBundleContext();
-            registration = context.registerService(ConnectionFactory.class, pooledConnectionFactory, props);
-        }
-
-        void unregister() {
-            if (registration != null) {
-                try {
-                    registration.unregister();
-                } catch (Exception e) {
-                    // Ignore
-                } finally {
-                    registration = null;
-                }
-            }
-            if (pooledConnectionFactory != null) {
-                try {
-                    pooledConnectionFactory.stop();
-                } catch (Exception e) {
-                    // Ignore
-                } finally {
-                    pooledConnectionFactory = null;
-                }
-            }
-        }
-
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/JmsMBean.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/JmsMBean.java b/jms/src/main/java/org/apache/karaf/jms/JmsMBean.java
new file mode 100644
index 0000000..d62a9ba
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/JmsMBean.java
@@ -0,0 +1,165 @@
+/*
+ * 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.karaf.jms;
+
+import javax.management.MBeanException;
+import javax.management.openmbean.TabularData;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JMS MBean.
+ */
+public interface JmsMBean {
+
+    /**
+     * List the JMS connection factories.
+     *
+     * @return The {@link List} of the JMS connection factories name.
+     * @throws MBeanException If the MBean fails.
+     */
+    List<String> getConnectionfactories() throws MBeanException;
+
+    /**
+     * Create a JMS connection factory.
+     *
+     * @param name The JMS connection factory name.
+     * @param type The JMS connection factory type (ActiveMQ or WebsphereMQ).
+     * @param url The JMS connection factory URL. NB: when type is WebsphereMQ, the URL has the format host/port/queuemanager/channel.
+     * @throws MBeanException If the MBean fails.
+     */
+    void create(String name, String type, String url) throws MBeanException;
+
+    /**
+     * Create a JMS connection factory.
+     *
+     * @param name The JMS connection factory name.
+     * @param type The JMS connection factory type (ActiveMQ or WebsphereMQ).
+     * @param url The JMS connection factory URL. NB: when type is WebsphereMQ, the URL has the format host/port/queuemanager/channel.
+     * @param username The JMS connection factory authentication username.
+     * @param password The JMS connection factory authentication password.
+     * @throws MBeanException If the MBean fails.
+     */
+    void create(String name, String type, String url, String username, String password) throws MBeanException;
+
+    /**
+     * Delete a JMS connection factory.
+     *
+     * @param name The JMS connection factory name.
+     * @throws MBeanException If the MBean fails.
+     */
+    void delete(String name) throws MBeanException;
+
+    /**
+     * Get details about a JMS connection factory.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return A {@link Map} (property/value) containing details.
+     * @throws MBeanException If the MBean fails.
+     */
+    Map<String, String> info(String connectionFactory, String username, String password) throws MBeanException;
+
+    /**
+     * Count the messages on a given JMS queue.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The JMS queue name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The number of messages in the queue.
+     * @throws MBeanException If the MBean fails.
+     */
+    int count(String connectionFactory, String queue, String username, String password) throws MBeanException;
+
+    /**
+     * List the JMS queues.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The {@link List} of JMS queues.
+     * @throws MBeanException If the MBean fails.
+     */
+    List<String> queues(String connectionFactory, String username, String password) throws MBeanException;
+
+    /**
+     * List the JMS topics.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The @link List} of JMS topics.
+     * @throws MBeanException If the MBean fails.
+     */
+    List<String> topics(String connectionFactory, String username, String password) throws MBeanException;
+
+    /**
+     * Browse the messages in a JMS queue.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The JMS queue name.
+     * @param selector A selector to use to browse only certain messages.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return A {@link TabularData} containing messages details.
+     * @throws MBeanException If the MBean fails.
+     */
+    TabularData browse(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException;
+
+    /**
+     * Send a JMS message to given queue.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The JMS queue name.
+     * @param content The message content.
+     * @param replyTo The message ReplyTo.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @throws MBeanException If the MBean fails.
+     */
+    void send(String connectionFactory, String queue, String content, String replyTo, String username, String password) throws MBeanException;
+
+    /**
+     * Consume JMS messages from a given queue.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param queue The JMS queue name.
+     * @param selector A selector to use to consume only certain messages.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The number of messages consumed.
+     * @throws MBeanException If the MBean fails.
+     */
+    int consume(String connectionFactory, String queue, String selector, String username, String password) throws MBeanException;
+
+    /**
+     * Move JMS messages from one queue to another.
+     *
+     * @param connectionFactory The JMS connection factory name.
+     * @param source The source JMS queue name.
+     * @param destination The destination JMS queue name.
+     * @param selector A selector to move only certain messages.
+     * @param username The (optional) username to connect to the JMS broker.
+     * @param password The (optional) password to connect to the JMS broker.
+     * @return The number of messages moved.
+     * @throws MBeanException If the MBean fails.
+     */
+    int move(String connectionFactory, String source, String destination, String selector, String username, String password) throws MBeanException;
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/7a84233c/jms/src/main/java/org/apache/karaf/jms/JmsMessage.java
----------------------------------------------------------------------
diff --git a/jms/src/main/java/org/apache/karaf/jms/JmsMessage.java b/jms/src/main/java/org/apache/karaf/jms/JmsMessage.java
new file mode 100644
index 0000000..acf13bf
--- /dev/null
+++ b/jms/src/main/java/org/apache/karaf/jms/JmsMessage.java
@@ -0,0 +1,164 @@
+/*
+ * 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.karaf.jms;
+
+import javax.jms.*;
+import java.io.UnsupportedEncodingException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Describe a JMS message is more human readable way.
+ */
+public class JmsMessage {
+
+    private Map<String, Object> properties = new HashMap<>();
+
+    private String content;
+    private String charset = "UTF-8";
+    private String correlationID;
+    private String deliveryMode;
+    private String destination;
+    private String expiration;
+    private String messageId;
+    private int priority;
+    private boolean redelivered;
+    private String replyTo;
+    private String timestamp;
+    private String type;
+
+    public JmsMessage(Message message) {
+        try {
+            initFromMessage(message);
+        } catch (JMSException e) {
+            throw new RuntimeException(e.getMessage(), e);
+        }
+    }
+
+    public void initFromMessage(Message message) throws JMSException {
+        @SuppressWarnings("unchecked")
+        Enumeration<String> names = message.getPropertyNames();
+        while (names.hasMoreElements()) {
+            String key = names.nextElement();
+            Object value = message.getObjectProperty(key);
+            properties.put(key, value);
+        }
+
+        correlationID = message.getJMSCorrelationID();
+        if (message.getJMSDeliveryMode() == DeliveryMode.NON_PERSISTENT) {
+            deliveryMode = "Non Persistent";
+        } else {
+            deliveryMode = "Persistent";
+        }
+        Destination destinationDest = message.getJMSDestination();
+        if (destinationDest != null) {
+            destination = destinationDest.toString();
+        }
+        if (message.getJMSExpiration() > 0) {
+            expiration = new Date(message.getJMSExpiration()).toString();
+        } else {
+            expiration = "Never";
+        }
+        messageId = message.getJMSMessageID();
+        priority = message.getJMSPriority();
+        redelivered = message.getJMSRedelivered();
+        Destination replyToDest = message.getJMSReplyTo();
+        if (replyToDest != null) {
+            replyTo = replyToDest.toString();
+        }
+        if (message.getJMSTimestamp() > 0) {
+            timestamp = new Date(message.getJMSTimestamp()).toString();
+        } else {
+            timestamp = "";
+        }
+        type = message.getJMSType();
+        content = getMessageContent(message);
+    }
+
+
+    private String getMessageContent(Message message) throws JMSException {
+        if (message instanceof TextMessage) {
+            return ((TextMessage) message).getText();
+        } else if (message instanceof BytesMessage) {
+            BytesMessage bMessage = (BytesMessage) message;
+            long length = bMessage.getBodyLength();
+            byte[] content = new byte[(int) length];
+            bMessage.readBytes(content);
+            try {
+                return new String(content, charset);
+            } catch (UnsupportedEncodingException e) {
+                throw new RuntimeException(e.getMessage(), e);
+            }
+        }
+        return "";
+    }
+
+    public Map<String, Object> getProperties() {
+        return properties;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public String getCharset() {
+        return charset;
+    }
+
+    public String getCorrelationID() {
+        return correlationID;
+    }
+
+    public String getDeliveryMode() {
+        return deliveryMode;
+    }
+
+    public String getDestination() {
+        return destination;
+    }
+
+    public String getExpiration() {
+        return expiration;
+    }
+
+    public String getMessageId() {
+        return messageId;
+    }
+
+    public int getPriority() {
+        return priority;
+    }
+
+    public boolean isRedelivered() {
+        return redelivered;
+    }
+
+    public String getReplyTo() {
+        return replyTo;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+}
\ No newline at end of file


[6/6] karaf git commit: Fix problem between features config installer and file install when using factory pids

Posted by gn...@apache.org.
Fix problem between features config installer and file install when using factory pids

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b2d37089
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b2d37089
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b2d37089

Branch: refs/heads/master
Commit: b2d37089277de1019916a77738817a22d7469009
Parents: f7ea3e0
Author: Guillaume Nodet <gn...@apache.org>
Authored: Wed Jul 26 10:54:01 2017 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Wed Aug 2 14:10:48 2017 +0200

----------------------------------------------------------------------
 .../karaf/features/internal/service/FeatureConfigInstaller.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/b2d37089/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
index 5474806..e1f0ca8 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeatureConfigInstaller.java
@@ -255,7 +255,7 @@ public class FeatureConfigInstaller {
             } else {
                 cfgFile = new File(storage, pid + ".cfg");
             }
-            Configuration cfg = findExistingConfiguration(configAdmin, factoryPid, pid);
+            Configuration cfg = findExistingConfiguration(configAdmin, pid, factoryPid);
             // update the cfg file depending of the configuration
             if (cfg != null && cfg.getProperties() != null) {
                 Object val = cfg.getProperties().get(FILEINSTALL_FILE_NAME);