mongodb 3.x 驱动程序 Android 兼容性
mongodb 3.x driver Android compatibility
我正在开发一个 Android 应用程序,它使用 java mongodb 驱动程序 3.0.3 连接到 mongodb.
的每个实例
通用实例的连接器代码是:
try{
MongoCredential credential = MongoCredential.createCredential(user, dbname, pass.toCharArray());
MongoClient mongoClient = new MongoClient( new ServerAddress(server , port ), Arrays.asList(credential));
MongoDatabase db = mongoClient.getDatabase(dbname);
System.out.println("Connect to database successfully ");
Iterator i= mongoClient.listDatabaseNames().iterator();
while (i.hasNext()){
Log.d("DATABASE", (String) i.next());
}
Iterator ic= db.listCollectionNames().iterator();
while (ic.hasNext()){
Log.d("COLLECTION", (String) ic.next());
}
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
在运行时我有一些错误:
09-11 19:13:50.898 7418-7418/it.mysite.mongodbviewer W/org.bson.ObjectId﹕ Failed to get process identifier from JMX, using random number instead java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;
和
com.mongodb.MongoException: java.lang.NoClassDefFoundError: com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient
生成一个循环:
I/art﹕ Rejecting re-init on previously-failed class java.lang.Class
有人有解决办法吗?
java/lang/management/ManagementFactory似乎不存在于Android,请问如何解决?如果这是问题的中心。
提前致谢,马特奥
PS:完整日志为:
09-11 19:13:50.898 7418-7418/it.mysite.mongodbviewer W/org.bson.ObjectId﹕ Failed to get process identifier from JMX, using random number instead
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;
at org.bson.types.ObjectId.createProcessIdentifier(ObjectId.java:502)
at org.bson.types.ObjectId.<clinit>(ObjectId.java:460)
at com.mongodb.connection.ClusterId.<init>(ClusterId.java:47)
at com.mongodb.connection.DefaultClusterFactory.create(DefaultClusterFactory.java:40)
at com.mongodb.Mongo.createCluster(Mongo.java:660)
at com.mongodb.Mongo.createCluster(Mongo.java:646)
at com.mongodb.Mongo.<init>(Mongo.java:275)
at com.mongodb.MongoClient.<init>(MongoClient.java:184)
at com.mongodb.MongoClient.<init>(MongoClient.java:160)
at it.mysite.mongodbmanager.data.MongoDBDriver.connect(MongoDBDriver.java:102)
at it.mysite.mongodbmanager.fragments.MongoDBAccountDetailFragment.onClick(MongoDBAccountDetailFragment.java:101)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19865)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.management.ManagementFactory" on path: DexPathList[[zip file "/data/app/it.mysite.mongodbviewer-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.bson.types.ObjectId.createProcessIdentifier(ObjectId.java:502)
at org.bson.types.ObjectId.<clinit>(ObjectId.java:460)
at com.mongodb.connection.ClusterId.<init>(ClusterId.java:47)
at com.mongodb.connection.DefaultClusterFactory.create(DefaultClusterFactory.java:40)
at com.mongodb.Mongo.createCluster(Mongo.java:660)
at com.mongodb.Mongo.createCluster(Mongo.java:646)
at com.mongodb.Mongo.<init>(Mongo.java:275)
at com.mongodb.MongoClient.<init>(MongoClient.java:184)
at com.mongodb.MongoClient.<init>(MongoClient.java:160)
at it.mysite.mongodbmanager.data.MongoDBDriver.connect(MongoDBDriver.java:102)
at it.mysite.mongodbmanager.fragments.MongoDBAccountDetailFragment.onClick(MongoDBAccountDetailFragment.java:101)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19865)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Suppressed: java.lang.ClassNotFoundException: java.lang.management.ManagementFactory
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 22 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
09-11 19:13:50.901 7418-7418/it.mysite.mongodbviewer I/cluster﹕ Cluster created with settings {hosts=[192.168.1.74:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
09-11 19:13:50.918 7418-7418/it.mysite.mongodbviewer I/System.out﹕ Connect to database successfully
09-11 19:13:50.924 7418-7418/it.mysite.mongodbviewer I/cluster﹕ No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{address=192.168.1.74:27017, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
09-11 19:13:50.954 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:50.954 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:50.955 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:50.956 7418-7487/it.mysite.mongodbviewer I/cluster﹕ Exception in monitor thread while connecting to server 192.168.1.74:27017
com.mongodb.MongoException: java.lang.NoClassDefFoundError: com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:125)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NoClassDefFoundError: com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient
at com.mongodb.connection.ScramSha1Authenticator.createSaslClient(ScramSha1Authenticator.java:61)
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:42)
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:818)
09-11 19:13:51.479 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:52.106 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:52.637 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
在我看来,ManagementFactory 是一个转移注意力的问题,因为驱动程序捕获了该异常并转而使用随机数。
真正的问题似乎是驱动程序需要使用 SCRAM-SHA-1 进行身份验证,其实现导入以下 类:
import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
我怀疑这些在 Android 平台中不可用,它不是 Java 运行时环境的完整实现。
您可以尝试的一件事是 运行 针对 MongoDB 2.6,驱动程序的身份验证实现仅依赖于 java.security.MessageDigest。
另一件需要考虑的事情是在移动应用程序和 MongoDB 之间放置一个 REST 服务,该服务负责代理与数据库的所有交互。 REST 应用程序可以 运行 在 MongoDB 驱动程序将完全正常运行的环境中。
REST 服务解决方法不是办法,我必须直接连接到 mongodb 实例。
编辑:
Sync mongo-java-驱动程序已正确移植到 Android,此移植:https://github.com/matfur92/mongo-java-driver
没有驱动程序异步未移植,因为 java.nio.channels.AsynchronousSocketChannel
在 Android 上不存在并且不存在任何移植。
如果有人有使驱动程序异步工作的解决方案,请告诉我。问题出在 java.nio.channels.AsynchronousSocketChannel
而 Android
不存在
对于任何想在 Android 上使用 github.com/mongodb/mongo-java-driver
的人,我有一个解决方案!
我从官方 github.com/mongodb/mongo-java-driver
分叉并从 github.com/koterpillar/android-sasl
集成 类 以修复 Android 上的 javax.security.sasl
。
重要提示:没有驱动程序异步未移植,因为 java.nio.channels.AsynchronousSocketChannel 在 Android 上不存在并且不存在任何移植。
结果是工作同步 MongoDB Android (Java) 驱动程序,您可以从 https://github.com/matfur92/mongo-java-driver
下载
最后更新(2015 年 11 月 5 日):3.2.0-快照 --> https://github.com/matfur92/mongo-java-driver/blob/gh-pages/JARs/mongo-java-driver-3.2.0-SNAPSHOT.jar?raw=true
我正在开发一个 Android 应用程序,它使用 java mongodb 驱动程序 3.0.3 连接到 mongodb.
的每个实例通用实例的连接器代码是:
try{
MongoCredential credential = MongoCredential.createCredential(user, dbname, pass.toCharArray());
MongoClient mongoClient = new MongoClient( new ServerAddress(server , port ), Arrays.asList(credential));
MongoDatabase db = mongoClient.getDatabase(dbname);
System.out.println("Connect to database successfully ");
Iterator i= mongoClient.listDatabaseNames().iterator();
while (i.hasNext()){
Log.d("DATABASE", (String) i.next());
}
Iterator ic= db.listCollectionNames().iterator();
while (ic.hasNext()){
Log.d("COLLECTION", (String) ic.next());
}
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
在运行时我有一些错误:
09-11 19:13:50.898 7418-7418/it.mysite.mongodbviewer W/org.bson.ObjectId﹕ Failed to get process identifier from JMX, using random number instead java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;
和
com.mongodb.MongoException: java.lang.NoClassDefFoundError: com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient
生成一个循环:
I/art﹕ Rejecting re-init on previously-failed class java.lang.Class
有人有解决办法吗? java/lang/management/ManagementFactory似乎不存在于Android,请问如何解决?如果这是问题的中心。
提前致谢,马特奥
PS:完整日志为:
09-11 19:13:50.898 7418-7418/it.mysite.mongodbviewer W/org.bson.ObjectId﹕ Failed to get process identifier from JMX, using random number instead
java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;
at org.bson.types.ObjectId.createProcessIdentifier(ObjectId.java:502)
at org.bson.types.ObjectId.<clinit>(ObjectId.java:460)
at com.mongodb.connection.ClusterId.<init>(ClusterId.java:47)
at com.mongodb.connection.DefaultClusterFactory.create(DefaultClusterFactory.java:40)
at com.mongodb.Mongo.createCluster(Mongo.java:660)
at com.mongodb.Mongo.createCluster(Mongo.java:646)
at com.mongodb.Mongo.<init>(Mongo.java:275)
at com.mongodb.MongoClient.<init>(MongoClient.java:184)
at com.mongodb.MongoClient.<init>(MongoClient.java:160)
at it.mysite.mongodbmanager.data.MongoDBDriver.connect(MongoDBDriver.java:102)
at it.mysite.mongodbmanager.fragments.MongoDBAccountDetailFragment.onClick(MongoDBAccountDetailFragment.java:101)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19865)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.management.ManagementFactory" on path: DexPathList[[zip file "/data/app/it.mysite.mongodbviewer-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
at org.bson.types.ObjectId.createProcessIdentifier(ObjectId.java:502)
at org.bson.types.ObjectId.<clinit>(ObjectId.java:460)
at com.mongodb.connection.ClusterId.<init>(ClusterId.java:47)
at com.mongodb.connection.DefaultClusterFactory.create(DefaultClusterFactory.java:40)
at com.mongodb.Mongo.createCluster(Mongo.java:660)
at com.mongodb.Mongo.createCluster(Mongo.java:646)
at com.mongodb.Mongo.<init>(Mongo.java:275)
at com.mongodb.MongoClient.<init>(MongoClient.java:184)
at com.mongodb.MongoClient.<init>(MongoClient.java:160)
at it.mysite.mongodbmanager.data.MongoDBDriver.connect(MongoDBDriver.java:102)
at it.mysite.mongodbmanager.fragments.MongoDBAccountDetailFragment.onClick(MongoDBAccountDetailFragment.java:101)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19865)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Suppressed: java.lang.ClassNotFoundException: java.lang.management.ManagementFactory
at java.lang.Class.classForName(Native Method)
at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
... 22 more
Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
09-11 19:13:50.901 7418-7418/it.mysite.mongodbviewer I/cluster﹕ Cluster created with settings {hosts=[192.168.1.74:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
09-11 19:13:50.918 7418-7418/it.mysite.mongodbviewer I/System.out﹕ Connect to database successfully
09-11 19:13:50.924 7418-7418/it.mysite.mongodbviewer I/cluster﹕ No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{address=192.168.1.74:27017, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
09-11 19:13:50.954 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:50.954 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:50.955 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:50.956 7418-7487/it.mysite.mongodbviewer I/cluster﹕ Exception in monitor thread while connecting to server 192.168.1.74:27017
com.mongodb.MongoException: java.lang.NoClassDefFoundError: com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:125)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NoClassDefFoundError: com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient
at com.mongodb.connection.ScramSha1Authenticator.createSaslClient(ScramSha1Authenticator.java:61)
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:42)
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:818)
09-11 19:13:51.479 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:52.106 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
09-11 19:13:52.637 7418-7487/it.mysite.mongodbviewer I/art﹕ Rejecting re-init on previously-failed class java.lang.Class<com.mongodb.connection.ScramSha1Authenticator$ScramSha1SaslClient>
在我看来,ManagementFactory 是一个转移注意力的问题,因为驱动程序捕获了该异常并转而使用随机数。
真正的问题似乎是驱动程序需要使用 SCRAM-SHA-1 进行身份验证,其实现导入以下 类:
import javax.crypto.Mac;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
我怀疑这些在 Android 平台中不可用,它不是 Java 运行时环境的完整实现。
您可以尝试的一件事是 运行 针对 MongoDB 2.6,驱动程序的身份验证实现仅依赖于 java.security.MessageDigest。
另一件需要考虑的事情是在移动应用程序和 MongoDB 之间放置一个 REST 服务,该服务负责代理与数据库的所有交互。 REST 应用程序可以 运行 在 MongoDB 驱动程序将完全正常运行的环境中。
REST 服务解决方法不是办法,我必须直接连接到 mongodb 实例。
编辑:
Sync mongo-java-驱动程序已正确移植到 Android,此移植:https://github.com/matfur92/mongo-java-driver
没有驱动程序异步未移植,因为 java.nio.channels.AsynchronousSocketChannel
在 Android 上不存在并且不存在任何移植。
如果有人有使驱动程序异步工作的解决方案,请告诉我。问题出在 java.nio.channels.AsynchronousSocketChannel
而 Android
对于任何想在 Android 上使用 github.com/mongodb/mongo-java-driver
的人,我有一个解决方案!
我从官方 github.com/mongodb/mongo-java-driver
分叉并从 github.com/koterpillar/android-sasl
集成 类 以修复 Android 上的 javax.security.sasl
。
重要提示:没有驱动程序异步未移植,因为 java.nio.channels.AsynchronousSocketChannel 在 Android 上不存在并且不存在任何移植。
结果是工作同步 MongoDB Android (Java) 驱动程序,您可以从 https://github.com/matfur92/mongo-java-driver
下载最后更新(2015 年 11 月 5 日):3.2.0-快照 --> https://github.com/matfur92/mongo-java-driver/blob/gh-pages/JARs/mongo-java-driver-3.2.0-SNAPSHOT.jar?raw=true