Reputation: 12750
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 ?
Upvotes: 3
Views: 301
Reputation: 12750
My solution was to have the properties files NOT in the jar archive, contrary to what was asked in the original title of the question.
I got it working, with a properties file sitting in the project home directory.
$ 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
I can open this file and load its properties with:
properties.load(new FileInputStream(new File(DB_AUTOSELF_PROPERTIES_FILENAME)));
Then I can move the .jar
archive and the properties file to another directory, and run the application:
$ 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
My pom.xml
file contains the plugins to copy the resources and create a fat jar
archive:
<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>
Upvotes: 0
Reputation: 131316
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.
Upvotes: 1