keycloak-aplcache

KEYCLOAK-2805 - Support for JBoss Fuse 6.3 Upgrade of CXF,

3/22/2016 6:00:43 AM

Details

diff --git a/adapters/oidc/osgi-adapter/pom.xml b/adapters/oidc/osgi-adapter/pom.xml
index 95d26d8..187dcc1 100755
--- a/adapters/oidc/osgi-adapter/pom.xml
+++ b/adapters/oidc/osgi-adapter/pom.xml
@@ -31,15 +31,19 @@
     <packaging>jar</packaging>
 
     <properties>
+
+        <cxf.version>3.1.5</cxf.version>
         <jetty9.version>8.1.17.v20150415</jetty9.version>
         <keycloak.osgi.export>
             org.keycloak.adapters.osgi.*
         </keycloak.osgi.export>
         <keycloak.osgi.import>
-            org.ops4j.pax.web.*;version="[3.0,4)",
+            org.ops4j.pax.web.*;version="[3.0,5)",
             javax.servlet.*;version="[2.5,4)";resolution:=optional,
             org.eclipse.jetty.*;version="[8.1,10)";resolution:=optional,
             org.keycloak.*;version="${project.version}",
+            org.apache.cxf.transport.http;resolution:=optional;version="[3,4)",
+            org.apache.cxf.transport.servlet;resolution:=optional;version="[3,4)",
             *;resolution:=optional
         </keycloak.osgi.import>
     </properties>
