Abstract types can only be instantiated with additional type information

1,242 views
Skip to first unread message

oliv.g...@gmail.com

unread,
Sep 29, 2015, 2:28:48 PM9/29/15
to mongo-jackson-mapper
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.



Reply all
Reply to author
Forward
0 new messages