RFC 147 Overview :: Apache Felix Home Subprojects Dependency Manager Event Admin File Install Framework Gogo Shell Health Checks Inventory Log Logback Maven bundle plugin Maven SCR plugin Metatype Service Preferences Service Remote Shell Script console plugin Lightweight shell Shell TUI Web Console Downloads Documentation Documentation Downloads Getting Started News Community Apache Felix Project Info Contributing Projects Using Felix Development Coding Standards DEPENDENCIES file template Provisional OSGi API Policy Release Management Site How To Using the OSGi Compliance Tests FAQS Apache Felix Bundle Plugin Frequently Asked Questions Apache Felix SCR Plugin Frequently Asked Questions Subprojects Apache Felix Dependency Manager Guides Apache Felix Dependency Manager - Migrating from earlier versions Dependency Manager - Annotations Dependency Manager - Background Dependency Manager - Bundles and Dependencies Dependency Manager - Design Patterns Dependency Manager - Development Dependency Manager - History Dependency Manager - JavaDocs Dependency Manager - Migrating from other solutions. Dependency Manager - Performance Tuning Dependency Manager - Resource adapters Dependency Manager - What’s new in version 4? Dependency Manager Lambda What’s New in R15 Reference Dependency Manager - Adapter Dependency Manager - Aspect Dependency Manager - Bundle Adapter Dependency Manager - Bundle Dependency Dependency Manager - Components Dependency Manager - Configuration Dependency Dependency Manager - Dependencies Dependency Manager - External Links Dependency Manager - Factory Configuration Adapter Service Dependency Manager - Resource Adapter Dependency Manager - Resource Dependency Dependency Manager - Service Dependency Dependency Manager - Service Scopes Dependency Manager - Singleton Component Dependency Manager - Thread Model Dependency Manager Annotations Tutorials Dependency Manager - Annotations Dependency Manager - Getting Started Dependency Manager - Leveraging the shell Dependency Manager sample projects Apache Felix Event Admin Apache Felix File Install Apache Felix Framework Apache Felix Framework Bundle Cache Apache Felix Framework Configuration Properties Apache Felix Framework Frequently Asked Questions Apache Felix Framework Launching and Embedding Apache Felix Framework Usage Documentation Apache Felix Framework Security Apache Felix Gogo RFC 147 Overview Apache Felix Health Checks Apache Felix Inventory Printer Apache Felix Log Apache Felix Logback Apache Felix Maven Bundle Plugin (BND) Apache Felix Metatype Service Apache Felix OSGi Bundle Repository (OBR) Apache Felix Preferences Service Apache Felix Remote Shell Apache Felix Shell Apache Felix Shell TUI Apache Felix Web Console Extending the Apache Felix Web Console Web Console RESTful API Web Console Security Provider Extensions Branding the Web Console Providing Resources Providing Web Console Plugins Web Console Logging Web Console Output Templating Tutorials Apache Felix Application Demonstration Apache Felix OSGi Tutorial OSGi Frequently Asked Questions OSGI Tutorial Apache Felix Tutorial Example 1 - Service Event Listener Bundle Apache Felix Tutorial Example 2 Apache Felix Tutorial Example 2b Apache Felix Tutorial Example 3 Apache Felix Tutorial Example 4 Apache Felix Tutorial Example 5 Example 6 - Spell Checker Service Bundle Example 7 - Spell Checker Client Bundle Example 8 - Spell Checker Service using Service Binder Example 9 - Spell Checker Service using Declarative Services Apache License 2.0 Site map Documentation master Documentation master Documentation Subprojects Apache Felix Gogo RFC 147 Overview Edit this Page RFC 147 Overview The RFC-147 draft is not yet publicly available. It used to be called RFC-132, which can be found in an early specification draft This is an overview of its main features: Standard way to implement and run commands for any OSGi 4.2 framework Commands are registered via service attributes, you don’t have to register a specific service. This allows commands to be registered by existing services, just by adding the new attributes: Dictionary<String, Object> dict = new Hashtable<String, Object>(); dict.put(CommandProcessor.COMMAND_SCOPE, "shell"); dict.put(CommandProcessor.COMMAND_FUNCTION, new String[] {"sleep", "grep"}); context.registerService(name, service, dict); Scope is used to provide a namespace for commands. The commands above can be invoked as shell:sleep and shell:grep. If the scope is omitted (e.g. sleep and grep) then the first matching command is invoked. Commands can have any signature Arguments are coerced to call the best matching method using reflection. A CommandSession argument is inserted if required: public void sleep(long millis) throws InterruptedException{ Thread.sleep(millis); } public void sleep(String[] args) throws Exception; public boolean grep(CommandSession session, String[] args) throws Exception; The CommandSession interface provides methods for executing commands and getting and setting session variables: public interface org.apache.felix.service.command.CommandSession { Object execute(CharSequence commandline) throws Exception; Object get(String name); void put(String name, Object value); ... } Easy to use interactively - no unnecessary syntax basic commands g! echo hello world hello world session variables g! msg = "hello world" g! echo $msg hello world execution quotes () - similar to bash backquotes g! (bundle 1) location file:/Users/derek/Downloads/felix-framework-3.0.0/bundle/org.apache.felix.bundlerepository-1.6.2.jar Lists, maps, pipes and closures lists - [] g! list = [1 2 a b] 1 2 a b maps - [] g! map = [Jan=1 Feb=2 Mar=3] Jan 1 Feb 2 Mar 3 pipes - | g! bundles | grep gogo 2|Active | 1|org.apache.felix.gogo.command (0.6.0) 3|Active | 1|org.apache.felix.gogo.runtime (0.6.0) 4|Active | 1|org.apache.felix.gogo.shell (0.6.0) closures - {} g! echo2 = { echo xxx $args yyy } g! echo2 hello world xxx hello world yyy Leverages existing Java capabilities, via reflection exception handling - console shows summary, but full context available g! start xxx E: Cannot coerce start[xxx] to any of [(Bundle)] g! $exception printstacktrace java.lang.IllegalArgumentException: Cannot coerce start[xxx] to any of [(Bundle)] at org.apache.felix.gogo.runtime.shell.Reflective.method(Reflective.java:162) at org.apache.felix.gogo.runtime.shell.Command.execute(Command.java:40) at org.apache.felix.gogo.runtime.shell.Closure.execute(Closure.java:211) at org.apache.felix.gogo.runtime.shell.Closure.executeStatement(Closure.java:146) at org.apache.felix.gogo.runtime.shell.Pipe.run(Pipe.java:91) ... add all public methods on java.lang.System as commands: g! addcommand system (loadClass java.lang.System) g! system:getproperties sun.io.unicode.encodingUnicodeLittle java.version 1.5.0_19 java.class.path bin/felix.jar java.awt.graphicsenvapple.awt.CGraphicsEnvironment user.language en sun.os.patch.level unknown os.version 10.6.2 [snip] Easy to implement and test commands without needing OSGi Command implementations don’t need to reference any OSGi interfaces. They can use System.in, System.out and System.err, just as you would in a trivial Java application. The ThreadIO service transparently manages the singleton System.out etc, so that each thread sees the appropriate stream: public void cat(String[] args) throws Exception { for (String arg : args) { IOUtil.copy(arg, System.out); } } Normal commands can provide control primitives public void each(CommandSession session, Collection<Object> list, Function closure) throws Exception { for (Object x : list) { closure.execute(session, null); } } then g! each [Jan Feb Mar] { echo $it | grep . } Jan Feb Mar The default echo command returns a String and does not write to System.out. Also, by default, the console prints the results of each command, so echo appears to behave as you would expect. However, the console does not see the each closure above, so the result of echo would not be seen. This is why it is piped into grep, as the result of the command as well as its output is written to a pipeline. Content licensed under AL2. UI licensed under MPL-2.0 with extensions licensed under AL2