0

I get the following errors when trying to connect mySQL DB to Android via JDBC:

2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err: The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
2020-06-28 21:08:57.969 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at java.sql.DriverManager.getConnection(DriverManager.java:580)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at java.sql.DriverManager.getConnection(DriverManager.java:218)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at com.example.mmi.DBUtility.connect(DBUtility.java:14)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at com.example.mmi.MainActivity.checkUser(MainActivity.java:99)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at com.example.mmi.MainActivity$2.onClick(MainActivity.java:49)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at android.view.View.performClick(View.java:7125)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at android.view.View.performClickInternal(View.java:7102)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at android.view.View.access$3500(View.java:801)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at android.view.View$PerformClick.run(View.java:27336)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at android.os.Handler.handleCallback(Handler.java:883)
2020-06-28 21:08:57.970 31747-31747/com.example.mmi W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:100)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err:     at android.os.Looper.loop(Looper.java:214)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7356)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
2020-06-28 21:08:57.971 31747-31747/com.example.mmi W/System.err: The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at java.lang.reflect.Constructor.newInstance0(Native Method)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:105)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:151)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.exceptions.ExceptionFactory.createCommunicationsException(ExceptionFactory.java:167)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:91)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.NativeSession.connect(NativeSession.java:144)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err:   ... 19 more
2020-06-28 21:08:57.972 31747-31747/com.example.mmi W/System.err: Caused by: java.net.SocketException: socket failed: EPERM (Operation not permitted)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:     at java.net.Socket.createImpl(Socket.java:492)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:     at java.net.Socket.getImpl(Socket.java:552)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:     at java.net.Socket.setTcpNoDelay(Socket.java:1012)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.protocol.StandardSocketFactory.configureSocket(StandardSocketFactory.java:94)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:147)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:     at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
2020-06-28 21:08:57.973 31747-31747/com.example.mmi W/System.err:   ... 22 more
2020-06-28 21:08:58.015 31747-31788/com.example.mmi D/EGL_emulation: eglMakeCurrent: 0xe2da9260: ver 3 0 (tinfo 0xe2d99b40)
2020-06-28 21:08:58.026 31747-31788/com.example.mmi D/EGL_emulation: eglMakeCurrent: 0xe2da9260: ver 3 0 (tinfo 0xe2d99b40)

Here is my code:

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtility
{
    public static Connection connect() throws IOException, ClassNotFoundException, SQLException {
        Connection con =null;

            Class.forName("com.mysql.cj.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://192.168.1.202:3306/mmi?useSSL=false", "username", "password");

        return con;
    }
}

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class MainActivity extends AppCompatActivity {

    EditText mTextUsername;
    EditText mTextPassword;
    Button mButtonLogin;
    TextView mTextViewForgot;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTextUsername = (EditText) findViewById(R.id.edittext_username);
        mTextPassword = (EditText) findViewById(R.id.edittext_password);
        mButtonLogin = (Button) findViewById(R.id.button_login);
        mTextViewForgot = (TextView) findViewById(R.id.textview_forgot);
        mTextViewForgot.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                Intent forgotIntent = new Intent (MainActivity.this,ForgotActivity.class);
                startActivity(forgotIntent);
            }
        });

        mButtonLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {

                String user = mTextUsername.getText().toString().trim();
                String pwd = mTextPassword.getText().toString().trim();

                boolean res = checkUser(user, pwd);
                if (res)
                {
                    Toast.makeText(MainActivity.this, "Successfully Logged In", Toast.LENGTH_SHORT).show();
                }
                else
                {
                    Toast.makeText(MainActivity.this, "Login Error", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    public boolean checkUser(String user, String pass)
    {
        boolean statement = false;
        try {
            Connection con = DBUtility.connect();
            Statement st = con.createStatement();
            statement = true;
            ResultSet rs = st.executeQuery("SELECT * FROM mmi_userinfo where USERNAME='"+ user + "' and USER PASSWORD='" + pass + "'");

            if (rs.next()) {
                statement = true;
            }

        }catch (Exception e)
        {
            e.printStackTrace();
        }
        return statement;
    }
}

I've confirmed my DB is running, I've flushed my DNS, I changed the my.cnf file to bind-address appropriately, and I removed the skip-networking line.

I am not sure what is preventing this from working, any help would be appreciated.

Mike
  • 7
  • 5
  • Your connection URL points to "localhost" 127.0.0.1. Are you really running MySQL on an Android device like your connection URL suggests? That seems unusual – Joni Jun 29 '20 at 02:30
  • I am running the DB off my computer and the android device is an emulator on that same PC. Should I update the bindaddress to reflect my computers IP address, and update the code accordingly? – Mike Jun 29 '20 at 02:38
  • I just tried what I mentioned above, updated the my.cnf file to my local IP address, and changed the code to that as well, still getting the same errors. – Mike Jun 29 '20 at 02:42
  • Can you post a minimal example of how you're using this? Looking at the stack trace it looks like you're calling this method from the main thread... but you can't call networking methods from the main thread, you'll get an error immediately – Joni Jun 29 '20 at 03:03
  • Sure, I will add the rest of the code to my initial question. – Mike Jun 29 '20 at 03:07
  • Can you try uninstalling the app from emulator and run it again? Also, try running your java using the option `Djava.net.preferIPv4Stack=true` – Govind Jun 29 '20 at 05:20
  • Where do I go to set Djava.net.preferIPv4Stack=true ? – Mike Jun 29 '20 at 06:15

2 Answers2

0

You have to get the actual IP address of the computer you are connecting to. 127.0.0.1 refers to localhost (in your case, your android phone or emulator), which is a wrong destination.Have a look at the question that was answered available here

Kasalwe
  • 358
  • 2
  • 6
0

If you look closely at the error stack trace, towards the end you see what caused it:

Caused by: java.net.SocketException: socket failed: EPERM (Operation not permitted)

This means the app is missing the necessary permissions for making network connections: see https://developer.android.com/training/basics/network-ops/connecting

You have to add these to the app manifest:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

After you do that, you should start seeing a different error, this time caused by NetworkOnMainThreadException because you are trying to connect to a network resource on the application main thread. There are several ways to solve that and the recommended way changes as new technology is developed. The developer guide should always have the latest information: https://developer.android.com/guide/background/threading

The current recommendation seems to be to use ViewModel and MutableLiveData from the Android Architecture components. You submit the networked operation to a thread pool (instance of ExecutorService) and have it update the MutableLiveData when it finishes.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • Thank you! This corrected my error and now I have moved on to a "java.sql.SQLNonTransientConnectionException: Could not create connection to database server." "caused by android.os.NetworkOnMainThreadException." I will follow your recommendation to solve that issue. – Mike Jun 29 '20 at 14:40