3

I need to package an application as an executable jar; its properties files will be located outside it, in the same directory. In the end, I will have something like that in the filesystem:

 .
 app.jar
 file1.properties
 file2.properties

But, after packaging it, the application cannot access the properties files. After some research, I think I know what is causing it, but I am not being able to instruct Maven to perform as I want.

I am using maven-assembly-plugin to build a jar-with-dependencies, as show below:

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <index>false</index>                
            <manifest>
                <mainClass>main.Main</mainClass>
            </manifest>
            <manifestEntries>
                <Class-Path>.</Class-Path> 
            </manifestEntries>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

When I try to run the jar, I get an exception that indicates that the properties outside the jar file are not being loaded.

In main.Main class, I put the following code, just to test accessibiliy from outside the jar:

ClassLoader cl = ClassLoader.getSystemClassLoader();
URL systemResource = ClassLoader.getSystemResource("file1.properties");
System.out.println("File 1 " + systemResource);
systemResource = ClassLoader.getSystemResource("insideJarFile.xml");
System.out.println("insideJarFile.xml " + systemResource);

insideJarFile.xml is a file that is packaged inside the jar. This is the result of the code above:

File 1 null
insideJarFile.xml jar:file:/D:/test/application-jar-with-dependencies.jar!/insideJarFile.xml

Researching for a few hours hinted me that the cause could be the INDEX.LIST file. I opened the jar file in 7-zip and I found it there, inside META-INF folder. I deleted it from inside the jar and executed it again; the result was:

File 1 file:/D:/test/file1.properties
insideJarFile.xml jar:file:/D:/test/application-jar-with-dependencies.jar!/insideJarFile.xml

Question: how I tell maven to not create the INDEX.LIST file? I tried <index>false</index> but it did not work.

TIA,

FQL

Quaestor Lucem
  • 607
  • 9
  • 21

2 Answers2

1

I gave up using maven-assembly-plugin.

Instead, I used André Aronsen's solution, only adding the following code:

<manifestEntries>
    <Class-Path>.</Class-Path>
</manifestEntries>

I did it to insert the jar's current directory in the classpath, so I can have my properties files outside it, as I wanted.

Just for the sake of future readers, here is the final code:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>lib/</classpathPrefix>
                <mainClass>theMainClass</mainClass>
            </manifest>
            <manifestEntries>
                <Class-Path>.</Class-Path>
            </manifestEntries>
        </archive>
    </configuration>
</plugin> 

This way, I do not have to worry with a lot of problems and at the sametime the André Aronsen's solution is very simple, although it did not create a jar with all its dependencies inside it.

Thanks for reading, kudos for André Aronsen, and hope this helps others too.

Community
  • 1
  • 1
Quaestor Lucem
  • 607
  • 9
  • 21
1

Another workaround would be to delete the Index.List file after jar-creation. This can be done with help of the TrueZIP Maven Plugin. This way one does not have to switch the maven-assembly-plugin.

Below example taken and adapted from here. Just insert the snippet inside your pom.xml after the maven-assembly-plugin.

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.1</version>
<executions>
    <execution>
        <id>remove-a-file-in-sub-archive</id>
        <goals>
            <goal>remove</goal>
        </goals>
        <phase>package</phase>
        <configuration>
            <fileset>
                <directory>target/my-jar.jar/META-INF</directory>
                <includes>
                    <include>INDEX.LIST</include>
                </includes>
            </fileset>
        </configuration>
    </execution>
</executions>

Community
  • 1
  • 1