Hmmm this seems to be a limitation of the iPojo @ServiceProperty
annotation.
You don't actually need the gogo help command to test your example.
another command which will show the existence of your search command is
'type':
g! type search
search is Set<Book> book:search(String, String, String, String)
search is Set<Book> book:search(String, String, String, int, int)
You should be able to invoke it directly:
g! search args ...
Derek
On 16 June 2011 09:58, Mike Veksler<[email protected]> wrote:
I tried registing FUNCTIONS however the annotation expects String value
and
not String array.
On Thu, Jun 16, 2011 at 1:55 AM, Derek Baum<[email protected]>
wrote:
This is a bug in the gogo help command.
Services proving commands can be registered with
@ServiceProperty(name = "osgi.command.function", functions)
where functions is either String or String[].
The gogo help command does not take account of this being a String
rather
than String[].
The quick fix for now is to register FUNCTIONS rather than
FUNCTIONS_STR.
I'll raise an issue to fix the gogo help command.
Derek
On 16 June 2011 09:46, Mike Veksler<[email protected]> wrote:
Here is the stack trace:
g! e
java.lang.ClassCastException: java.lang.String cannot be cast to
[Ljava.lang.String;
at
org.apache.felix.gogo.command.Basic.getCommands(Basic.java:384)
at org.apache.felix.gogo.command.Basic.help(Basic.java:211)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
org.apache.felix.gogo.runtime.Reflective.method(Reflective.java:136)
at
org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:82)
at
org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:469)
at
org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:395)
at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
at
org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)
at
org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)
at
org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.jav
a:89)
at org.apache.felix.gogo.shell.Console.run(Console.java:62)
at org.apache.felix.gogo.shell.Shell.console(Shell.java:203)
at org.apache.felix.gogo.shell.Shell.gosh(Shell.java:128)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown
Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at
org.apache.felix.gogo.runtime.Reflective.method(Reflective.java:136)
at
org.apache.felix.gogo.runtime.CommandProxy.execute(CommandProxy.java:82)
at
org.apache.felix.gogo.runtime.Closure.executeCmd(Closure.java:469)
at
org.apache.felix.gogo.runtime.Closure.executeStatement(Closure.java:395)
at org.apache.felix.gogo.runtime.Pipe.run(Pipe.java:108)
at
org.apache.felix.gogo.runtime.Closure.execute(Closure.java:183)
at
org.apache.felix.gogo.runtime.Closure.execute(Closure.java:120)
at
org.apache.felix.gogo.runtime.CommandSessionImpl.execute(CommandSessionImpl.jav
a:89)
at
org.apache.felix.shell.remote.Shell.startGogoShell(Shell.java:108)
at org.apache.felix.shell.remote.Shell.run(Shell.java:81)
at java.lang.Thread.run(Unknown Source)
g!
On Thu, Jun 16, 2011 at 1:39 AM, Derek Baum<[email protected]>
wrote:
Have you got a stack trace?
Type 'e' in gogo after an exception is reported to see the stack
trace
'e' is actually a function:
g! type e
e is function { $exception printStackTrace }
which simply invokes the printStackTrace() method on the Exception
object
stored in the gogo exception variable.
Derek
On 16 June 2011 06:35, Mike Veksler<[email protected]> wrote:
I am trying to go through tutorial from OSGI and Apache Felix 3.0
book
and
one of the the examples is to use IPOJO Annotation and Meta.xml.
When
I
deploy application to Felix the application runs fine but if i
try
to
lookup
help iside Felix Gogo shell, I get error: gogo:
ClassCastException:
java.lang.String cannot be cast to [Ljava.lang.String;
Here is the code with annotation:
package com.packtpub.felix.bookshelf.service.tui;
import com.packtpub.felix.bookshelf.inventory.api.Book;
import
com.packtpub.felix.bookshelf.inventory.api.BookAlreadyExistsException;
import
com.packtpub.felix.bookshelf.inventory.api.BookNotFoundException;
import
com.packtpub.felix.bookshelf.inventory.api.InvalidBookException;
import com.packtpub.felix.bookshelf.service.api.BookshelfService;
import
com.packtpub.felix.bookshelf.service.api.InvalidCredentialsException;
import
com.packtpub.felix.bookshelf.service.tui.api.BookshelfServiceProxy;
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.annotations.Provides;
import org.apache.felix.ipojo.annotations.Requires;
import org.apache.felix.ipojo.annotations.ServiceProperty;
import org.apache.felix.service.command.Descriptor;
//import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import java.util.HashSet;
import java.util.Set;
@Component(name = "BookshelfServiceProxy")
@Provides
public class BookshelfServiceProxyImpl implements
BookshelfServiceProxy{
public static final String SCOPE = "book";
@ServiceProperty(name = "osgi.command.scope", value = SCOPE)
public String gogoScope;
public static final String[] FUNCTIONS = new String[] {
"add", "search"
};
public static final String FUNCTIONS_STR ="search";
@ServiceProperty(name = "osgi.command.function", value =
FUNCTIONS_STR)
public String gogoFunctions;
//private BundleContext context;
@Requires
private BookshelfService bookshelf;
// public BookshelfServiceProxyImpl(BundleContext context){
// this.context = context;
// }
public BookshelfServiceProxyImpl(){
}
@Descriptor("Search books by author, title, or category")
public Set<Book> search(
@Descriptor("username")
String username,
@Descriptor("password")
String password,
@Descriptor(
"search on attribute: author, title, or
category"
)
String attribute,
@Descriptor(
"match like (use % at the beginning or end of
<like>"
+
" for wild-card)")
String filter) throws InvalidCredentialsException{
BookshelfService service = lookupService();
String sessionid =
service.login(username,password.toCharArray());
Set<String> results;
if("title".equals(attribute)){
results =
service.searchBooksByTitle(sessionid,filter);
}
else if("author".equals(attribute)){
results =
service.searchBooksByAuthor(sessionid,filter);
}
else if("category".equals(attribute)){
results =
service.searchBooksByCategory(sessionid,filter);
}
else{
throw new RuntimeException(
"Invalid attribute, expecting one of {
'title',
"
+
"'author', 'category' } got
'"+attribute+"'");
}
return getBooks(sessionid,service,results);
}
@Descriptor("Search books by rating")
public Set<Book> search(
@Descriptor("username")
String username,
@Descriptor("password")
String password,
@Descriptor("search on attribute rating")
String attribute,
@Descriptor("lower rating limit (inclusive)")
int lower,
@Descriptor("upper rating limit (inclusive)")
int upper) throws InvalidCredentialsException {
if(!"rating".equals(attribute)){
throw new RuntimeException(
"Invalid attribute, expecting 'rating' got '"+
attribute+"'");
}
BookshelfService service = lookupService();
String sessionid =
service.login(username,password.toCharArray());
Set<String> results =
service.searchBooksByRating(sessionid,lower,upper);
return getBooks(sessionid,service,results);
}
@Descriptor("Add book to the inventory")
public String add(
@Descriptor("username") String username,
@Descriptor("password") String password,
@Descriptor("ISBN") String isbn,
@Descriptor("Title") String title,
@Descriptor("Author") String author,
@Descriptor("Category") String category,
@Descriptor("Rating (0..10)") int rating)
throws InvalidCredentialsException,
BookAlreadyExistsException,
InvalidBookException{
BookshelfService service = lookupService();
String sessionId =
service.login(username,password.toCharArray());
service.addBook(sessionId,isbn,title,author,category,rating);
return isbn;
}
private BookshelfService lookupService(){
// ServiceReference reference =
context.getServiceReference(
// BookshelfService.class.getName());
// if(reference==null){
// throw new RuntimeException("BookshelfService not
registered,cannot invoke "+
// "operation");
// }
// BookshelfService service = (BookshelfService)
this.context.getService(reference);
// if(service==null){
// throw new RuntimeException(
// "BookshelfService not registered, cannot
invoke
"+
// "operation");
// }
// return service;
return this.bookshelf;
}
private Set<Book> getBooks(
String sessionid, BookshelfService service,
Set<String> results) {
Set<Book> books = new HashSet<Book>();
for(String isbn: results){
Book book;
try{
book = service.getBook(sessionid,isbn);
books.add(book);
} catch (BookNotFoundException e) {
System.out.println("ISBN "+ isbn +
" referenced but not found");
}
}
return books;
}
}
Here is meta.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="org.apache.felix.ipojo
http://felix.apache.org/ipojo/schemas/CURRENT/core.xsd"
xmlns="org.apache.felix.ipojo">
<instance component="BookshelfServiceProxy"
name="bookshelf.service.tui"/>
</ipojo>