Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read a file in the jar

Tags:

java

I'm trying to open a file sitting in my jar archive.

I use this Maven 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>

I build and then copy my archive:

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

Now I can try running it:

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

Alas, it cannot find the file:

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

But the file does exist, I can see it in the archive:

$ 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

Here is how I try opening the file:

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;
}    

The scriptPath is "secure" and the filename is "extrapack-renew.sql".

What am I missing ?

like image 357
Stephane Avatar asked Dec 21 '25 11:12

Stephane


1 Answers

I think that your problem is the way you use getResource() :

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

You use a relative classpath (that is relative to the the current class location) to retrieve the "extrapack-renew.sql" file.
It means that this resource has to be located inside this path in your jar to be retrieved.

If the resource is not located inside the current class path, the path used to retrieve the resource should start with a "/" character in order to specify an absolute name of the resource:

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

Of course if you use maven, extrapack-renew.sql should be in

the src/main/resources/secure folder of the source project so that "/secure/extrapack-renew.sql" be a resource in the classpath.

like image 191
davidxxx Avatar answered Dec 23 '25 00:12

davidxxx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!