2017-02-10 153 views
2

我正试图打开一个坐在我的jar文件中的文件。在jar中读取文件

我用这个Maven插件:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <version>3.0.0</version> 
    <configuration> 
     <archive> 
     <manifest> 
      <addClasspath>true</addClasspath> 
      <mainClass>com.fatec.migration.script.utils.Script</mainClass> 
     </manifest> 
     </archive> 
     <descriptorRefs> 
     <descriptorRef>jar-with-dependencies</descriptorRef> 
     </descriptorRefs> 
    </configuration> 
    <executions> 
     <execution> 
     <id>assemble-all</id> 
     <phase>package</phase> 
     <goals> 
      <goal>single</goal> 
     </goals> 
     </execution> 
    </executions> 
    </plugin> 

我建立,然后复制我的档案:

cp /home/stephane/dev/java/projects/fatec/Fiabilisation_Controles_XP_AS/target/fatec-script-jar-with-dependencies.jar . 

现在我可以尝试运行它:

java -jar fatec-script-jar-with-dependencies.jar 1 2017-02-01 2017-02-02 all 

唉,就不能找到文件:

The file secure/extrapack-renew.sql could not be opened. 
java.lang.NullPointerException 
    at com.fatec.migration.script.utils.AbstractScript.loadSqlStatement(AbstractScript.java:75) 

但该文件确实存在,我可以看到它在存档:

$ jar -tvf target/fatec-script-jar-with-dependencies.jar | grep "secure/extrapack-renew.sql" 
    1844 Fri Feb 10 17:43:46 CET 2017 secure/extrapack-renew.sql 

这里是我尝试打开该文件:

protected String loadSqlStatement(String scriptPath, String filename) { 
    String filepath = buildSqlFilePath(scriptPath, filename); 
    try { 
     return new String(Files.readAllBytes(Paths.get(getClass().getResource(filepath).toURI()))); 
    } catch (Exception e) { 
     System.err.println("The file " + filepath + " could not be opened."); 
     e.printStackTrace(); 
    } 
    return null; 
} 

private String buildSqlFilePath(String scriptPath, String filename) { 
    return scriptPath + "/" + filename; 
}  

的SCRIPTPATH是“安全”和文件名是“extrapack-renew.sql”。

我错过了什么?

回答

1

我觉得你的问题是你用getResource()方式:

Paths.get(getClass().getResource(filepath).toURI()); 

您使用相对类路径(即相对于当前类的位置)来检索"extrapack-renew.sql"文件。
这意味着此资源必须位于您的jar中的此路径中才能被检索。

如果资源不在当前的类路径中,用于检索资源的路径应以"/"字符开始,以指定资源的绝对名称:

Paths.get(getClass().getResource("/"+filepath).toURI()); 

当然如果使用maven,extrapack-renew.sql应该在

src/main/resources/secure文件夹的源项目中,这样"/secure/extrapack-renew.sql"是类路径中的一个资源。

+0

SQL文件位于jar文件中。它不应该被移动或改变。假设它是硬编码的。也许我不需要将它放在外部文件中,更不用说放在资源文件中。 – Stephane

+1

事实上,如果你没有要求在jar被打包后改变它,你没有义务从jar中移出文件。这是一个部署选择。 – davidxxx

0

我的解决方案是让属性文件不在jar文件中,与问题原始标题中提出的内容相反。

我得到它的工作,与属性文件坐在项目主目录。

$ ll 
total 52K 
-rw-rw-r-- 1 stephane 10 févr. 13 10:49 application.properties 
-rw-r--r-- 1 stephane 6,1K févr. 10 17:22 pom.xml 

我可以打开此文件,并加载它的属性:

properties.load(new FileInputStream(new File(DB_AUTOSELF_PROPERTIES_FILENAME))); 

然后,我可以移动.jar归档和属性文件到另一个目录,并运行应用程序:

$ pwd 
/home/stephane/trash 
$ cp ~/dev/java/projects/AS/target/script-jar-with-dependencies.jar . 
$ cp ~/dev/java/projects/AS/application.properties . 
$ vi application.properties 
-rw-rw-r-- 1 stephane 10 févr. 13 10:53 application.properties 
java -jar script-jar-with-dependencies.jar 1 2016-12-01 2017-02-12 all 

我的pom.xml文件包含插件来复制资源并创建一个胖jar存档:

<plugin> 
    <artifactId>maven-resources-plugin</artifactId> 
    <executions> 
     <execution> 
     <id>copy-resources</id> 
     <phase>validate</phase> 
     <goals> 
      <goal>copy-resources</goal> 
     </goals> 
     <configuration> 
      <outputDirectory>${basedir}/target</outputDirectory> 
      <resources> 
      <resource> 
       <directory>src/main/resources</directory> 
       <filtering>true</filtering> 
      </resource> 
      </resources> 
     </configuration> 
     </execution> 
    </executions> 
    </plugin> 
    <plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <version>3.0.0</version> 
    <configuration> 
     <archive> 
     <manifest> 
      <addClasspath>true</addClasspath> 
      <mainClass>com.fatec.migration.script.utils.Script</mainClass> 
     </manifest> 
     </archive> 
     <descriptorRefs> 
     <descriptorRef>jar-with-dependencies</descriptorRef> 
     </descriptorRefs> 
    </configuration> 
    <executions> 
     <execution> 
     <id>assemble-all</id> 
     <phase>package</phase> 
     <goals> 
      <goal>single</goal> 
     </goals> 
     </execution> 
    </executions> 
    </plugin>