Repository: karaf
Updated Branches:
  refs/heads/karaf-2.x fda3393cf -> bf0311611


Fix packaging problems with gogo as Gogo is deployed in its own bundle, but 
also partially embedded in shell/core.
 * Embed gogo in shell/core
 * Export the secured CommandProcessor directly


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

Branch: refs/heads/karaf-2.x
Commit: 94ffa5e5bedff9bb779ddf48888aea351459e006
Parents: fda3393
Author: Guillaume Nodet <gno...@gmail.com>
Authored: Thu Sep 11 23:04:19 2014 +0200
Committer: Guillaume Nodet <gno...@gmail.com>
Committed: Thu Sep 11 23:19:09 2014 +0200

----------------------------------------------------------------------
 .../standard/src/main/resources/features.xml    |   1 -
 .../apache/karaf/itests/KarafTestSupport.java   |   4 +-
 shell/console/pom.xml                           |  10 +-
 .../karaf/shell/console/jline/Console.java      | 107 +---------
 .../shell/console/jline/ConsoleFactory.java     |   8 +-
 .../security/impl/SecCommandProcessorImpl.java  |  42 ++++
 .../impl/SecuredCommandProcessorImpl.java       |  99 +++++-----
 .../OSGI-INF/blueprint/karaf-console.xml        |  25 +--
 .../org/apache/felix/gogo/commands/Context.java |   2 +-
 .../karaf/shell/console/jline/ConsoleTest.java  | 195 -------------------
 .../impl/SecuredCommandProcessorImplTest.java   |   2 +-
 .../karaf/shell/ssh/ShellFactoryImpl.java       | 112 ++++++-----
 12 files changed, 185 insertions(+), 422 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/assemblies/features/standard/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/resources/features.xml 
b/assemblies/features/standard/src/main/resources/features.xml
index 587bd1d..99008d4 100644
--- a/assemblies/features/standard/src/main/resources/features.xml
+++ b/assemblies/features/standard/src/main/resources/features.xml
@@ -99,7 +99,6 @@
     <feature name="shell" description="Karaf Shell" 
version="${project.version}">
         <feature>aries-blueprint</feature>
         <feature>jaas</feature>
-        <bundle 
start-level="30">mvn:org.apache.felix/org.apache.felix.gogo.runtime/${felix.gogo.version}</bundle>
         <bundle 
start-level="30">mvn:org.apache.karaf.shell/org.apache.karaf.shell.console/${project.version}</bundle>
         <bundle 
start-level="30">mvn:org.apache.karaf.shell/org.apache.karaf.shell.commands/${project.version}</bundle>
         <bundle 
