在maven程序集中包含共享对象

时间:2012-08-30 12:38:42

标签: java maven shared-libraries

我目前正在尝试使用maven和sqlite4java构建我的项目。哪个在官方maven存储库中可用。 官方sqlite4java page on google code确实有一个示例配置,但它有点过时,不适合我的需要。我想最后有一个.jar-File,我可以在其他地方部署。这里的问题是共享对象依赖。我正在使用他们页面中的官方构建目标将其复制到build.dir / lib,但我的程序集目标崩溃了:

[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>

2 个答案:

答案 0 :(得分:2)

编辑:

我认为jar-with-dependencies程序集描述符试图解压缩依赖项。

请参阅链接:

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

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

<unpack>true</unpack>

当然,它无法解压缩.so

因此,您可能必须使用自定义程序集来执行您想要执行的操作

答案 1 :(得分:0)

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

  1. 我们需要将所有本地库(included in sqlite4java zip download)放到 src / main / resources 目录中。还要从Maven POM文件中删除sqlite4java本机库依赖项。
  2. 因为sqlite4java的本机库加载器不会查看您的类路径或JAR文件内部,所以您必须在启动时提取本机库,并且设置“sqlite4java.library.path”系统运行时的属性。请参阅以下示例代码:
  3. /** 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();
    }
    

    /** 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(); }

    现在,您的应用程序应该可以使用标准的“jar-with-dependencies”描述符进行构建,并且您的应用程序可以使用标准的“java -jar your_jar.jar”命令运行。

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

    如果你有一个更好,更少脏的解决方案,请告诉我!