【问题标题】:How can I set up a simple gradle project that uses sqlite4java?如何设置一个使用 sqlite4java 的简单 gradle 项目?
【发布时间】:2015-09-02 23:58:44
【问题描述】:

我正在使用 sqlite4java 开始一个简单的 java 测试项目并使用 java 构建。

我可以轻松下载核心 sqlite4java 库,但我不确定让 gradle 下载本机库并将它们放在正确位置的最佳(任何!)方法。

这是我的 build.gradle 文件:

apply plugin: 'java'

/* We use Java 1.7 */
sourceCompatibility = 1.7
targetCompatibility = 1.7
version = '1.0'

repositories {
    mavenCentral()
}

sourceSets {
    main {
        java.srcDir 'src'
        output.classesDir = 'build/main'
    }
    test {
        java.srcDir 'test'
        output.classesDir = 'build/test'
    }
}


dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile "com.almworks.sqlite4java:sqlite4java:1.0.392"
    compile "com.almworks.sqlite4java:libsqlite4java-osx:1.0.392"
}

但是当我运行一个简单的测试时,我得到:

TestTest > testSqlite4Basic FAILED
    com.almworks.sqlite4java.SQLiteException at TestTest.java:15
        Caused by: java.lang.UnsatisfiedLinkError at TestTest.java:15

(我在 IntelliJ 中构建,但正在使用 gradle 构建选项 - 所以我不认为 ItelliJ 在运行测试时填充了类路径......)

我很确定我第一次尝试构建时收到了一些关于无法解压缩 libsqlite4java-osx ZIP 文件的消息(并不奇怪,因为 maven Central 说它是一个 dylib 文件)。

我需要做什么才能让 gradle 做正确的事?

ASIDE:我可以通过手动将下载的 .dylib 从 maven 缓存复制到我的 java.library.path 中列出的某个位置来运行代码(我认为我使用了 $HOME/Library/Java/Extensions on我的苹果电脑)。但这似乎与将所有设置和依赖项打包在 .gradle 文件中的全部意义相悖,并且不会让我以后轻松分发任何东西。

【问题讨论】:

标签: java gradle sqlite4java


【解决方案1】:

我想,您需要使用额外的 gradle 插件来处理原生库或制作自己的特定任务,上传原生库并将其放置在正确的位置,以便可以找到和链接它们。

目前我只知道一个这样的插件,希望它能解决你的问题https://github.com/cjstehno/gradle-natives

编辑: 在您的情况下,插件的问题在于,您的依赖“com.almworks.sqlite4java:libsqlite4java-osx:1.0.392”本身就是本机库,而不是我认为的包含本机库的 jar。因此,在这种情况下,您可以简单地将此依赖项添加到构建脚本的依赖项部分中,因为它已经完成,然后创建一个自定义复制任务,将其放在您需要的任何地方。尝试在 Win7 上使用 gradle 2.6 来做,看起来像:

task copyNtiveDeps(type: Copy) {
  from (configurations.compile+configurations.testCompile) {
    include "libsqlite4java-osx-1.0.392.dylib"
  }
  into "c:\\tmp"
}

在您的情况下,您只需将“into”属性设置为 java.library.path 中的某个路径。其次,您可以使用 gradle 任务属性 dependsOn 和 mustRunAfter 使此任务自动运行。

【讨论】:

  • 看起来该插件实际上并没有从 maven 中提取库,它要求它们已经安装并在您的类路径中。您还需要下载并构建插件并将其放入本地 maven 缓存中 - 对于这样一个简单的任务来说似乎需要做很多工作。
  • 我找到了原因,为什么插件不是你的决定,所以我对我的答案进行了一些更改。您可以简单地将任何 Maven 依赖项手动复制到您需要的任何路径。
  • 插件本身。它不提取任何依赖项,它应该以通常的 gradle 方式完成,它只是从这些依赖项中提取本机库。并且不需要做任何额外的工作来使这个插件在 gradle 中工作,只需添加一个 buildscript 依赖项并应用它
  • 您的回答最终使我得到了我需要的解决方案(作为附加答案添加...)但是在您修改答案之前我取消了之前的 +100 赏金...所以 +200 来了24 小时内为您服务。
  • 很高兴您找到了解决方案并提前致谢
【解决方案2】:

这是基于 Stanislav 的 cmets 的完整答案。

apply plugin: 'java'