@@ -66,11 +70,22 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.ops4j.pax.web</groupId>
+            <artifactId>pax-web-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-security</artifactId>
             <version>${jetty9.version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http</artifactId>
+            <version>${cxf.version}</version>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java b/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java
index 3bff5a0..1aace71 100644
--- a/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java
+++ b/adapters/oidc/osgi-adapter/src/main/java/org/keycloak/adapters/osgi/ServletReregistrationService.java
@@ -18,15 +18,22 @@
 package org.keycloak.adapters.osgi;
 
 import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Properties;
 
 import javax.servlet.Servlet;
 
+import org.apache.cxf.transport.http.DestinationRegistry;
+import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
 import org.jboss.logging.Logger;
 import org.ops4j.pax.web.service.WebContainer;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.Configuration;
+import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.http.HttpContext;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
@@ -42,13 +49,15 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer;
  */
 public class ServletReregistrationService {
 
+    private static final String CXF_SERVLET_PREFIX = "org.apache.cxf.servlet.";
     protected static final Logger log = Logger.getLogger(ServletReregistrationService.class);
 
     private static final List<String> FILTERED_PROPERTIES = Arrays.asList("objectClass", "service.id");
 
     private BundleContext bundleContext;
-    private ServiceReference servletReference;
+    private ServiceReference managedServiceReference;
     private ServiceTracker webContainerTracker;
+    private String alias;
 
     public BundleContext getBundleContext() {
         return bundleContext;
@@ -58,24 +67,18 @@ public class ServletReregistrationService {
         this.bundleContext = bundleContext;
     }
 
-    public ServiceReference getServletReference() {
-        return servletReference;
-    }
-
-    public void setServletReference(ServiceReference servletReference) {
-        this.servletReference = servletReference;
-    }
-
-    protected ServiceTracker getWebContainerTracker() {
-        return webContainerTracker;
-    }
 
     public void start() {
-        if (servletReference == null) {
-            throw new IllegalStateException("No servlet reference provided");
+        if ( managedServiceReference == null) {
+            return;
+        }
+
+        Dictionary properties = obtainProperties();
+        alias = (String)getProp(properties, CXF_SERVLET_PREFIX + "context", "/cxf");
+        if(alias == null){
+            alias = "/cxf";
         }
 
-        final Servlet servlet = (Servlet) bundleContext.getService(servletReference);
         WebContainer externalWebContainer = findExternalWebContainer();
         if (externalWebContainer == null) {
             return;
@@ -83,18 +86,19 @@ public class ServletReregistrationService {
 
         // Unregister servlet from external container now
         try {
-            externalWebContainer.unregisterServlet(servlet);
+            externalWebContainer.unregister(alias);
             log.debug("Original servlet with alias " + getAlias() + " unregistered successfully from external web container.");
         } catch (IllegalStateException e) {
             log.warn("Can't unregister servlet due to: " + e.getMessage());
         }
 
+        final Dictionary finalProperties = properties;
         ServiceTrackerCustomizer trackerCustomizer = new ServiceTrackerCustomizer() {
 
             @Override
             public Object addingService(ServiceReference webContainerServiceReference) {
                 WebContainer ourWebContainer = (WebContainer) bundleContext.getService(webContainerServiceReference);
-                registerServlet(ourWebContainer, servlet);
+                registerServlet(ourWebContainer, finalProperties);
                 log.debugv("Servlet with alias " + getAlias() + " registered to secured web container");
                 return ourWebContainer;
             }
@@ -122,28 +126,82 @@ public class ServletReregistrationService {
 
         // Re-register servlet back to original context
         WebContainer externalWebContainer = findExternalWebContainer();
-        Servlet servlet = (Servlet) bundleContext.getService(servletReference);
-        registerServlet(externalWebContainer, servlet);
+        registerServlet(externalWebContainer,  obtainProperties());
         log.debug("Servlet with alias " + getAlias() + " registered back to external web container");
     }
 
     private String getAlias() {
-        return (String) servletReference.getProperty("alias");
+        return alias;
     }
 
-    protected void registerServlet(WebContainer webContainer, Servlet servlet) {
+    /**
+     * Code comes from org.apache.cxf.transport.http.osgi.ServletExporter#updated(java.util.Dictionary)
+     * @param webContainer
+     * @param properties
+     */
+    protected void registerServlet(WebContainer webContainer, Dictionary properties) {
+        HttpContext httpContext = webContainer.createDefaultHttpContext();
+
+        ServiceReference destinationServiceServiceReference = bundleContext.getServiceReference("org.apache.cxf.transport.http.DestinationRegistry");
+        DestinationRegistry destinationRegistry = (DestinationRegistry) bundleContext.getService(destinationServiceServiceReference);
+
+        Servlet servlet = new CXFNonSpringServlet(destinationRegistry, false);
         try {
+            if (properties == null) {
+                properties = new Properties();
+            }
+            Properties sprops = new Properties();
+            sprops.put("init-prefix",
+                    getProp(properties, CXF_SERVLET_PREFIX + "init-prefix", ""));
+            sprops.put("servlet-name",
+                    getProp(properties, CXF_SERVLET_PREFIX + "name", "cxf-osgi-transport-servlet"));
+            sprops.put("hide-service-list-page",
+                    getProp(properties, CXF_SERVLET_PREFIX + "hide-service-list-page", "false"));
+            sprops.put("disable-address-updates",
+                    getProp(properties, CXF_SERVLET_PREFIX + "disable-address-updates", "true"));
+            sprops.put("base-address",
+                    getProp(properties, CXF_SERVLET_PREFIX + "base-address", ""));
+            sprops.put("service-list-path",
+                    getProp(properties, CXF_SERVLET_PREFIX + "service-list-path", ""));
+            sprops.put("static-resources-list",
+                    getProp(properties, CXF_SERVLET_PREFIX + "static-resources-list", ""));
+            sprops.put("redirects-list",
+                    getProp(properties, CXF_SERVLET_PREFIX + "redirects-list", ""));
+            sprops.put("redirect-servlet-name",
+                    getProp(properties, CXF_SERVLET_PREFIX + "redirect-servlet-name", ""));
+            sprops.put("redirect-servlet-path",
+                    getProp(properties, CXF_SERVLET_PREFIX + "redirect-servlet-path", ""));
+            sprops.put("service-list-all-contexts",
+                    getProp(properties, CXF_SERVLET_PREFIX + "service-list-all-contexts", ""));
+            sprops.put("service-list-page-authenticate",
+                    getProp(properties, CXF_SERVLET_PREFIX + "service-list-page-authenticate", "false"));
+            sprops.put("service-list-page-authenticate-realm",
+                    getProp(properties, CXF_SERVLET_PREFIX + "service-list-page-authenticate-realm", "karaf"));
+            sprops.put("use-x-forwarded-headers",
+                    getProp(properties, CXF_SERVLET_PREFIX + "use-x-forwarded-headers", "false"));
+
+            // Accept extra properties by default, can be disabled if it is really needed
+            if (Boolean.valueOf(getProp(properties, CXF_SERVLET_PREFIX + "support.extra.properties", "true").toString())) {
+                Enumeration keys = properties.keys();
+                while (keys.hasMoreElements()) {
+                    String nextKey = keys.nextElement().toString();
+                    if (!nextKey.startsWith(CXF_SERVLET_PREFIX)) {
+                        sprops.put(nextKey, properties.get(nextKey));
+                    }
+                }
+            }
+
             Hashtable<String, Object> servletInitParams = new Hashtable<String, Object>();
-            String[] propNames = servletReference.getPropertyKeys();
-            for (String propName : propNames) {
+            Enumeration keys = sprops.keys();
+
+            while(keys.hasMoreElements()){
+                String propName = (String) keys.nextElement();
                 if (!FILTERED_PROPERTIES.contains(propName)) {
-                    servletInitParams.put(propName, servletReference.getProperty(propName));
+                    servletInitParams.put(propName, sprops.getProperty(propName));
                 }
             }
 
             // Try to register servlet in given web container now
-            HttpContext httpContext = webContainer.createDefaultHttpContext();
-            String alias = (String) servletReference.getProperty("alias");
             webContainer.registerServlet(alias, servlet, servletInitParams, httpContext);
         } catch (Exception e) {
             log.error("Can't register servlet in web container", e);
@@ -156,7 +214,7 @@ public class ServletReregistrationService {
      * @return web container or null
      */
     protected WebContainer findExternalWebContainer() {
-        BundleContext servletBundleContext = servletReference.getBundle().getBundleContext();
+        BundleContext servletBundleContext = managedServiceReference.getBundle().getBundleContext();
         ServiceReference webContainerReference = servletBundleContext.getServiceReference(WebContainer.class.getName());
         if (webContainerReference == null) {
             log.warn("Not found webContainer reference for bundle " + servletBundleContext);
@@ -166,4 +224,32 @@ public class ServletReregistrationService {
         }
     }
 
+    private Dictionary obtainProperties(){
+        Dictionary properties = null;
+        ServiceReference reference = bundleContext.getServiceReference(ConfigurationAdmin.class.getName());
+        ConfigurationAdmin admin = (ConfigurationAdmin) bundleContext.getService(reference);
+        try {
+            Configuration configuration = admin.getConfiguration("org.apache.cxf.osgi");
+            properties = configuration.getProperties();
+        } catch (Exception e){
+            log.warn("Unable to obtain cxf osgi configadmin reference.", e);
+        }
+        return properties;
+    }
+
+    private Object getProp(Dictionary properties, String key, Object defaultValue) {
+        Object value = null;
+        if(properties != null){
+            value = properties.get(key);
+        }
+        return value == null ? defaultValue : value;
+    }
+
+    public ServiceReference getManagedServiceReference() {
+        return managedServiceReference;
+    }
+
+    public void setManagedServiceReference(ServiceReference managedServiceReference) {
+        this.managedServiceReference = managedServiceReference;
+    }
 }
diff --git a/distribution/adapters/osgi/features/src/main/resources/features.xml b/distribution/adapters/osgi/features/src/main/resources/features.xml
index 6ead274..c9c726e 100755
--- a/distribution/adapters/osgi/features/src/main/resources/features.xml
+++ b/distribution/adapters/osgi/features/src/main/resources/features.xml
@@ -46,12 +46,21 @@
     <feature name="keycloak-jetty8-adapter" version="${project.version}" resolver="(obr)">
         <details>The keycloak Jetty8 adapter</details>
         <feature>keycloak-adapter-core</feature>
-        <feature version="[8.1,9)">jetty</feature>
+        <feature version="[8,9)">jetty</feature>
         <bundle>mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version}</bundle>
         <bundle>mvn:org.keycloak/keycloak-jetty-core/${project.version}</bundle>
         <bundle>mvn:org.keycloak/keycloak-jetty81-adapter/${project.version}</bundle>
     </feature>
 
+    <feature name="keycloak-jetty9-adapter" version="${project.version}" resolver="(obr)">
+        <details>The keycloak Jetty9 adapter</details>
+        <feature>keycloak-adapter-core</feature>
+        <feature version="[9,10)">jetty</feature>
+        <bundle>mvn:org.keycloak/keycloak-jetty-adapter-spi/${project.version}</bundle>
+        <bundle>mvn:org.keycloak/keycloak-jetty-core/${project.version}</bundle>
+        <bundle>mvn:org.keycloak/keycloak-jetty92-adapter/${project.version}</bundle>
+    </feature>
+
     <feature name="keycloak-jaas" version="${project.version}" resolver="(obr)">
         <details>The keycloak JAAS configuration</details>
         <feature>keycloak-adapter-core</feature>
@@ -61,7 +70,6 @@
     <feature name="keycloak" version="${project.version}" resolver="(obr)">
         <details>The keycloak adapter core stuff</details>
         <feature>keycloak-osgi-adapter</feature>
-        <feature>keycloak-jetty8-adapter</feature>
         <feature>keycloak-jaas</feature>
     </feature>
 
@@ -74,4 +82,4 @@
         <bundle>mvn:org.apache.xbean/xbean-finder/3.18</bundle>
     </feature>
 
-</features>
\ No newline at end of file
+</features>
diff --git a/examples/fuse/camel/pom.xml b/examples/fuse/camel/pom.xml
index 33ff7c4..8b82f1f 100755
--- a/examples/fuse/camel/pom.xml
+++ b/examples/fuse/camel/pom.xml
@@ -32,15 +32,21 @@
     <description/>
 
     <properties>
-        <camel.version>2.15.1</camel.version>
+
         <keycloak.osgi.export>
         </keycloak.osgi.export>
         <keycloak.osgi.import>
-            org.eclipse.jetty.security;version="[8.1,10)",
-            org.eclipse.jetty.util.security;version="[8.1,10)",
-            org.apache.camel;version="[2.12,3)",
+            javax.servlet;version="[3,4)",
+            javax.servlet.http;version="[3,4)",
+            org.apache.camel.*,
+            org.apache.camel;version="[2.13,3)",
+            org.eclipse.jetty.security;version="[8,10)",
+            org.eclipse.jetty.server.nio;version="[8,10)",
+            org.eclipse.jetty.util.security;version="[8,10)",
             org.keycloak.*;version="${project.version}",
-            *;resolution:=optional
+            org.osgi.service.blueprint,
+            org.osgi.service.blueprint.container,
+            org.osgi.service.event,
         </keycloak.osgi.import>
         <keycloak.osgi.private>
             org.keycloak.example.*
@@ -63,7 +69,7 @@
             <version>${camel.version}</version>
         </dependency>
         <dependency><groupId>org.apache.camel</groupId>
-            <artifactId>camel-jetty</artifactId>
+            <artifactId>camel-jetty9</artifactId>
             <version>${camel.version}</version>
         </dependency>
     </dependencies>
diff --git a/examples/fuse/cxf-jaxrs/pom.xml b/examples/fuse/cxf-jaxrs/pom.xml
index afcbed8..15a03e1 100755
--- a/examples/fuse/cxf-jaxrs/pom.xml
+++ b/examples/fuse/cxf-jaxrs/pom.xml
@@ -31,7 +31,6 @@
     <name>CXF JAXRS Example - Secured in Karaf/Fuse</name>
 
     <properties>
-        <cxf.version>3.0.4</cxf.version>
         <keycloak.osgi.export>
         </keycloak.osgi.export>
         <keycloak.osgi.import>
@@ -40,9 +39,11 @@
             org.apache.cxf.transport.http;version="[2.7,3.2)",
             org.apache.cxf.*;version="[2.7,3.2)",
             com.fasterxml.jackson.jaxrs.json;version="${jackson.version}",
+            org.eclipse.jetty.security;version="[8,10)",
+            org.eclipse.jetty.util.security;version="[8,10)",
+            org.keycloak.*;version="${project.version}",
             org.keycloak.adapters.jetty;version="${project.version}",
-            org.keycloak.adapters;version="${project.version}",
-            *
+            *;resolution:=optional
         </keycloak.osgi.import>
         <keycloak.osgi.private>
             org.keycloak.example.rs.*
diff --git a/examples/fuse/cxf-jaxrs/src/main/resources/META-INF/cxf/bus-extensions.txt b/examples/fuse/cxf-jaxrs/src/main/resources/META-INF/cxf/bus-extensions.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/examples/fuse/cxf-jaxrs/src/main/resources/META-INF/cxf/bus-extensions.txt
diff --git a/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml b/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml
index 619b047..74b5fab 100644
--- a/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml
+++ b/examples/fuse/cxf-jaxrs/src/main/resources/OSGI-INF/blueprint/blueprint.xml
@@ -69,9 +69,9 @@
     <bean id="defaultCxfReregistration" class="org.keycloak.adapters.osgi.ServletReregistrationService" depends-on="cxfKeycloakPaxWebIntegration"
           init-method="start" destroy-method="stop">
         <property name="bundleContext" ref="blueprintBundleContext" />
-        <property name="servletReference">
-            <reference interface="javax.servlet.Servlet" filter="(alias=/cxf)" timeout="5000" />
+        <property name="managedServiceReference">
+            <reference interface="org.osgi.service.cm.ManagedService" filter="(service.pid=org.apache.cxf.osgi)" timeout="5000"  />
         </property>
     </bean>
 
-</blueprint>
\ No newline at end of file
+</blueprint>
diff --git a/examples/fuse/cxf-jaxws/pom.xml b/examples/fuse/cxf-jaxws/pom.xml
index 8afa018..2aad440 100755
--- a/examples/fuse/cxf-jaxws/pom.xml
+++ b/examples/fuse/cxf-jaxws/pom.xml
@@ -32,7 +32,6 @@
     <description/>
 
     <properties>
-        <cxf.version>3.0.4</cxf.version>
         <keycloak.osgi.export>
         </keycloak.osgi.export>
         <keycloak.osgi.import>
@@ -50,7 +49,9 @@
             org.apache.cxf.transport.http;version="[2.7,3.2)",
             org.apache.cxf.*;version="[2.7,3.2)",
             org.springframework.beans.factory.config,
-            *;resolution:=optional
+            org.eclipse.jetty.security;version="[8,10)",
+            org.eclipse.jetty.util.security;version="[8,10)",
+            org.keycloak.*;version="${project.version}"
         </keycloak.osgi.import>
         <keycloak.osgi.private>
             org.keycloak.example.ws.*
diff --git a/examples/fuse/features/src/main/resources/features.xml b/examples/fuse/features/src/main/resources/features.xml
index c838b02..3333a4a 100644
--- a/examples/fuse/features/src/main/resources/features.xml
+++ b/examples/fuse/features/src/main/resources/features.xml
@@ -18,13 +18,32 @@
 
 <features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0" name="keycloak-${project.version}">
 
-    <feature name="keycloak-fuse-example" version="${project.version}">
+      <feature name="keycloak-fuse-6.3-example" version="${project.version}">
+          <details>The keycloak fuse example</details>
+          <feature>war</feature>
+          <feature>camel</feature>
+          <feature>camel-jetty9</feature>
+          <feature>cxf</feature>
+          <feature>keycloak</feature>
+          <feature>keycloak-jetty9-adapter</feature>
+          <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
+          <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
+          <bundle>mvn:org.keycloak.example.demo/product-portal-fuse-example/${project.version}</bundle>
+          <bundle>mvn:org.keycloak.example.demo/customer-portal-fuse-example/${project.version}/war</bundle>
+          <bundle>mvn:org.keycloak.example.demo/camel-endpoint-example/${project.version}</bundle>
+          <bundle>mvn:org.keycloak.example.demo/cxf-jaxws-example/${project.version}</bundle>
+          <bundle>mvn:org.keycloak.example.demo/cxf-jaxrs-example/${project.version}</bundle>
+      </feature>
+
+      <!-- The difference are keycloak-jetty8-adapter and camel-jetty feature -->
+    <feature name="keycloak-fuse-6.2-example" version="${project.version}">
         <details>The keycloak fuse example</details>
         <feature>war</feature>
         <feature>camel</feature>
         <feature>camel-jetty</feature>
         <feature>cxf</feature>
         <feature>keycloak</feature>
+        <feature>keycloak-jetty8-adapter</feature>
         <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
         <bundle dependency="true">mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
         <bundle>mvn:org.keycloak.example.demo/product-portal-fuse-example/${project.version}</bundle>
@@ -34,4 +53,4 @@
         <bundle>mvn:org.keycloak.example.demo/cxf-jaxrs-example/${project.version}</bundle>
     </feature>
 
-</features>
\ No newline at end of file
+</features>
diff --git a/examples/fuse/pom.xml b/examples/fuse/pom.xml
index c0caca3..4d5ba2c 100755
--- a/examples/fuse/pom.xml
+++ b/examples/fuse/pom.xml
@@ -29,7 +29,10 @@
 
     <artifactId>keycloak-examples-fuse-parent</artifactId>
     <packaging>pom</packaging>
-
+    <properties>
+        <cxf.version>3.1.5</cxf.version>
+        <camel.version>2.16.1</camel.version>
+    </properties>
     <modules>
         <module>customer-app-fuse</module>
         <module>product-app-fuse</module>
@@ -39,4 +42,4 @@
         <module>features</module>
     </modules>
 
-</project>
\ No newline at end of file
+</project>

pom.xml 7(+6 -1)

diff --git a/pom.xml b/pom.xml
index e66df28..a25a62a 100755
--- a/pom.xml
+++ b/pom.xml
@@ -84,7 +84,7 @@
         <mongo.driver.version>3.2.0</mongo.driver.version>
         <mysql.version>5.1.29</mysql.version>
         <osgi.version>4.2.0</osgi.version>
-        <pax.web.version>3.1.2</pax.web.version>
+        <pax.web.version>4.2.4</pax.web.version>
         <postgresql.version>9.3-1100-jdbc41</postgresql.version>
         <mariadb.version>1.3.7</mariadb.version>
         <servlet.api.30.version>1.0.2.Final</servlet.api.30.version>
@@ -622,6 +622,11 @@
                 <version>${pax.web.version}</version>
             </dependency>
             <dependency>
+                <groupId>org.ops4j.pax.web</groupId>
+                <artifactId>pax-web-api</artifactId>
+                <version>${pax.web.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>org.jboss.aesh</groupId>
                 <artifactId>aesh</artifactId>
                 <version>${aesh.version}</version>