While running db4o library (Both 8.1-SNAPSHOT and 8.0), opening the database works
oc = Db4oEmbedded.openFile(dbConfig(), db4oDBFullPath(context));
//context.getDir("data", 0) + "/" + "mDB.DB4O"; to get the full path
However, once I start trying to store an object
oc.store(object)
I get the error, cannot cast java.lang.Long to java.lang.Integer
. This problem is caused probably by the new dalvik implementation for the new Android OS versions, but is there any patches or workarounds for this error available?
A guy was introducing a patch here but it's inaccessible.
Full stacktrace of the error
java.lang.UnsupportedOperationException: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer at com.db4o.internal.DalvikVM$Dalvik3ObjectFactoryFactory.(DalvikVM.java:120) at com.db4o.internal.DalvikVM.factory(DalvikVM.java:75) at com.db4o.internal.DalvikVM.supportSkipConstructorCall(DalvikVM.java:55) at com.db4o.internal.Platform4.callConstructor(Platform4.java:463) at com.db4o.reflect.core.ConstructorSupport.createConstructor(ConstructorSupport.java:21) at com.db4o.reflect.jdk.JdkClass.constructorSpec(JdkClass.java:176) at com.db4o.reflect.jdk.JdkClass.ensureCanBeInstantiated(JdkClass.java:182) at com.db4o.reflect.generic.GenericClass.ensureCanBeInstantiated(GenericClass.java:282) at com.db4o.internal.ClassMetadata.createConstructor(ClassMetadata.java:684) at com.db4o.internal.ClassMetadata.initializeConstructor(ClassMetadata.java:648) at com.db4o.internal.ClassMetadata.initializeAspects(ClassMetadata.java:266) at com.db4o.internal.ClassMetadata.checkChanges(ClassMetadata.java:494) at com.db4o.internal.ClassMetadataRepository.readClassMetadata(ClassMetadataRepository.java:465) at com.db4o.internal.ClassMetadataRepository.classMetadataForId(ClassMetadataRepository.java:259) at com.db4o.internal.ObjectContainerBase.classMetadataForID(ObjectContainerBase.java:1069) at com.db4o.internal.marshall.ObjectHeader.(ObjectHeader.java:39) at com.db4o.internal.marshall.ObjectHeader.(ObjectHeader.java:23) at com.db4o.internal.marshall.UnmarshallingContext.readObjectHeader(UnmarshallingContext.java:124) at com.db4o.internal.marshall.UnmarshallingContext.read(UnmarshallingContext.java:47) at com.db4o.internal.ObjectReference.read(ObjectReference.java:306) at com.db4o.internal.ObjectReference.read(ObjectReference.java:292) at com.db4o.internal.ObjectContainerBase.getByID2(ObjectContainerBase.java:886) at com.db4o.internal.ObjectContainerBase.getByID(ObjectContainerBase.java:857) at com.db4o.internal.fileheader.FileHeaderVariablePart.readIdentity(FileHeaderVariablePart.java:44) at com.db4o.internal.fileheader.NewFileHeaderBase.readIdentity(NewFileHeaderBase.java:92) at com.db4o.internal.LocalObjectContainer.readThis(LocalObjectContainer.java:497) at com.db4o.internal.IoAdaptedObjectContainer.openImpl(IoAdaptedObjectContainer.java:71) at com.db4o.internal.ObjectContainerBase$1.run(ObjectContainerBase.java:140) at com.db4o.foundation.DynamicVariable.with(DynamicVariable.java:54) at com.db4o.foundation.Environments.runWith(Environments.java:28) at com.db4o.internal.ObjectContainerBase.withEnvironment(ObjectContainerBase.java:161) at com.db4o.internal.ObjectContainerBase.open(ObjectContainerBase.java:131) at com.db4o.internal.IoAdaptedObjectContainer.(IoAdaptedObjectContainer.java:35) at com.db4o.internal.ObjectContainerFactory.openObjectContainer(ObjectContainerFactory.java:18) at com.db4o.Db4oEmbedded.openFile(Db4oEmbedded.java:64)
Update:
So, after tracing the error, it turns out that there is a terrible cast from Long to Integer inside com.db4o.internal.DalvikVM
in version 8.0
int _methodId; _methodId = (Integer) constructorIdMethod.invoke(null, Object.class);
I tried to fix this by declaring the variable as long. I recompiled and ran again on Android, I got another error which is
UnsupportedOperationException: java.lang.NoSuchMethodException: newInstance [class java.lang.Class, int]
Caused by this:
try {
_method = ObjectStreamClass.class.getDeclaredMethod("newInstance", Class.class, Integer.TYPE);
_method.setAccessible(true);
} catch (Exception e) {
throw new UnsupportedOperationException(e);
}
}
Any clue how to solve this?
I managed to fix this by creating a patch in the code of db4o 8.1
Here you go, the new JAR file and code changes are available in this GITHUB repository. There is also a demo for testing the library on the repo.
I changed few lines in com.db4o.internal.Platform4
. Basically I changed the order of JDKs to look up.
private static void createJdk() {
Class<?>[] jdkFactories = {
JDK_5.Factory.class,//1 switched both positions.
DalvikVM.Factory.class,//2
JDK_1_4.Factory.class,
JDK_1_3.Factory.class,
JDK_1_2.Factory.class,
JDKReflect.Factory.class,
};
//-----