【问题标题】:Connect Android App to Bluemix db2 database using JDBC (NoClassDefFoundError:)使用 JDBC 将 Android 应用程序连接到 Bluemix db2 数据库 (NoClassDefFoundError:)
【发布时间】:2023-03-28 06:06:01
【问题描述】:

首先:我有一些 Java 经验,但这是我第一次创建 Android 应用程序。 我正在使用 Bluemix IoT-Foundation-Service 并获得了 Bluemix-DB2-SQL-Database。 (我的 RasPi2 正在收集一些传感器数据,通过 MQTT 发布它们,并在 bluemix 上运行的应用程序订阅这些数据,并将它们存储到 DB2-Database 中)。

现在我想编写一个 Android 应用程序,它连接到我的数据库并执行一些数据库操作。我从一个简单的应用程序开始。只是一个在我的 DB2-TodoList-Table 上添加内容的按钮。

代码:

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.sql.*;
public class MainActivity extends AppCompatActivity {

static Connection       con;
static Statement        stmt;
static Statement        stmt1;
static DatabaseMetaData dmd;


private static String user = "user*****";
private static String password = "L***********";
private static String url = "jdbc:db2://*.**.*****:50001/SQLDB";


public void connect(){
    java.util.Properties properties = new java.util.Properties();

    properties.put("user", user);
    properties.put("password", password);
    properties.put("sslConnection", "true");

    try {
        Class.forName("com.ibm.db2.jcc.DB2Driver");
    con = DriverManager.getConnection(url, properties);
    stmt = con.createStatement();

    } catch (ClassNotFoundException e) {
       // e.printStackTrace();
    } catch (SQLException e) {
      //  e.printStackTrace();
    }
}
public void close() throws SQLException, ClassNotFoundException{
    stmt.close();
    con.close();
}

public static void addSomethingToMyToDoList(int ID, String something) throws SQLException{
    if(con != null)
        stmt.executeUpdate("INSERT INTO TODOLIST VALUES (" + ID + " , '" + something +"')");
    con.commit();
}

public void addSomethingToDatabase(View v){
    connect();
    int sampleID = 1233;
    try {
        addSomethingToMyToDoList(sampleID, "testTest");
         close();
    } catch (SQLException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

我将 db2jcc.jar 拖放到 /app/libs 文件夹中并右键单击 + 添加为库

我使用 Android Studio

我了解到 db2jcc.jar 不适用于 jdk 1.8,这就是我安装 jdk 1.7 的原因(Did File->Project Structure -> SDK Location -> 将 JDK 位置更改为我的 jdk1.7.0 目录)

build.gradle 文件包含:

defaultConfig {
    [...]
    multiDexEnabled true
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile files('libs/db2jcc.jar')
testCompile 'junit:junit:4.12'
compile 'com.android.support:design:23.1.1'
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:appcompat-v7:23.1.1'
}

当我运行我的应用程序(在 AVD 上)并单击按钮时,我的应用程序崩溃并收到以下消息:

Caused by: java.lang.NoClassDefFoundError: com.ibm.db2.jcc.DB2SimpleDataSource

完整的错误日志:

致命异常:主要 进程:com.example.egebert.datanbank,PID:7125 java.lang.IllegalStateException:无法执行方法 安卓:点击 在 android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:275) 在 android.view.View.performClick(View.java:5198) 在 android.view.View$PerformClick.run(View.java:21147) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 引起:java.lang.reflect.InvocationTargetException 在 java.lang.reflect.Method.invoke(本机方法) 在 android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:270) 在 android.view.View.performClick(View.java:5198) 在 android.view.View$PerformClick.run(View.java:21147) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 引起:java.lang.NoClassDefFoundError: com.ibm.db2.jcc.DB2SimpleDataSource 在 java.lang.Class.classForName(本机方法) 在 java.lang.Class.forName(Class.java:324) 在 java.lang.Class.forName(Class.java:285) 在 com.ibm.db2.jcc.am.GlobalProperties.d(未知来源) 在 com.ibm.db2.jcc.am.GlobalProperties.a(未知来源) 在 com.ibm.db2.jcc.am.GlobalProperties.c(未知来源) 在 com.ibm.db2.jcc.am.GlobalProperties.a(未知来源) 在 com.ibm.db2.jcc.am.hb.j(未知来源) 在 com.ibm.db2.jcc.am.hb.(未知来源) 在 java.lang.Class.classForName(本机方法) 在 java.lang.Class.forName(Class.java:324) 在 java.lang.Class.forName(Class.java:285) 在 com.ibm.db2.jcc.DB2BaseDataSource.class$(未知来源) 在 com.ibm.db2.jcc.DB2BaseDataSource.(未知来源) 在 java.lang.Class.classForName(本机方法) 在 java.lang.Class.forName(Class.java:324) 在 java.lang.Class.forName(Class.java:285) 在 com.ibm.db2.jcc.DB2Driver.class$(未知来源) 在 com.ibm.db2.jcc.DB2Driver.(未知来源) 在 java.lang.Class.classForName(本机方法) 在 java.lang.Class.forName(Class.java:324) 在 java.lang.Class.forName(Class.java:285) 在 com.example.egebert.datanbank.MainActivity.connect(MainActivity.java:40) 在 com.example.egebert.datanbank.MainActivity.addSomethingToDatabase(MainActivity.java:78) 在 java.lang.reflect.Method.invoke(本机方法) 在 android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:270) 在 android.view.View.performClick(View.java:5198) 在 android.view.View$PerformClick.run(View.java:21147) 在 android.os.Handler.handleCallback(Handler.java:739) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:5417) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我试过了

Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();

