[JAVA-295] Support Android platform Created: 11/Mar/11  Updated: 29/Aug/12  Resolved: 02/Aug/12

Status: Closed
Project: Java Driver
Component/s: API
Affects Version/s: 2.3, 2.4, 2.5
Fix Version/s: 2.9.0

Type: Improvement Priority: Major - P3
Reporter: Angelos Kapsimanis Assignee: Jeffrey Yemin
Resolution: Done Votes: 2
Labels: android
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Eclipse Helios Service Release 1, mongodb 1.6.5, Android SDK version 7/release 2, Windows XP SP3, Windows Vista SP2


Issue Links:
Duplicate
is duplicated by JAVA-291 Support Android platform Closed

 Description   

Hello to everybody,

I am facing the following problem:

I am trying to use the java driver within the android SDK and it gets crashed when use it as a precompiled jar (ver. 2.3, ver.2.4, ver.2.5)
whether I use it as-is or after converting it to dex format with dx.

Here is the stack trace:

03-11 22:38:17.320: INFO/dalvikvm(230): Could not find method java.lang.management.ManagementFactory.getRuntimeMXBean, referenced from method org.bson.types.ObjectId.<clinit>
03-11 22:38:17.320: WARN/dalvikvm(230): VFY: unable to resolve static method 1537: Ljava/lang/management/ManagementFactory;.getRuntimeMXBean ()Ljava/lang/management/RuntimeMXBean;
03-11 22:38:17.320: DEBUG/dalvikvm(230): VFY: replacing opcode 0x71 at 0x006c
03-11 22:38:17.320: DEBUG/dalvikvm(230): Making a copy of Lorg/bson/types/ObjectId;.<clinit> code (529 bytes)
03-11 22:38:17.410: WARN/dalvikvm(230): Exception Ljava/lang/RuntimeException; thrown during Lorg/bson/types/ObjectId;.<clinit>
03-11 22:38:17.580: WARN/dalvikvm(230): Exception Ljava/lang/ExceptionInInitializerError; thrown during Lcom/mongodb/Bytes;.<clinit>

I have tried to use the source code in the project but depends on the MBeanServer component and the java.lang.management package , hence it can't be compiled for dalvik because of their absence. The exception is thrown from the file ObjectId.class where
the MBeanServer is called.

I read in jira.mongodb.org/browse/JAVA-170 that the compilation of java.lang.management is optional but I couldn't figure it out.

Any help is greatly apreciated.



 Comments   
Comment by Jeffrey Yemin [ 29/Aug/12 ]

Closing as part of 2.9.0 release process.

Comment by auto [ 02/Aug/12 ]

Author:

{u'date': u'2012-05-02T06:54:21-07:00', u'email': u'jeff.yemin@10gen.com', u'name': u'Jeff Yemin'}

Message: JAVA-295: Further indirecting JMX dependencies to that driver will run on Android
Branch: master
https://github.com/mongodb/mongo-java-driver/commit/5664f79528fe12d62923f20db6ac80e7a512926d

Comment by Jeffrey Yemin [ 01/Aug/12 ]

I've re-evaluated the API change required for this, and I don't think it's significant enough to require a major release. SimplePool class is public but in practice should not really be used by any clients. Moving to 2.9.0.

Comment by auto [ 25/May/12 ]

Author:

{u'login': u'jyemin', u'name': u'Jeff Yemin', u'email': u'jeff.yemin@10gen.com'}

Message: JAVA-295: Further indirecting JMX dependencies to that driver will run on Android
Branch: android
https://github.com/mongodb/mongo-java-driver/commit/d3174c9415ad89cd4b8d2b1c6375faf82e4d5c6c

Comment by Jeffrey Yemin [ 02/May/12 ]

I got the driver to run on Android in the emulator by replacing DynamicMBean with SimplePoolMBean. But the change is not backwards compatible so it will have to wait for a major release.

Comment by Jeffrey Yemin [ 01/May/12 ]

I tried this out, and it does seem like the VM is being overly aggressive in its classloading. I tried this change to DBPortPool.Holder and it helped:

    static class Holder {
        static {
            MBeanServer temp = null;
            try {
               temp = ManagementFactory.getPlatformMBeanServer();
           } catch (Throwable t) {
           }
           _server = temp;
        }

But then I ran into another problem. com.mongodb.util.SimplePool implements javax.management.DynamicMBean, and so I get this error:

05-01 14:35:26.870: ERROR/dalvikvm(789): Could not find class 'com.mongodb.DBPortPool', referenced from method com.mongodb.DBPortPool$Holder.get
05-01 14:35:26.870: WARN/dalvikvm(789): VFY: unable to resolve check-cast 38 (Lcom/mongodb/DBPortPool;) in Lcom/mongodb/DBPortPool$Holder;
05-01 14:35:26.870: DEBUG/dalvikvm(789): VFY: replacing opcode 0x1f at 0x0006
05-01 14:35:26.880: DEBUG/dalvikvm(789): DexOpt: unable to opt direct call 0x0749 at 0x4e in Lcom/mongodb/DBPortPool$Holder;.createObjectName
05-01 14:35:26.880: INFO/dalvikvm(789): Failed resolving Lcom/mongodb/util/SimplePool; interface 315 'Ljavax/management/DynamicMBean;'
05-01 14:35:26.880: WARN/dalvikvm(789): Link of class 'Lcom/mongodb/util/SimplePool;' failed
05-01 14:35:26.891: WARN/dalvikvm(789): Unable to resolve superclass of Lcom/mongodb/DBPortPool; (159)
05-01 14:35:26.891: WARN/dalvikvm(789): Link of class 'Lcom/mongodb/DBPortPool;' failed

Comment by Jeffrey Yemin [ 28/Apr/12 ]

Apologies that this has been left unattended for so long. But I'm unsure what we can do about this without removing JMX entirely or resorting to reflection, which has its own risks (as it can be prevented by the security manager). Using the standard Sun VM, the technique used to fix JAVA-170 works just fine:

public class NonExistentClassTest {
    public static void main(String[] args) {
        Mongo m = null;
        try {
            m = new Mongo();
        } catch (Throwable t) {
            System.out.println(t);
        }
 
        System.out.println("Here I am");
    }
}

Run this code without mongo-java-driver in the classpath and you get this output:

java.lang.NoClassDefFoundError: com/mongodb/Mongo
Here I am

which demonstrates that the VM waits until the actual point of call before attempting to load the class.

It's possible that Dalvik is doing this differently. Can any Android developers confirm this with a full stack trace of the exception?

Comment by Samuel Kroslak [ 17/May/11 ]

Hello,

this is probably related to:
https://jira.mongodb.org/browse/JAVA-291

and the issue is marked as fixed in:
https://jira.mongodb.org/browse/JAVA-170 - but it turned out it's not, as it was said in comments,

I see this was planned for 2.6 but was postponed to 2.7, so my question: is there anything I can do, if I want to use mongodb java driver on android?
I'd love to use it instead of building my own server to act as a REST web service broker between android and mongodb...

now when I try to use it it throws:
05-17 15:36:31.390: ERROR/AndroidRuntime(6748): java.lang.NoClassDefFoundError: com.mongodb.Mongo

I've tried downloading the code and to get rid of all references to java.lang.management.* and javax.management.*
either there is problem elsewhere or I've done something wrong, but with this recompiled library it still shows the exact same error to me.
UPDATE: I've missed few parts where java.lang.management and javax.management is used, I don't know how to do it

Generated at Thu Feb 08 08:51:57 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.