Dear All,
I am using MongoJack on a OSGI Stack. Below is the exception I am getting:
set 29, 2015 3:12:59 PM com.mongodb.DBPortPool gotError
ADVERTÊNCIA: emptying DBPortPool to localhost/
127.0.0.1:27017 b/c of error
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of api.Book, problem: abstract types can only be instantiated with additional type information
at [Source: de.undercouch.bson4jackson.io.LittleEndianInputStream@4fe0026c; pos: 0]
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:233)
at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:60)
at org.codehaus.jackson.map.ObjectMapper._readValue(ObjectMapper.java:2704)
at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1315)
at net.vz.mongodb.jackson.internal.stream.JacksonDBDecoder.decode(JacksonDBDecoder.java:62)
at com.mongodb.Response.<init>(Response.java:83)
at com.mongodb.DBPort.go(DBPort.java:142)
at com.mongodb.DBPort.call(DBPort.java:92)
at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:244)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:216)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:288)
at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:273)
at com.mongodb.DBCursor._check(DBCursor.java:368)
at com.mongodb.DBCursor._hasNext(DBCursor.java:459)
at com.mongodb.DBCursor.hasNext(DBCursor.java:484)
at net.vz.mongodb.jackson.DBCursor.hasNext(DBCursor.java:315)
at mongo.BookInventoryMongo.listBooks(BookInventoryMongo.java:44)
at mongo.BookInventoryMongo.start(BookInventoryMongo.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.felix.dm.InvocationUtil.invokeMethod(InvocationUtil.java:111)
at org.apache.felix.dm.InvocationUtil.invokeCallbackMethod(InvocationUtil.java:66)
at org.apache.felix.dm.impl.ComponentImpl.invokeCallbackMethod(ComponentImpl.java:688)
at org.apache.felix.dm.impl.ComponentImpl.invoke(ComponentImpl.java:679)
at org.apache.felix.dm.impl.ComponentImpl.bindService(ComponentImpl.java:624)
at org.apache.felix.dm.impl.ComponentImpl.access$400(ComponentImpl.java:52)
at org.apache.felix.dm.impl.ComponentImpl$7.run(ComponentImpl.java:181)
at org.apache.felix.dm.impl.SerialExecutor$1.run(SerialExecutor.java:47)
at org.apache.felix.dm.impl.SerialExecutor.scheduleNext(SerialExecutor.java:84)
at org.apache.felix.dm.impl.SerialExecutor.access$000(SerialExecutor.java:33)
at org.apache.felix.dm.impl.SerialExecutor$1.run(SerialExecutor.java:50)
at org.apache.felix.dm.impl.SerialExecutor.scheduleNext(SerialExecutor.java:84)
at org.apache.felix.dm.impl.SerialExecutor.access$000(SerialExecutor.java:33)
at org.apache.felix.dm.impl.SerialExecutor$1.run(SerialExecutor.java:50)
at org.apache.felix.dm.impl.SerialExecutor.scheduleNext(SerialExecutor.java:84)
at org.apache.felix.dm.impl.SerialExecutor.execute(SerialExecutor.java:68)
at org.apache.felix.dm.impl.ComponentImpl.calculateStateChanges(ComponentImpl.java:231)
at org.apache.felix.dm.impl.ComponentImpl.start(ComponentImpl.java:399)
at org.apache.felix.dm.DependencyManager.add(DependencyManager.java:169)
at mongo.Activator.init(Activator.java:28)
at org.apache.felix.dm.DependencyActivatorBase.start(DependencyActivatorBase.java:76)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2154)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2072)
at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:976)
at aQute.launcher.Launcher.update(Launcher.java:457)
at aQute.launcher.Launcher$1.run(Launcher.java:194)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
WARNING: Invocation of 'start' failed. (com.mongodb.MongoException$Network: Read operation to server localhost/
127.0.0.1:27017 failed on database test_booksDB)
Below the code:
********API Bundle******
package api;
public interface
Book {
public String getBookName();
public void setBookName(String name);
}
package api;
import java.util.List;
public interface
BookInventory {
public void addBook(Book book);
public List<Book> listBooks();
}
****** Mongo Bundle********
package mongo;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonProperty;
import api.Book;
public class
BookMongo implements Book{
private String _id;
private String bookName;
public BookMongo() {
super();
// TODO Auto-generated constructor stub
}
@JsonCreator
public BookMongo(@JsonProperty ("id") String _id, @JsonProperty ("bName") String bookName) {
super();
this._id = _id;
this.bookName = bookName;
}
@JsonProperty("id")
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
@Override
@JsonProperty("bName")
public String getBookName() {
return bookName;
}
@Override
public void setBookName(String name) {
this.bookName = name;
}
@Override
public String toString() {
return "BookMongo [_id=" + _id + ", bookName=" + bookName + "]";
}
}
package mongo;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import net.vz.mongodb.jackson.DBCursor;
import net.vz.mongodb.jackson.JacksonDBCollection;
import org.amdatu.mongo.MongoDBService;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import com.mongodb.DBCollection;
import api.Book;
import api.BookInventory;
public class
BookInventoryMongo implements BookInventory{
private volatile MongoDBService mongoDBService;
@Override
public void addBook(Book book) {
DBCollection collection = mongoDBService.getDB().getCollection("booksColl");
JacksonDBCollection<Book, Object> books = JacksonDBCollection.wrap(collection, Book.class);
addBook
books.save(book);
}
@Override
@JsonDeserialize(contentAs=BookMongo.class)
public List<Book> listBooks() {
DBCollection collection = mongoDBService.getDB().getCollection("booksColl");
JacksonDBCollection<Book, Object> books = JacksonDBCollection.wrap(collection, Book.class);
DBCursor<Book> cursor = books.find();
List<Book> result = new ArrayList<Book>();
while (cursor.hasNext()) {
result.add(cursor.next());
}
return result;
}
public void start(){
Book bm = new BookMongo("5","The walking dead");
addBook(bm);
System.out.println("****Attention***");
System.out.println("New book added to mongo");
System.out.println(listBooks().toString());
}
}
package mongo;
import java.util.Properties;
import org.amdatu.mongo.MongoDBService;
import org.apache.felix.dm.DependencyActivatorBase;
import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.BundleContext;
import api.BookInventory;
public class
Activator extends DependencyActivatorBase{
@Override
public void destroy(BundleContext arg0, DependencyManager arg1)
throws Exception {
// TODO Auto-generated method stub
}
@Override
public void init(BundleContext arg0, DependencyManager dm)
throws Exception {
Properties props = new Properties();
props.put("persistent", true);
dm.add(createComponent()
.setInterface(BookInventory.class.getName(), props)
.setImplementation(BookInventoryMongo.class)
.add(createServiceDependency()
.setService(MongoDBService.class).
setRequired(true)));
}
}
It is clear for me that the problem is due to the impossibility of mongo-jackson-mapper reading from the bank. it cannot instantiate the "Book.class" once it is an interface.
I cannot anotate any of the api interfaces otherwise it would broke modularity. In my research I thought MixIns should be the more suitable option here, however it didnt work at all. I mitgh be doing something wrong definetely. Is there any option to solve this? By the way, the addBook method in
BookInventoryMongo works fine.
Than you for helpping.