简体   繁体   中英

Error connecting Android Studio app to remote MySQL: java.sql.SQLNonTransientConnectionException: Could not create connection to database server

I'm trying to connect an Android Studio app to a remote MYSQL database but an error is displaying that couldn't create a connection to the database.

Some troubleshooting I did:

  1. Reviewed if the database is running (it is)
  2. Connected from MySQL workbench in my computer to the remote database (I was able to connect and retrieve data)
  3. Also I was developing another app (no Android Studio). I used the same connection classes and I was able to access the data.

--- With this, I think that is not a server issue. ---

  1. Used different JDBC drivers (Gradle implementation below of the versions I used)
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.22'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.23'
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.13'
  1. I also tried to add the.jar file in the project files but had other errors that didn't recognized the driver.

--- With this, I noticed that implementing the driver in Gradle is not an error as apparently it is recognizing the driver --- Note: I'm currently using the gradle implementation.

  1. I added the internet permissions to the AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
  1. I tried to implement the code that retrieves the data from the data base using an ASYNCTASK but received the following errors

Main class WITH ASYNCTASK (MainActivity.java) * Note: The code in this class was just to test if I was able to get the data from the database. Is not regarding to any functionality I was trying to implement in the app itself.

public class MainActivity extends AppCompatActivity {

    AlertDialog.Builder builder;

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

        Button button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                
                builder = new AlertDialog.Builder(MainActivity.this);

                builder.setTitle("Data");
                new GetCultivos().execute();
                builder.setPositiveButton("Accept", null);

                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });

    class GetCultivos extends AsyncTask<Void, Void, Void>{

        String list = "Data = ";

        @Override
        protected Void doInBackground(Void... voids) {

            CultivoDao cultivoDao = new CultivoDao();
            List<Cultivo> listaCultivos = cultivoDao.obtenerCultivos();
            for (Cultivo i : listaCultivos){
                list = i.getIdCultivo() + " " + i.getNombre() + ", ";
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void eVoid){
            builder.setMessage(list);
        }
    }
}
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
    Process: com.example.appmov, PID: 5699
    java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.os.AsyncTask$4.done(AsyncTask.java:399)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)
     Caused by: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/sql/SQLType;
        at com.mysql.cj.jdbc.DatabaseMetaData.getInstance(DatabaseMetaData.java:729)
        at com.mysql.cj.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:1180)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:446)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
        at java.sql.DriverManager.getConnection(DriverManager.java:580)
        at java.sql.DriverManager.getConnection(DriverManager.java:218)
        at com.DAO.appmov.CultivoDao.StartConnection(CultivoDao.java:30)
        at com.DAO.appmov.CultivoDao.obtenerCultivos(CultivoDao.java:49)
        at com.example.appmov.MainActivity$GetCultivos.doInBackground(MainActivity.java:228)
        at com.example.appmov.MainActivity$GetCultivos.doInBackground(MainActivity.java:220)
        at android.os.AsyncTask$3.call(AsyncTask.java:378)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:919) 
     Caused by: java.lang.ClassNotFoundException: Didn't find class "java.sql.SQLType" on path: DexPathList[[zip file "/data/app/com.example.appmov-U33MrmDYU8kMl3MFpFCdcA==/base.apk"],nativeLibraryDirectories=[/data/app/com.example.appmov-U33MrmDYU8kMl3MFpFCdcA==/lib/arm64, /system/lib64]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
        at com.mysql.cj.jdbc.DatabaseMetaData.getInstance(DatabaseMetaData.java:729) 
        at com.mysql.cj.jdbc.ConnectionImpl.getMetaData(ConnectionImpl.java:1180) 
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:446) 
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240) 
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207) 
        at java.sql.DriverManager.getConnection(DriverManager.java:580) 
        at java.sql.DriverManager.getConnection(DriverManager.java:218) 
        at com.DAO.appmov.CultivoDao.StartConnection(CultivoDao.java:30) 
        at com.DAO.appmov.CultivoDao.obtenerCultivos(CultivoDao.java:49) 
        at com.example.appmov.MainActivity$GetCultivos.doInBackground(MainActivity.java:228) 
        at com.example.appmov.MainActivity$GetCultivos.doInBackground(MainActivity.java:220) 
        at android.os.AsyncTask$3.call(AsyncTask.java:378) 
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:919) 
I/Process: Sending signal. PID: 5699 SIG: 9
  1. So I tried to implement the code without an ASYNCTASK, but I'm receiving the error that you can see below in the error log.

Class I use to connect to the database (CultivoDao.java)

public class CultivoDao {

    private Connection connection;
    private Statement statement;