而不是

Class.forName("com.ibm.db2.jcc.DB2Driver");

也是。

有没有办法让 JDBC-db2Driver 在 Android 上工作? 刚刚发现Thisstackoverflow 问题告诉我,您无法使用 android 连接到 bluemix-db2-server。这是正确的吗?或者有没有办法修复 NoClassDefFoundError?

谢谢你

【问题讨论】:

    标签: android jdbc db2 ibm-cloud iot


    【解决方案1】:

    错误很明显,您的应用程序找不到 db2 模块。检查您是否将这些模块正确导入到您的应用程序库中,以及添加到 lib 中的驱动程序是否提供了您用于数据源的类。

    无论如何,出于以下几个原因,我会避免让您的应用程序直接连接到外部数据库:

    • 数据库连接通常是有限的,为每个应用程序实例使用它们会使数据库实例很快失去可用连接,尤其是在数据库交互不是很短并且连接没有正确释放的情况下
    • 便携式设备的网络连接不稳定,您可能会在运行数据库操作时失去连接

    通常更好的解决方案应该是添加一个集成层(如 Web 服务),管理包括数据库连接在内的所有数据库交互,并为应用程序集成公开一些端点。

    【讨论】:

    • 首先.. 谢谢.. 好吧我仍然不知道如何解决这个问题,但是您对网络服务的建议使这有点无关紧要。我认为 jdbc 将是进行 db-operations 的第二种方式。因为我希望有相当多的设备与这个数据库通信,所以我期待获得一些 web 服务技能.. html 和 javascript 会是一些关键字吗? ...
    • 不是严格要求您可以使用 Spring(Java 上)或 CakePHP/Zend/Laravel(PHP 上)等框架或多个 MVC 之一开发一个 RESTful Web 服务,该服务类似于您的数据库实例的接口使用 Javascript 可用于 nodejs (nodeframework.com) 的框架您可以使用可用的运行时直接在 Bluemix 上运行此 Web 服务,因此您可以利用 Bluemix 上可用的运行时和 SQLDB 服务之间的集成
    • 谢谢,这对我帮助很大。我刚刚研究了 Strongloop,认为这对我的情况可能非常有用。我会将它与 Spring 和 CakePHP 进行比较。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多