4

I'm trying to run a stored procedure on my SQL Server database from an Android app I've developed. I'm just messing about at the minute but I can't seem to get it to run. Thing is I don't get any kind of errors or crashes either - the app works fine and I can click the button, the stored procedure just doesn't seem to want to run.

The SP creates a row in a table. I've tested this in SQL server and it works perfectly. The issue seems to be with executing it from my app..

I think I've set things up correctly.

1) I've included the correct .jar file in the libs folder for my app.

2) I've included a reference to the library in build.gradle:-

dependencies {
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
    compile 'com.google.android.gms:play-services:8.3.0'
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile files('libs/jtds-1.3.1.jar')
}

3) I've imported all of the libraries that I need (I think):-

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

4) I've got a button that, when clicked should run the stored procedure:-

@Override
public void onClick(View v) {
    try {
        Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
        String username = "myusername";
        String password = "mypassword";
        Connection DbConn = DriverManager.getConnection("jdbc:jtds:sqlserver://sql9.hostinguk.net/matprichardson;user=" + username + ";password=" + password);

        Log.w("Connection","Open");
        Statement stmt = DbConn.createStatement();
        stmt.execute("exec [matprichardson].[updatelatlong]");

        DbConn.close();
    } catch (Exception e) {
        Log.w("Error connection","" + e.getMessage());
    }
}

If I remove the code from the try/catch blocks, the Class.forName part highlights in red and when I hover I get a java.lang.ClassNotFoundException but I've read that's the reason for the try/catch block in the first place...am I right?

Anyway, after tinkering about with this for an hour I've reached a point where I don't know what to do anymore. Hope you guys can help.

Note: I'm running the app directly on my device rather than through an emulator.

Another note: In the 'logcat' part of Android Monitor I get an error. Full log when I click the button:

11-28 22:54:29.173 11995-11995/uk.co.matprichardson.omgandroid D/libc: [NET] android_getaddrinfofornet+,hn 18(0x73716c372e686f),sn(),hints(known),family 0,flags 4
11-28 22:54:29.173 11995-11995/uk.co.matprichardson.omgandroid D/libc: [NET] android_getaddrinfofornet-, err=8
11-28 22:54:29.173 11995-11995/uk.co.matprichardson.omgandroid E/MYAPP: exception android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1155)
    at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
    at java.net.InetAddress.getAllByName(InetAddress.java:215)
    at java.net.Socket.tryAllAddresses(Socket.java:109)
    at java.net.Socket.<init>(Socket.java:178)
    at java.net.Socket.<init>(Socket.java:150)
    at net.sourceforge.jtds.jdbc.SharedSocket.<init>(SharedSocket.java:259)
    at net.sourceforge.jtds.jdbc.ConnectionJDBC2.<init>(ConnectionJDBC2.java:311)
    at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:187)
    at java.sql.DriverManager.getConnection(DriverManager.java:179)
    at java.sql.DriverManager.getConnection(DriverManager.java:144)
    at uk.co.matprichardson.omgandroid.MainActivity.onClick(MainActivity.java:114)
    at android.view.View.performClick(View.java:4785)
    at android.view.View$PerformClick.run(View.java:19869)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:155)
    at android.app.ActivityThread.main(ActivityThread.java:5721)
    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:1029)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
Tiny
  • 27,221
  • 105
  • 339
  • 599
Mat Richardson
  • 3,576
  • 4
  • 31
  • 56

3 Answers3

5

This is not entirely right.

catch (Exception e)
{
    Log.w("Error connection","" + e.getMessage());
}
11-26 20:49:14.662 5445-5445/uk.co.matprichardson.omgandroid W/Error connection: null

As usual, the answer is in the full stack trace, not in only the exception message. You're basically suppressing the whole exception including its stack trace and only logging the sole exception message. This is really unhelpful (not only for us in order to translate it into layman's terms in case you didn't understand it, but also for yourself in order to research/google it).

In case you have no idea how to print the full stack trace in Android, head to among others the following Q&A: Android - print full exception backtrace to log.

Once having the full stack trace at hands which should look like below:

android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1155)
    at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
    at java.net.InetAddress.getAllByName(InetAddress.java:215)
    at java.net.Socket.tryAllAddresses(Socket.java:109)
    at java.net.Socket.<init>(Socket.java:178)
    at java.net.Socket.<init>(Socket.java:150)
    at net.sourceforge.jtds.jdbc.SharedSocket.<init>(SharedSocket.java:259)
    at net.sourceforge.jtds.jdbc.ConnectionJDBC2.<init>(ConnectionJDBC2.java:311)
    at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:187)
    at java.sql.DriverManager.getConnection(DriverManager.java:179)
    at java.sql.DriverManager.getConnection(DriverManager.java:144)
    at uk.co.matprichardson.omgandroid.MainActivity.onClick(MainActivity.java:114)
    at android.view.View.performClick(View.java:4785)
    at android.view.View$PerformClick.run(View.java:19869)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:155)
    at android.app.ActivityThread.main(ActivityThread.java:5721)
    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:1029)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)

Then simply copypaste the exception type, message (if any) and 1st line of stack trace (without the parentheses and line number), like below,

android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork

Into a decent search engine for clues, like Google. As of now, the top hits directly or indirectly (duplicate) refer the below Stack Overflow questions:

Surely one of them must have explained/answered your concrete problem.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
1

EDIT:

You may need to use an older version of jtds. Does this post help.

Community
  • 1
  • 1
user1438150
  • 165
  • 1
  • 12
  • I'm connecting to an SQL Server database, not mysql. – Mat Richardson Nov 26 '15 at 20:52
  • Is jTDS JDBC not good enough for this? Sorry if this is a stupid question just thought I already had the right jar file for the project.. – Mat Richardson Nov 26 '15 at 21:00
  • Just tried this - didn't work, but for some reason I wasn't sure why just adding a different .jar file to a folder would... – Mat Richardson Nov 26 '15 at 21:05
  • I've just replaced with the older version but this hasn't made any difference. Thought I'd fixed it myself earlier but I was very wrong. – Mat Richardson Nov 26 '15 at 21:41
  • Can you try to clean your project and rebuild+sync? Also could you paste the entire error message – user1438150 Nov 26 '15 at 21:44
  • There isn't an error message when using the app. I can click the button and everything seems to work fine. It's just that the database doesn't update as I would expect when the sp is called. The only error messages I see are those detailed in my original post. – Mat Richardson Nov 26 '15 at 21:46
  • Also why are you connecting to SQL Server from a front end? There are a number of security concerns with this approach. Normally people will use a REST API for this kind of stuff. – user1438150 Nov 26 '15 at 21:48
  • If you're sticking with the db adapter approach then you should have your code in a AsyncTask – user1438150 Nov 26 '15 at 21:49
  • I know its not the best idea to connect directly to a database, but this app is literally just for me to use (at the moment) so I don't want to overcomplicate things. At this stage I simply want to connect to my DB and run a stored procedure. Nothing more or less than that really. – Mat Richardson Nov 26 '15 at 21:53
1

Androids Strict mode is explained here.

R Sawant
  • 241
  • 1
  • 8