/* We use Java 1.8 */
sourceCompatibility = 1.8
targetCompatibility = 1.8
version = '1.0'

repositories { mavenCentral() }

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile "com.almworks.sqlite4java:sqlite4java:1.0.392"
    compile "com.almworks.sqlite4java:libsqlite4java-osx:1.0.392"
}

sourceSets {
    main {
        java.srcDir 'src'
        output.classesDir = 'build/main'
    }
    test {
        java.srcDir 'test'
        output.classesDir = 'build/test'
    }
}

/* Copy the native files */
task copyNativeDeps(type: Copy) {
    from (configurations.compile+configurations.testCompile) {
        include "*.dylib"
    }
    into 'build/libs'
}

/* Make sure we setup the tests to actually copy 
 * the native files and set the paths correctly. */
test {
    dependsOn copyNativeDeps
    systemProperty "java.library.path", 'build/libs'
}

以及为其运行的示例测试源:

import com.almworks.sqlite4java.SQLiteConnection;
import com.almworks.sqlite4java.SQLiteStatement;
import org.junit.Test;

import java.io.File;

public class SqliteTest {

    @Test public void aTest() throws Exception {
        SQLiteConnection db = new SQLiteConnection(new File("/tmp/database"));
        db.open(true);  

        SQLiteStatement st = db.prepare("SELECT name FROM dummy");
        try {
            while(st.step()) {
                System.err.printf("name = %s\n", st.columnString(1));
            }
        } finally {
            st.dispose();
        }
    }
}

【讨论】:

    【解决方案3】:

    我用这个方法在anroid studio 3.1.4中设置了sqlite4java。

    首先从这个链接下载库: https://bitbucket.org/almworks/sqlite4java

    下载将包含一个 zip 文件,其中包含一个名为 android 的文件夹以及其他 .jar 、 .so 和 .dll 文件。

    将android中的“armeabi”、“armeabi-v7a”和“x86”三个文件夹复制到名为“jniLibs”的文件夹中。

    将上述文件夹(即“jniLibs”)复制到您的项目/app/src/main/ 文件夹中。

    然后实现java4sqlite的gradle依赖:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 26
        defaultConfig {
            applicationId "your.project.name"
            minSdkVersion 15
            targetSdkVersion 26
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
    
    
    
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:26.1.0'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        implementation 'com.android.support:design:26.1.0'
        implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:2.0.1'
        implementation "com.almworks.sqlite4java:sqlite4java:1.0.392"
        implementation "com.almworks.sqlite4java:libsqlite4java-osx:1.0.392"
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    
    
    }
    

    【讨论】:

    • 查看我的回答 stackoverflow.com/a/54977264/8034839 了解如何编译自己的 sqlite3 库。
    • 您能否解释一下您是如何在以下代码中在 build.gradle 中添加路径的: jniLibs.srcDirs += ['/your-libs'] 此代码是否会添加图书馆自动?否则我仍然必须复制文件夹。
    • 是的,它将指向您的 libs 目录。详细检查我的答案
    【解决方案4】:

    要编译自己的sqlite3库,可以查看github android-sqlite3

    对于当前的 Android Studio (3.3.1),您只需在 app/build.gradle 中添加 .so 文件,如下所示:

    android {
        ...
    
        sourceSets {
            main {
                jniLibs.srcDirs += ['<your-path>/your-libs']
            }
        }
    
        ...
    }
    
    

    说明

    jniLibs.srcDirs 是指向 jni 库的 gradle 路径,操作符 += 表示除了里面的默认库之外的附加 jni 库app/src/main/jniLibs如下:

    app/
    ├──libs/
    |  └── *.jar           <-- java libs
    ├──src/
       └── main/
           ├── AndroidManifest.xml
           ├── java/
           └── jniLibs/    <-- default directory for jni libs, i.e. <ANDROID_ABI>/**.so
    

    请注意,jni 库必须根据 android ABI 组织,即

    your-libs/
    ├── arm64-v8a/                       <-- ARM 64bit
    │   └── lib-your-abc.so
    ├── armeabi-v7a/                     <-- ARM 32bit
    │   └── lib-your-abc.so
    ├── x86_64/                          <-- Intel 64bit
    │   └── lib-your-abc.so
    └── x86/                             <-- Intel 32bit
        └── lib-your-abc.so
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      • 2011-10-23
      • 2016-07-13
      • 2011-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多