I need to access a MySQL db from my android app. Now all the work is done through
DriverManager.getConnection(url);
and so on. But I have to access the db from multiple threads, so I have to use connection pooling.
Question 1. Is
com.mysql.jdbc.jdbc2.optional.MysqlDataSource ds = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
the right way of creating the data source?
Question 2. If I write the previous line of code, my app compiles and installs on the device (not emulator) fine, but I get a weird
java.lang.NoClassDefFoundError: com.mysql.jdbc.jdbc2.optional.MysqlDataSource`
, that I can't catch with a try/catch handler:
try
{
com.mysql.jdbc.jdbc2.optional.MysqlDataSource a = new com.mysql.jdbc.jdbc2.optional.MysqlDataSource();
}
catch (Exception e)
{
I don't get here. The app just crashes, as if I had no try/catch block.
}
Question 3. I copied mysql-connector-java-5.1.20-bin.jar to the device and wrote the following code:
try
{
final String str = Environment.getExternalStorageState();
final File sd = getActivity().getExternalFilesDir(null);
final File file = new File(sd, "mysql-connector-java-5.1.20-bin.jar");
boolean b = file.exists();
final URLClassLoader cl = URLClassLoader.newInstance(new URL[] {file.toURI().toURL()} );
cl.loadClass("com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); //$NON-NLS-1$
}
catch (Exception e)
{
new AlertDialog.Builder(getActivity())
.setMessage(ObjectConverter.throwable2String(e))
.show();
}
The file is found but
cl.loadClass()
fails with
java.lang.NullPointerException
at java.net.URLClassLoader.getPermissions(URLClassLoader.java:614)
at java.security.SecureClassLoader.getPD(SecureClassLoader.java:140)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:93)
at java.net.URLClassLoader.access$600(URLClassLoader.java:55)
at java.net.URLClassLoader$URLJarHandler.createClass(URLClassLoader.java:364)
at java.net.URLClassLoader$URLJarHandler.findClass(URLClassLoader.java:303)
at java.net.URLClassLoader.findClass(URLClassLoader.java:748)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at ru.mypkg.myapp.func(myapp.java:367)
at android.view.View.performClick(View.java:3511)
at android.view.View$PerformClick.run(View.java:14110)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4424)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Any help greatly appreciated.
This question is 6 years old and Mark is correct that, in almost every scenario you can think of, JDBC on Android is about as sensible as trying to use a toaster in the bath. However, sometimes we do things because we can and not because we necessarily should, and today I had a justifiable reason to want to do this (for a specific very niche app running in an unusual environment), which is how I found this question.
Addressing the
NoClassDefFoundError
first, the reason it isn't caught by thecatch
block is because it's anError
not anException
. BothError
andException
inherit fromThrowable
, so you could catch that instead:I believe that it's not
MySqlDataSource
that it can't find, but one of the classes or interfaces that it depends on - in my case it wasjavax.naming.Referenceable
. Android doesn't provide thejavax.naming
package so trying to use the pooling features of the Connector/J JDBC driver for MySQL isn't going to get you very far (you could try to provide the missing dependencies but that road likely leads to madness).Instead you'll probably have more luck with a third-party connection pool implementation. There are various Java libraries for doing this. Some of them will work on Android. One that I have verified does work is HikariCP. There are instructions for configuring it here and, specifically for MySQL, here.