2012-08-30 115 views
5

我目前正在尝试使用maven和sqlite4java来构建我的项目。官方的maven仓库中有这个功能。 官方sqlite4java page on google code确实有一个示例配置,但它有点过时,并不适合我的需要。我想最终有一个.jar文件,我可以在其他地方部署。这里的问题是共享对象的依赖性。我现在用的是官方的构建目标,从他们的网页复制这样的build.dir/lib目录,但与我的组装目标崩溃:在maven程序集中包含共享对象

[INFO] Failed to create assembly: Error adding file-set for 'com.almworks.sqlite4java:libsqlite4java-linux-i386:so:0.282' to archive: Error adding archived file-set. PlexusIoResourceCollection not found for: /home/lhw/.m2/repository/com/almworks/sqlite4java/libsqlite4java-linux-i386/0.282/libsqlite4java-linux-i386-0.282.so 
No such archiver: 'so'. 

我在做什么错?这是我从一些依赖剥夺当前的pom.xml无关这个话题

<?xml version="1.0"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>de.ring0.lhw</groupId> 
    <artifactId>system</artifactId> 
    <version>0.0.1-SNAPSHOT</version> 
    <dependencies> 
    <dependency> 
     <groupId>com.almworks.sqlite4java</groupId> 
     <artifactId>sqlite4java</artifactId> 
     <version>${sqlite4java.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>com.almworks.sqlite4java</groupId> 
     <artifactId>libsqlite4java-linux-i386</artifactId> 
     <version>${sqlite4java.version}</version> 
     <type>so</type> 
    </dependency> 
    </dependencies> 
    <properties> 
    <sqlite4java.version>0.282</sqlite4java.version> 
    </properties> 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-dependency-plugin</artifactId> 
     <executions> 
      <execution> 
      <id>copy</id> 
      <phase>compile</phase> 
      <goals> 
       <goal>copy</goal> 
      </goals> 
      <configuration> 
       <artifactItems> 
       <artifactItem> 
        <groupId>com.almworks.sqlite4java</groupId> 
        <artifactId>libsqlite4java-linux-i386</artifactId> 
        <version>${sqlite4java.version}</version> 
        <type>so</type> 
        <overWrite>true</overWrite> 
        <outputDirectory>${project.build.directory}/lib</outputDirectory> 
       </artifactItem> 
       </artifactItems> 
      </configuration> 
      </execution> 
     </executions> 
     </plugin> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-compiler-plugin</artifactId> 
     <version>2.5.1</version> 
     <configuration> 
      <source>1.6</source> 
      <target>1.6</target> 
     </configuration> 
     </plugin> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-surefire-plugin</artifactId> 
     <version>2.12.2</version> 
     <configuration> 
      <skipTests>true</skipTests> 
      <systemProperties> 
      <property> 
       <name>sqlite4java.library.path</name> 
       <value>${project.build.directory}/lib</value> 
      </property> 
      </systemProperties> 
     </configuration> 
     </plugin> 
     <plugin> 
     <artifactId>maven-assembly-plugin</artifactId> 
     <executions> 
      <execution> 
      <phase>package</phase> 
      <goals> 
       <goal>single</goal> 
      </goals> 
      <configuration> 
       <archive> 
       <manifest> 
        <mainClass>de.ring0.lhw.Init</mainClass> 
       </manifest> 
       </archive> 
       <descriptorRefs> 
       <descriptorRef>jar-with-dependencies</descriptorRef> 
       </descriptorRefs> 
      </configuration> 
      </execution> 
     </executions> 
     </plugin> 
    </plugins> 
    </build> 
</project> 

回答

1

编辑:

我认为JAR-与依赖性装配描述符试图解开依赖。

见链接:

http://maven.apache.org/plugins/maven-assembly-plugin/descriptor-refs.html

maven.apache.org/plugins/maven-assembly-plugin/... ...

<unpack>true</unpack> 

当然,它不能解压.so

所以你可能不得不使用自定义程序集来执行你想要做的事

+0

-rw-RW-R-- 1个LHW LHW 716K年08月30 12点23分的.m2 /库/ COM/almworks/sqlite4java/libsqlite4java-Linux的I386/0.282/libsqlite4java-linux-i386-0.282.so 是的,文件确实存在,并且在执行编译目标时被复制到target/lib。 – lhw

+0

你是如何在回购站安装/部署'so'的? mvn clean install:install-file? 你有这个安装的依赖关系吗?如果是,您是否将依赖关系的类型和打包设置为“so”? 您可以尝试使用 mvn clean install进行安装:install-file -Dpackaging = so –

+0

libsqlite4java-linux-i386是共享对象依赖关系,它的类型如您所见。它自动下载到本地存储库。如果你想自己尝试,sqlite4java可以在标准的maven仓库中使用。 – lhw

0

可以使用库存“jar-with-dependencies”程序集描述符创建可执行jar,而不使用任何启动shell /批处理脚本。但是,它需要不涉及太多Maven配置的肮脏的解决方法。

  1. 我们需要把所有的本地库(included in sqlite4java zip download)的src/main /资源目录。同时从你的Maven POM文件中删除sqlite4java本地库依赖项。
  2. 因为sqlite4java的本地库加载程序不会看你的类路径或JAR文件里,你必须提取本地库在启动,并在运行时集“sqlite4java.library.path”系统属性。请看下面的示例代码:

/** List of native libraries you put in src/main/resources */ 
public static final String[] NATIVE_LIB_FILENAMES = { 
    "libsqlite4java-linux-amd64.so", 
    "libsqlite4java-linux-i386.so", 
    "libsqlite4java-osx.jnilib", 
    "libsqlite4java-osx-10.4.jnilib", 
    "libsqlite4java-osx-ppc.jnilib", 
    "sqlite4java-win32-x64.dll", 
    "sqlite4java-win32-x86.dll", 
}; 

/** 
* Extract native libraries to the current directory. 
* This example needs Apache Commons IO (https://commons.apache.org/proper/commons-io/) 
*/ 
public static void extractNativeResources() { 
    for(String filename: NATIVE_LIB_FILENAMES) { 
     // Change "DemoSQLite2" to your class name 
     final InputStream in = DemoSQLite2.class.getResourceAsStream("/"+filename); 

     if(in != null) { 
      try { 
       System.out.println("Extracting " + filename); 
       FileUtils.copyInputStreamToFile(in, new File(filename)); 
      } catch (IOException e) { 
       System.err.println("Can't extract " + filename); 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

/** 
* Delete native libraries in the current directory 
*/ 
public static void removeNativeResources() { 
    for(String filename: NATIVE_LIB_FILENAMES) { 
     File file = new File(filename); 
     file.delete(); 
    } 
} 

public static void main(String[] args) throws Exception { 
    boolean deleteNativesOnExit = false; // Delete natives on exit 

    // Extract native libraries if sqlite4java.library.path property is not set 
    String sqlitePath = System.getProperty("sqlite4java.library.path"); 
    if(sqlitePath == null) { 
     System.setProperty("sqlite4java.library.path", "."); // Read natives from current directory 
     extractNativeResources(); 
     deleteNativesOnExit = true; 
    } 

    // Do SQLite jobs here 
    final SQLiteConnection db = new SQLiteConnection(new File("test.db")); 
    try { 
     db.open(); 
     db.dispose(); 
     System.out.println("Success"); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     System.err.println("FAILED"); 
    } 

    // Delete the native libraries we extracted 
    if(deleteNativesOnExit) removeNativeResources(); 
} 

现在您的应用程序应该是可建标准“罐子与 - 依赖”的描述符,并且您的应用程序可运行与标准的“Java的罐子your_jar.jar”命令。

当然,如果sqlite4java将来得到更新,您必须手动更新资源目录中的本地库。

如果你有一个更好的,不太脏的解决方案,请让我知道!

+0

如果你投了票,请给我一个更好的解决方案和/或你的想法,所以我可以修改这个帖子。 – NullNoname