start-level="30">mvn:org.apache.karaf.shell/org.apache.karaf.shell.osgi/${project.version}</bundle>

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
----------------------------------------------------------------------
diff --git a/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java 
b/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
index cbba8b7..c9321a5 100644
--- a/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
+++ b/itests/src/test/java/org/apache/karaf/itests/KarafTestSupport.java
@@ -120,8 +120,6 @@ public class KarafTestSupport {
         String response;
         final ByteArrayOutputStream byteArrayOutputStream = new 
ByteArrayOutputStream();
         final PrintStream printStream = new PrintStream(byteArrayOutputStream);
-        final CommandProcessor commandProcessor = 
getOsgiService(CommandProcessor.class);
-        final CommandSession commandSession = 
commandProcessor.createSession(System.in, printStream, System.err);
         final Callable<String> commandCallable = new Callable<String>() {
             @Override
             public String call() throws Exception {
@@ -129,6 +127,8 @@ public class KarafTestSupport {
                     if (!silent) {
                         System.err.println(command);
                     }
+                    final CommandProcessor commandProcessor = 
getOsgiService(CommandProcessor.class);
+                    final CommandSession commandSession = 
commandProcessor.createSession(System.in, printStream, System.err);
                     commandSession.execute(command);
                 } catch (Exception e) {
                     throw new RuntimeException(e.getMessage(), e);

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/pom.xml
----------------------------------------------------------------------
diff --git a/shell/console/pom.xml b/shell/console/pom.xml
index a2ebe1f..4a8d98f 100644
--- a/shell/console/pom.xml
+++ b/shell/console/pom.xml
@@ -119,15 +119,16 @@
                 <configuration>
                     <instructions>
                         <Import-Package>
-                            !org.apache.felix.gogo.runtime.*,
                             org.osgi.service.event;resolution:=optional,
                             org.apache.karaf.branding;resolution:=optional,
                             org.apache.sshd.agent*;resolution:=optional,
                             *
                         </Import-Package>
                         <Export-Package>
-                            
org.apache.felix.gogo.runtime.*;version=${felix.gogo.version};-split-package:=merge-first,
-                            
org.apache.felix.gogo.commands.*;version=${felix.gogo.version};-split-package:=merge-first,
+                            
org.apache.felix.service.command;version=${felix.gogo.version};-split-package:=merge-first;-noimport:=true,
+                            
org.apache.felix.service.threadio;version=${felix.gogo.version};-split-package:=merge-first;-noimport:=true,
+                            
org.apache.felix.gogo.api;version=${felix.gogo.version};-split-package:=merge-first;-noimport:=true,
+                            
org.apache.felix.gogo.commands.*;version=${felix.gogo.version};-split-package:=merge-first;-noimport:=true,
                             
org.apache.karaf.shell.console*;version=${project.version},
                             
org.fusesource.jansi;version=${jansi.version};-split-package:=merge-first,
                             jline*;version=${jline.version},
@@ -135,6 +136,7 @@
                             
org.fusesource.hawtjni*;version=1.0;-split-package:=merge-first
                         </Export-Package>
                         <Private-Package>
+                            org.apache.felix.gogo.runtime.*,
                             org.apache.karaf.shell.security.impl,
                             
org.fusesource.jansi.internal;-split-package:=merge-first,
                             !org.apache.karaf.util.properties,
@@ -155,13 +157,11 @@
                         <Main-Class>
                             org.apache.karaf.shell.console.Main
                         </Main-Class>
-                        <!--
                         <Export-Service>
                             org.apache.felix.service.threadio.ThreadIO,
                             org.apache.felix.service.command.CommandProcessor,
                             org.apache.felix.service.command.Converter
                         </Export-Service>
-                        -->
                     </instructions>
                     <unpackBundle>true</unpackBundle>
                 </configuration>

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java 
b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java
index ac48e0c..4ab38c6 100644
--- 
a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java
+++ 
b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/Console.java
@@ -102,7 +102,8 @@ public class Console implements Runnable
         this.queue = new ArrayBlockingQueue<Integer>(1024);
         this.terminal = term == null ? new UnsupportedTerminal() : term;
         this.consoleInput = new ConsoleInputStream();
-        this.session = new DelegateSession();
+
+        this.session = processor.createSession(consoleInput, out, err);
         this.session.put("SCOPE", "shell:osgi:*");
         this.closeCallback = closeCallback;
         this.bundleContext = bc;
@@ -178,7 +179,6 @@ public class Console implements Runnable
     {
         try {
             threadIO.setStreams(consoleInput, out, err);
-            SecuredCommandProcessorImpl secCP = 
createSecuredCommandProcessor();
             thread = Thread.currentThread();
             CommandSessionHolder.setSession(session);
             running = true;
@@ -212,11 +212,6 @@ public class Console implements Runnable
                     logException(t);
                 }
             }
-            try {
-                secCP.close();
-            } catch (Throwable t) {
-                // Ignore
-            }
             close(true);
         } finally {
             try {
@@ -227,22 +222,6 @@ public class Console implements Runnable
         }
     }
     
-    SecuredCommandProcessorImpl createSecuredCommandProcessor() {
-        if (!(session instanceof DelegateSession)) {
-            throw new IllegalStateException("Should be an Delegate Session 
here, about to set the delegate");
-        }
-        DelegateSession is = (DelegateSession)session;
-
-        // make it active
-        SecuredCommandProcessorImpl secCP = new 
SecuredCommandProcessorImpl(bundleContext);
-        CommandSession s = secCP.createSession(consoleInput, out, err);
-
-        // before the session is activated attributes may have been set on it. 
Pass these on to the real
-        // session now
-        is.setDelegate(s);
-        return secCP;
-    }
-
     private void logException(Throwable t) {
         try {
             boolean isCommandNotFound = 
"org.apache.felix.gogo.runtime.CommandNotFoundException".equals(t.getClass().getName());
@@ -443,88 +422,6 @@ public class Console implements Runnable
         thread.interrupt();
     }
 
-    static class DelegateSession implements CommandSession {
-        final Map<String, Object> attrs = new HashMap<String, Object>();
-        volatile CommandSession delegate;
-
-        @Override
-        public Object execute(CharSequence commandline) throws Exception {
-            if (delegate != null)
-                return delegate.execute(commandline);
-
-            throw new UnsupportedOperationException();
-        }
-
-        void setDelegate(CommandSession s) {
-            synchronized (this) {
-                for (Map.Entry<String, Object> entry : attrs.entrySet()) {
-                    s.put(entry.getKey(), entry.getValue());
-                }
-            }
-            delegate = s;
-        }
-
-        @Override
-        public void close() {
-            if (delegate != null)
-                delegate.close();
-        }
-
-        @Override
-        public InputStream getKeyboard() {
-            if (delegate != null)
-                return delegate.getKeyboard();
-
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public PrintStream getConsole() {
-            if (delegate != null)
-                return delegate.getConsole();
-
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Object get(String name) {
-            if (delegate != null)
-                return delegate.get(name);
-
-            return attrs.get(name);
-        }
-
-        // you can put attributes on this session before it's delegate is 
set...
-        @Override
-        public void put(String name, Object value) {
-            if (delegate != null) {
-                delegate.put(name, value);
-                return;
-            }
-
-            // there is no delegate yet, so we'll keep the attributes locally
-            synchronized (this) {
-                attrs.put(name, value);
-            }
-        }
-
-        @Override
-        public CharSequence format(Object target, int level) {
-            if (delegate != null)
-                return delegate.format(target, level);
-
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public Object convert(Class<?> type, Object instance) {
-            if (delegate != null)
-                return delegate.convert(type, instance);
-
-            throw new UnsupportedOperationException();
-        }
-    }
-
     private class ConsoleInputStream extends InputStream
     {
         private int read(boolean wait) throws IOException

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
 
b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
index 68cf181..fcae59f 100644
--- 
a/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
+++ 
b/shell/console/src/main/java/org/apache/karaf/shell/console/jline/ConsoleFactory.java
@@ -73,6 +73,10 @@ public class ConsoleFactory {
         this.bundleContext = bundleContext;
     }
 
+    public void setCommandProcessor(CommandProcessor commandProcessor) {
+        this.commandProcessor = commandProcessor;
+    }
+
     public void setThreadIO(ThreadIO threadIO) {
         this.threadIO = threadIO;
     }
@@ -95,7 +99,7 @@ public class ConsoleFactory {
         this.start = start;
     }
 
-    protected void start() throws Exception {
+    public void start() throws Exception {
         if (start) {
             Subject subject = new Subject();
             String userName = System.getProperty("karaf.local.user");
@@ -211,7 +215,7 @@ public class ConsoleFactory {
         return parts[0];
     }
 
-    protected void stop() throws Exception {
+    public void stop() throws Exception {
         if (registration != null) {
             registration.unregister();
         }

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecCommandProcessorImpl.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecCommandProcessorImpl.java
 
b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecCommandProcessorImpl.java
new file mode 100644
index 0000000..29b02a2
--- /dev/null
+++ 
b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecCommandProcessorImpl.java
@@ -0,0 +1,42 @@
+/*
+ * 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.shell.security.impl;
+
+import java.io.InputStream;
+import java.io.PrintStream;
+
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.threadio.ThreadIO;
+import org.osgi.framework.BundleContext;
+
+public class SecCommandProcessorImpl implements CommandProcessor {
+
+    private final BundleContext bundleContext;
+    private final ThreadIO threadIO;
+
+    public SecCommandProcessorImpl(BundleContext bundleContext, ThreadIO 
threadIO) {
+        this.bundleContext = bundleContext;
+        this.threadIO = threadIO;
+    }
+
+    public CommandSession createSession(InputStream in, PrintStream out, 
PrintStream err) {
+        SecuredCommandProcessorImpl scp = new 
SecuredCommandProcessorImpl(bundleContext, threadIO);
+        return scp.createSession(in, out, err);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
 
b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
index 84224c4..3a83958 100644
--- 
a/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
+++ 
b/shell/console/src/main/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImpl.java
@@ -22,7 +22,6 @@ import org.apache.felix.gogo.runtime.CommandProxy;
 import org.apache.felix.gogo.runtime.activator.Activator;
 import org.apache.felix.service.command.CommandProcessor;
 import org.apache.felix.service.command.Converter;
-import org.apache.felix.service.command.Function;
 import org.apache.felix.service.threadio.ThreadIO;
 import org.apache.karaf.jaas.boot.principal.RolePrincipal;
 import org.osgi.framework.BundleContext;
@@ -35,48 +34,47 @@ import javax.security.auth.Subject;
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 
 public class SecuredCommandProcessorImpl extends CommandProcessorImpl {
 
     private final BundleContext bundleContext;
-    private final ServiceReference<ThreadIO> threadIOServiceReference;
     private final ServiceTracker<Object, Object> commandTracker;
     private final ServiceTracker<Converter, Converter> converterTracker;
     private final ServiceTracker<CommandSessionListener, 
CommandSessionListener> listenerTracker;
 
-    public SecuredCommandProcessorImpl(BundleContext bc) {
-        this(bc, bc.getServiceReference(ThreadIO.class));
-    }
-
-    private SecuredCommandProcessorImpl(BundleContext bc, 
ServiceReference<ThreadIO> sr) {
-        super(bc.getService(sr));
+    public SecuredCommandProcessorImpl(BundleContext bc, ThreadIO io) {
+        super(io);
         bundleContext = bc;
-        threadIOServiceReference = sr;
+
+        String roleClause = "";
 
         AccessControlContext acc = AccessController.getContext();
         Subject sub = Subject.getSubject(acc);
-        if (sub == null)
-            throw new SecurityException("No current Subject in the Access 
Control Context");
-
-        Set<RolePrincipal> rolePrincipals = 
sub.getPrincipals(RolePrincipal.class);
-        if (rolePrincipals.size() == 0)
-            throw new SecurityException("Current user has no associated 
roles.");
-
-        // TODO cater for custom roles
-        StringBuilder sb = new StringBuilder();
-        sb.append("(|");
-        for (RolePrincipal rp : rolePrincipals) {
-            sb.append('(');
-            sb.append("org.apache.karaf.service.guard.roles");
-            sb.append('=');
-            sb.append(rp.getName());
+        if (sub != null) {
+            Set<RolePrincipal> rolePrincipals = 
sub.getPrincipals(RolePrincipal.class);
+            if (rolePrincipals.size() == 0)
+                throw new SecurityException("Current user has no associated 
roles.");
+
+            // TODO cater for custom roles
+            StringBuilder sb = new StringBuilder();
+            sb.append("(|");
+            for (RolePrincipal rp : rolePrincipals) {
+                sb.append('(');
+                sb.append("org.apache.karaf.service.guard.roles");
+                sb.append('=');
+                sb.append(rp.getName());
+                sb.append(')');
+            }
+            sb.append("(!(org.apache.karaf.service.guard.roles=*))"); // Or no 
roles specified at all
             sb.append(')');
+            roleClause = sb.toString();
         }
-        sb.append("(!(org.apache.karaf.service.guard.roles=*))"); // Or no 
roles specified at all
-        sb.append(')');
-        String roleClause = sb.toString();
 
         addConstant(Activator.CONTEXT, bc);
         addCommand("osgi", this, "addCommand");
@@ -101,7 +99,6 @@ public class SecuredCommandProcessorImpl extends 
CommandProcessorImpl {
         commandTracker.close();
         converterTracker.close();
         listenerTracker.close();
-        bundleContext.ungetService(threadIOServiceReference);
     }
 
     private ServiceTracker<Object, Object> trackCommands(final BundleContext 
context, String roleClause) throws InvalidSyntaxException {
@@ -109,45 +106,57 @@ public class SecuredCommandProcessorImpl extends 
CommandProcessorImpl {
                 CommandProcessor.COMMAND_SCOPE, 
CommandProcessor.COMMAND_FUNCTION, roleClause));
 
         return new ServiceTracker<Object, Object>(context, filter, null) {
+            private final ConcurrentMap<ServiceReference, Map<String, 
CommandProxy>> proxies
+                    = new ConcurrentHashMap<ServiceReference, Map<String, 
CommandProxy>>();
+
             @Override
-            public Object addingService(ServiceReference<Object> reference) {
+            public Object addingService(ServiceReference reference)
+            {
                 Object scope = 
reference.getProperty(CommandProcessor.COMMAND_SCOPE);
                 Object function = 
reference.getProperty(CommandProcessor.COMMAND_FUNCTION);
                 List<Object> commands = new ArrayList<Object>();
 
-                if (scope != null && function != null) {
-                    if (function.getClass().isArray()) {
-                        for (Object f : ((Object[]) function)) {
-                            Function target = new CommandProxy(context, 
reference,
-                                    f.toString());
+                if (scope != null && function != null)
+                {
+                    Map<String, CommandProxy> proxyMap = new HashMap<String, 
CommandProxy>();
+                    if (function.getClass().isArray())
+                    {
+                        for (Object f : ((Object[]) function))
+                        {
+                            CommandProxy target = new CommandProxy(context, 
reference, f.toString());
+                            proxyMap.put(f.toString(), target);
                             addCommand(scope.toString(), target, f.toString());
                             commands.add(target);
                         }
-                    } else {
-                        Function target = new CommandProxy(context, reference,
-                                function.toString());
+                    }
+                    else
+                    {
+                        CommandProxy target = new CommandProxy(context, 
reference, function.toString());
+                        proxyMap.put(function.toString(), target);
                         addCommand(scope.toString(), target, 
function.toString());
                         commands.add(target);
                     }
+                    proxies.put(reference, proxyMap);
                     return commands;
                 }
                 return null;
             }
 
             @Override
-            public void removedService(ServiceReference<Object> reference, 
Object service) {
+            public void removedService(ServiceReference reference, Object 
service)
+            {
                 Object scope = 
reference.getProperty(CommandProcessor.COMMAND_SCOPE);
                 Object function = 
reference.getProperty(CommandProcessor.COMMAND_FUNCTION);
 
-                if (scope != null && function != null) {
-                    if (!function.getClass().isArray()) {
-                        removeCommand(scope.toString(), function.toString());
-                    } else {
-                        for (Object func : (Object[]) function) {
-                            removeCommand(scope.toString(), func.toString());
-                        }
+                if (scope != null && function != null)
+                {
+                    Map<String, CommandProxy> proxyMap = 
proxies.remove(reference);
+                    for (Map.Entry<String, CommandProxy> entry : 
proxyMap.entrySet())
+                    {
+                        removeCommand(scope.toString(), entry.getKey());
                     }
                 }
+
                 super.removedService(reference, service);
             }
         };

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
----------------------------------------------------------------------
diff --git 
a/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml 
b/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
index 65c1991..cf544bc 100644
--- a/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
+++ b/shell/console/src/main/resources/OSGI-INF/blueprint/karaf-console.xml
@@ -26,18 +26,23 @@
         </ext:default-properties>
     </ext:property-placeholder>
 
-    <reference id="commandProcessor" 
interface="org.apache.felix.service.command.CommandProcessor">
-        <reference-listener ref="consoleFactory"
-                            bind-method="registerCommandProcessor"
-                            unbind-method="unregisterCommandProcessor"/>
-    </reference>
-    <reference id="threadIO" 
interface="org.apache.felix.service.threadio.ThreadIO" />
-
-    <bean id="consoleFactory" 
class="org.apache.karaf.shell.console.jline.ConsoleFactory">
+    <bean id="threadIO" 
class="org.apache.felix.gogo.runtime.threadio.ThreadIOImpl"
+          init-method="start" destroy-method="stop"/>
+    <service ref="threadIO" auto-export="interfaces"/>
+
+    <bean id="commandProcessor" 
class="org.apache.karaf.shell.security.impl.SecCommandProcessorImpl">
+        <argument ref="blueprintBundleContext"/>
+        <argument ref="threadIO"/>
+    </bean>
+    <service ref="commandProcessor" auto-export="interfaces"/>
+
+    <bean id="consoleFactory" 
class="org.apache.karaf.shell.console.jline.ConsoleFactory"
+            init-method="start" destroy-method="stop">
         <property name="start" value="$[karaf.startLocalConsole]"/>
         <property name="bundleContext" ref="blueprintBundleContext"/>
         <property name="terminalFactory" ref="terminalFactory"/>
         <property name="threadIO" ref="threadIO"/>
+        <property name="commandProcessor" ref="commandProcessor"/>
     </bean>
 
     <bean id="converters" class="org.apache.karaf.shell.console.Converters">
@@ -83,9 +88,7 @@
     </service>
     <service auto-export="interfaces" ranking="-10">
         <bean 
class="org.apache.karaf.shell.console.help.SingleCommandHelpProvider">
-            <property name="io">
-                <reference 
interface="org.apache.felix.service.threadio.ThreadIO"/>
-            </property>
+            <property name="io" ref="threadIO"/>
         </bean>
     </service>
     <service auto-export="interfaces" ref="subShellHelpProvider" 
ranking="-10"/>

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/test/java/org/apache/felix/gogo/commands/Context.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/test/java/org/apache/felix/gogo/commands/Context.java 
b/shell/console/src/test/java/org/apache/felix/gogo/commands/Context.java
index 80f5309..4ef17e0 100644
--- a/shell/console/src/test/java/org/apache/felix/gogo/commands/Context.java
+++ b/shell/console/src/test/java/org/apache/felix/gogo/commands/Context.java
@@ -51,7 +51,7 @@ public class Context extends CommandProcessorImpl
 
     public void addCommand(String name, Object target)
     {
-        put("test:" + name, target);
+        addCommand("test", target, name);
     }
 
     public void set(String name, Object value)

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/test/java/org/apache/karaf/shell/console/jline/ConsoleTest.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/test/java/org/apache/karaf/shell/console/jline/ConsoleTest.java
 
b/shell/console/src/test/java/org/apache/karaf/shell/console/jline/ConsoleTest.java
deleted file mode 100644
index 34546c3..0000000
--- 
a/shell/console/src/test/java/org/apache/karaf/shell/console/jline/ConsoleTest.java
+++ /dev/null
@@ -1,195 +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.shell.console.jline;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-
-import org.apache.felix.gogo.api.CommandSessionListener;
-import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
-import org.apache.felix.service.command.CommandProcessor;
-import org.apache.felix.service.command.CommandSession;
-import org.apache.felix.service.command.Converter;
-import org.apache.karaf.jaas.boot.principal.RolePrincipal;
-import org.apache.karaf.shell.console.jline.Console.DelegateSession;
-import org.apache.karaf.shell.security.impl.SecuredCommandProcessorImpl;
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-
-public class ConsoleTest {
-    @Test
-    public void testConsoleImpl() throws Exception {
-        ServiceReference<?> cmRef = 
EasyMock.createMock(ServiceReference.class);
-        
EasyMock.expect(cmRef.getProperty(CommandProcessor.COMMAND_SCOPE)).andReturn("myscope").anyTimes();
-        
EasyMock.expect(cmRef.getProperty(CommandProcessor.COMMAND_FUNCTION)).andReturn("myfunction").anyTimes();
-        EasyMock.replay(cmRef);
-        ServiceReference<?>[] cmRefs = new ServiceReference[] {cmRef};
-
-        BundleContext bc = EasyMock.createMock(BundleContext.class);
-        EasyMock.expect(bc.getServiceReference((Class<?>) 
EasyMock.anyObject())).andReturn(null).anyTimes();
-        EasyMock.expect(bc.getService((ServiceReference<?>) 
EasyMock.anyObject())).andReturn(null).anyTimes();
-        bc.addServiceListener(EasyMock.isA(ServiceListener.class), 
EasyMock.isA(String.class));
-        EasyMock.expectLastCall().anyTimes();
-        EasyMock.expect(bc.getServiceReferences((String) null,
-                "(&(osgi.command.scope=*)(osgi.command.function=*)" +
-                        
"(|(org.apache.karaf.service.guard.roles=myrole)(!(org.apache.karaf.service.guard.roles=*))))")).andReturn(cmRefs).anyTimes();
-        EasyMock.expect(bc.getServiceReferences(Converter.class.getName(), 
null)).andReturn(null).anyTimes();
-        
EasyMock.expect(bc.getServiceReferences(CommandSessionListener.class.getName(), 
null)).andReturn(null).anyTimes();
-        
EasyMock.expect(bc.createFilter(EasyMock.isA(String.class))).andAnswer(new 
IAnswer<Filter>() {
-            @Override
-            public Filter answer() throws Throwable {
-                return FrameworkUtil.createFilter((String) 
EasyMock.getCurrentArguments()[0]);
-            }
-        }).anyTimes();
-        EasyMock.replay(bc);
-
-        final Console console = new Console(null, new ThreadIOImpl(), 
System.in, System.out, System.err, null, "UTF-8", null, bc);
-        assertTrue(console.session instanceof DelegateSession);
-
-        console.session.put("foo", "bar");
-
-        final DelegateSession ds = (DelegateSession) console.session;
-        assertNull("Precondition", ds.delegate);
-
-        Subject subject = new Subject();
-        subject.getPrincipals().add(new RolePrincipal("myrole"));
-
-        Subject.doAs(subject, new PrivilegedAction<Object>() {
-            @Override
-            public Object run() {
-                SecuredCommandProcessorImpl secCP = 
console.createSecuredCommandProcessor();
-                assertNotNull(ds.delegate);
-                assertEquals("Attributes set before the delegate was set 
should have been transferred",
-                        "bar", ds.get("foo"));
-                assertEquals("Attributes set before the delegate was set 
should have been transferred",
-                        "bar", ds.delegate.get("foo"));
-                assertSame(System.out, ds.delegate.getConsole());
-                assertSame(System.out, ds.getConsole());
-
-                assertTrue(secCP.getCommands().contains("myscope:myfunction"));
-
-                return null;
-            }
-        });
-    }
-
-    @Test
-    public void testDelegateSession() throws Exception {
-        DelegateSession ds = new DelegateSession();
-
-        ds.put("a", "b");
-        assertEquals("b", ds.get("a"));
-
-        TestSession ts = new TestSession();
-
-        assertNull("Precondition", ts.lastInvoked);
-
-        ds.setDelegate(ts);
-        assertEquals("put(a,b)", ts.lastInvoked);
-
-        ds.put("c", "d");
-        assertEquals("put(c,d)", ts.lastInvoked);
-
-        ds.execute("hello 1234");
-        assertEquals("execute(hello 1234)", ts.lastInvoked);
-
-        ds.close();
-        assertEquals("close", ts.lastInvoked);
-
-        ds.getKeyboard();
-        assertEquals("getKeyboard", ts.lastInvoked);
-
-        ds.getConsole();
-        assertEquals("getConsole", ts.lastInvoked);
-
-        ds.get("xyz");
-        assertEquals("get(xyz)", ts.lastInvoked);
-
-        ds.format("foo", 12);
-        assertEquals("format(foo,12)", ts.lastInvoked);
-
-        ds.convert(TestSession.class, "a string");
-        assertEquals("convert(TestSession,a string)", ts.lastInvoked);
-    }
-
-    static class TestSession implements CommandSession {
-        String lastInvoked;
-
-        @Override
-        public Object execute(CharSequence commandline) throws Exception {
-            lastInvoked = "execute(" + commandline + ")";
-            return null;
-        }
-
-        @Override
-        public void close() {
-            lastInvoked = "close";
-        }
-
-        @Override
-        public InputStream getKeyboard() {
-            lastInvoked = "getKeyboard";
-            return null;
-        }
-
-        @Override
-        public PrintStream getConsole() {
-            lastInvoked = "getConsole";
-            return null;
-        }
-
-        @Override
-        public Object get(String name) {
-            lastInvoked = "get(" + name + ")";
-            return null;
-        }
-
-        @Override
-        public void put(String name, Object value) {
-            lastInvoked = "put(" + name + "," + value + ")";
-        }
-
-        @Override
-        public CharSequence format(Object target, int level) {
-            lastInvoked = "format(" + target + "," + level + ")";
-            return null;
-        }
-
-        @Override
-        public Object convert(Class<?> type, Object instance) {
-            lastInvoked = "convert(" + type.getSimpleName() + "," + instance + 
")";
-            return null;
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
----------------------------------------------------------------------
diff --git 
a/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
 
b/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
index 351a89f..0c66eb6 100644
--- 
a/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
+++ 
b/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
@@ -132,7 +132,7 @@ public class SecuredCommandProcessorImplTest {
     // Subclass to provide access to some protected members
     static class MySecuredCommandProcessorImpl extends 
SecuredCommandProcessorImpl {
         public MySecuredCommandProcessorImpl(BundleContext bc) {
-            super(bc);
+            super(bc, null);
         }
 
         Map<String, Object> getConstants() {

http://git-wip-us.apache.org/repos/asf/karaf/blob/94ffa5e5/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
----------------------------------------------------------------------
diff --git 
a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java 
b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
index 37fb37c..8668b3c 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/ShellFactoryImpl.java
@@ -44,6 +44,8 @@ import org.apache.sshd.server.SessionAware;
 import org.apache.sshd.server.session.ServerSession;
 import org.osgi.framework.BundleContext;
 import org.osgi.service.blueprint.container.ReifiedType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * SSHD {@link org.apache.sshd.server.Command} factory which provides access 
to Shell.
@@ -56,6 +58,8 @@ public class ShellFactoryImpl implements Factory<Command> {
             JaasHelper.DelegatingProtectionDomain.class,
     };
 
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(ShellFactoryImpl.class);
+
     private CommandProcessor commandProcessor;
     private ThreadIO threadIO;
     private BundleContext bundleContext;
@@ -111,63 +115,63 @@ public class ShellFactoryImpl implements Factory<Command> 
{
         }
 
         public void start(final Environment env) throws IOException {
-            try {
-                final Terminal terminal = new SshTerminal(env);
-                String encoding = env.getEnv().get("LC_CTYPE");
-                if (encoding != null && encoding.indexOf('.') > 0) {
-                    encoding = encoding.substring(encoding.indexOf('.') + 1);
-                }
-                Console console = new Console(commandProcessor,
-                                              threadIO,
-                                              in,
-                                              new PrintStream(new 
LfToCrLfFilterOutputStream(out), true),
-                                              new PrintStream(new 
LfToCrLfFilterOutputStream(err), true),
-                                              terminal,
-                                              encoding,
-                                              new Runnable() {
-                                                  public void run() {
-                                                      destroy();
-                                                  }
-                                              },
-                                              bundleContext);
-                final CommandSession session = console.getSession();
-                session.put("APPLICATION", System.getProperty("karaf.name", 
"root"));
-                for (Map.Entry<String,String> e : env.getEnv().entrySet()) {
-                    session.put(e.getKey(), e.getValue());
-                }
-                session.put("#LINES", new Function() {
-                    public Object execute(CommandSession session, List<Object> 
arguments) throws Exception {
-                        return Integer.toString(terminal.getHeight());
-                    }
-                });
-                session.put("#COLUMNS", new Function() {
-                    public Object execute(CommandSession session, List<Object> 
arguments) throws Exception {
-                        return Integer.toString(terminal.getWidth());
+            new Thread() {
+                @Override
+                public void run() {
+                    Subject subject = ShellImpl.this.session != null ? 
ShellImpl.this.session.getAttribute(KarafJaasAuthenticator.SUBJECT_ATTRIBUTE_KEY)
 : null;
+                    if (subject != null) {
+                        JaasHelper.doAs(subject, new 
PrivilegedAction<Object>() {
+                            public Object run() {
+                                runConsole();
+                                return null;
+                            }
+                        });
+                    } else {
+                        runConsole();
                     }
-                });
-                session.put(".jline.terminal", terminal);
-                new Thread(console) {
-                    @Override
-                    public void run() {
-                        Subject subject = ShellImpl.this.session != null ? 
ShellImpl.this.session.getAttribute(KarafJaasAuthenticator.SUBJECT_ATTRIBUTE_KEY)
 : null;
-                        if (subject != null) {
-                            JaasHelper.doAs(subject, new 
PrivilegedAction<Object>() {
-                                public Object run() {
-                                    doRun();
-                                    return null;
-                                }
-                            });
-                        } else {
-                            doRun();
+                }
+                protected void runConsole() {
+                    try {
+                        final Terminal terminal = new SshTerminal(env);
+                        String encoding = env.getEnv().get("LC_CTYPE");
+                        if (encoding != null && encoding.indexOf('.') > 0) {
+                            encoding = 
encoding.substring(encoding.indexOf('.') + 1);
                         }
+                        final Console console = new Console(commandProcessor,
+                                threadIO,
+                                in,
+                                new PrintStream(new 
LfToCrLfFilterOutputStream(out), true),
+                                new PrintStream(new 
LfToCrLfFilterOutputStream(err), true),
+                                terminal,
+                                encoding,
+                                new Runnable() {
+                                    public void run() {
+                                        ShellImpl.this.destroy();
+                                    }
+                                },
+                                bundleContext);
+                        final CommandSession session = console.getSession();
+                        session.put("APPLICATION", 
System.getProperty("karaf.name", "root"));
+                        for (Map.Entry<String,String> e : 
env.getEnv().entrySet()) {
+                            session.put(e.getKey(), e.getValue());
+                        }
+                        session.put("#LINES", new Function() {
+                            public Object execute(CommandSession session, 
List<Object> arguments) throws Exception {
+                                return Integer.toString(terminal.getHeight());
+                            }
+                        });
+                        session.put("#COLUMNS", new Function() {
+                            public Object execute(CommandSession session, 
List<Object> arguments) throws Exception {
+                                return Integer.toString(terminal.getWidth());
+                            }
+                        });
+                        session.put(".jline.terminal", terminal);
+                        console.run();
+                    } catch (Exception e) {
+                        LOGGER.warn("Unable to start shell", e);
                     }
-                    protected void doRun() {
-                        super.run();
-                    }
-                }.start();
-            } catch (Exception e) {
-                throw (IOException) new IOException("Unable to start 
shell").initCause(e);
-            }
+                }
+            }.start();
         }
 
         public void destroy() {

Reply via email to