[ACCEPTED]-Executable jar won't find the properties files-maven

Accepted answer
Score: 22

BalusC is right, you need to instruct Maven 5 to generate a MANIFEST.MF with the current directory 4 (.) in the Class-Path: entry.

Assuming you're still using 3 the Maven Assembly Plugin and the jar-with-dependencies descriptor 2 to build your executable JAR, you can tell 1 the plugin to do so using the following:

  <plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>com.stackoverflow.App</mainClass>
        </manifest>
        <manifestEntries>
          <Class-Path>.</Class-Path> <!-- HERE IS THE IMPORTANT BIT -->
        </manifestEntries>
      </archive>
    </configuration>
    <executions>
      <execution>
        <id>make-assembly</id> <!-- this is used for inheritance merges -->
        <phase>package</phase> <!-- append to the packaging phase. -->
        <goals>
          <goal>single</goal> <!-- goals == mojos -->
        </goals>
      </execution>
    </executions>
  </plugin>
Score: 18

There are two workarounds:

  1. Don't use the JAR as executabele 8 JAR, but as library.

    java -cp .;filename.jar com.example.YourClassWithMain
    
  2. Obtain the root location 7 of the JAR file and get the properties file 6 from it.

    URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
    URL propertiesFile = new URL(root, "filename.properties");
    Properties properties = new Properties();
    properties.load(propertiesFile.openStream());
    

None of both are recommended approaches! The 5 recommend approach is to have the following 4 entry in JAR's /META-INF/MANIFEST.MF file:

Class-Path: .

Then it'll be available 3 as classpath resource the usual way. You'll 2 really have to instruct Maven somehow to 1 generate the MANIFEST.MF file like that.

Score: 1

EDIT: this is to respond to your comment:

You 16 need to make sure that the properties file 15 is on the class path with the right root 14 for the java invocation that stars up the 13 jar file. if your path is

stuff/things.properties 12

and the runtime location is

/opt/myapp/etc/stuff/things.properties 11

and the jar file is in

/opt/myapp/bin/myjar 10

then you need to launch as

/path/to/java 9 -cp "/opt/myapp/etc:/opt/myapp/bin/myjar.jar" my.pkg.KavaMain 8

working with this kind of config can be 7 irksome in a dev environment, luckily, there's 6 the maven exec plugin that will get you the right kind of 5 launch scenario.

Original Answer:

You want 4 to read about the maven resources plugin.

Basically you want to add 3 something like this:

<plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
                <resources>
                        <resource>
                                <directory>src/main/java</directory>
                                <includes>
                                        <include>**/*properties</include>
                                </includes>
                        </resource>
                </resources>
        </configuration>
<plugin>

to your pom.xml assuming 2 that you're propertis file is with your 1 java sources -- really it should be in src/main/resources.

Score: 0

I had a similar problem, and this thread 4 was a big help! FYI, I modified my Ant 3 buildfile to do the MANIFEST-making, then 2 designated that manifest when JAR-ing my 1 server-side code:

<!-- Create a custom MANIFEST.MF file, setting the classpath. -->
<delete file="${project.base.dir}/resources/MANIFEST.MF" failonerror="false"/>
<manifest file="${project.base.dir}/resources/MANIFEST.MF">
  <attribute name="Class-Path" value="." />
</manifest>

<!-- JAR the server-side code, using the custom manifest from above. -->
<jar destfile="services/${name}.aar" manifest="${project.base.dir}/resources/MANIFEST.MF">
[....]

More Related questions