    //Method to start the connection
    private void StartConnection() {

        String url = "jdbc:mysql://remotemysql.com:3306/hUfMa4wLpe";
        String usuario = ***HERE IS THE USERNAME***;
        String password = ***HERE IS THE PASSWORD***;


        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection(url, usuario, password);
            statement = connection.createStatement();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //Method to close the connection
    private void CloseConnection(){
        try {
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //Methog to get the data
    public List<Cultivo> obtenerCultivos(){
        List<Cultivo> listaCultivos = new ArrayList<>();
        try {
            StartConnection();
            ResultSet rs = statement.executeQuery("Select * from cultivo");
            while(rs.next()){
                Cultivo cultivo = new Cultivo(rs.getInt("idCultivo"), rs.getString("nombre"));
                listaCultivos.add(cultivo);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        CloseConnection();
        return listaCultivos;
    }
}

Main class WITHOUT ASYNCTASK (MainActivity.java) * Note: The code in this class was just to test if I was able to get the data from the database. Is not regarding to any functionality I was trying to implement in the app itself.

public class MainActivity extends AppCompatActivity {

    AlertDialog.Builder builder;

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

        Button button = findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                
                builder = new AlertDialog.Builder(MainActivity.this);
                
                String list = "Database list = ";

                CultivoDao cultivoDao = new CultivoDao();
                List<Cultivo> listaCultivos = cultivoDao.obtenerCultivos();
                for (Cultivo i : listaCultivos){
                    list = i.getIdCultivo() + " " + i.getNombre() + ", ";
                }

                builder.setTitle("Data");
                builder.setMessage(list);
                builder.setPositiveButton("Accept", null);

                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });
    }
}

The actual version I'm using is the one without the ASYNCTASK

I'm testing this app in a physical device. I don't know that this can affect in some way.

Error log:

W/System.err: java.sql.SQLNonTransientConnectionException: Could not create connection to database server.
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
W/System.err:     at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:1008)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:825)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:455)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:240)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:207)
        at java.sql.DriverManager.getConnection(DriverManager.java:580)
        at java.sql.DriverManager.getConnection(DriverManager.java:218)
        at com.DAO.appmov.CultivoDao.StartConnection(CultivoDao.java:30)
        at com.DAO.appmov.CultivoDao.obtenerCultivos(CultivoDao.java:49)
        at com.example.appmov.MainActivity$1.onClick(MainActivity.java:88)
        at android.view.View.performClick(View.java:7870)
        at android.widget.TextView.performClick(TextView.java:14970)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
        at android.view.View.performClickInternal(View.java:7839)
        at android.view.View.access$3600(View.java:886)
        at android.view.View$PerformClick.run(View.java:29363)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7814)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068)
W/System.err: Caused by: android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1565)
        at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115)
        at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
        at java.net.InetAddress.getAllByName(InetAddress.java:1152)
        at com.mysql.cj.protocol.StandardSocketFactory.connect(StandardSocketFactory.java:132)
        at com.mysql.cj.protocol.a.NativeSocketConnection.connect(NativeSocketConnection.java:65)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:152)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:955)
        ... 22 more
    java.lang.NullPointerException: Attempt to invoke interface method 'java.sql.ResultSet java.sql.Statement.executeQuery(java.lang.String)' on a null object reference
        at com.DAO.appmov.CultivoDao.obtenerCultivos(CultivoDao.java:50)
        at com.example.appmov.MainActivity$1.onClick(MainActivity.java:88)
        at android.view.View.performClick(View.java:7870)
        at android.widget.TextView.performClick(TextView.java:14970)
W/System.err:     at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
        at android.view.View.performClickInternal(View.java:7839)
        at android.view.View.access$3600(View.java:886)
        at android.view.View$PerformClick.run(View.java:29363)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7814)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068)
    java.lang.NullPointerException: Attempt to invoke interface method 'void java.sql.Connection.close()' on a null object reference
        at com.DAO.appmov.CultivoDao.CloseConnection(CultivoDao.java:40)
        at com.DAO.appmov.CultivoDao.obtenerCultivos(CultivoDao.java:58)
        at com.example.appmov.MainActivity$1.onClick(MainActivity.java:88)
        at android.view.View.performClick(View.java:7870)
        at android.widget.TextView.performClick(TextView.java:14970)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:967)
        at android.view.View.performClickInternal(View.java:7839)
        at android.view.View.access$3600(View.java:886)
        at android.view.View$PerformClick.run(View.java:29363)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:237)
        at android.app.ActivityThread.main(ActivityThread.java:7814)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1068) 

How can I solve this issue without implementing PHP that is another way I found as I can't edit anything of the server where the database is hosted.

Thanks!

ClassNotFoundException: Didn't find class "java.sql.SQLType"

Since java.sql.SQLType was added in Java 8, and doesn't exist at all on Android, you need to use a JDBC driver that is Java 7 compatible, which means you cannot use Connector/J 8.0, but must use version 5.1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM