12

I am building an executable jar file with maven, meaning that you run it with "java -jar file.jar".

I want to rely on user defined properties (just a file containing keys/values), during developpement phase I was putting my "user.properties" file in maven /src/main/resources/ folder.

My property file is loaded with:

final Properties p = new Properties();
final InputStream resource = IOParametres.class.getResourceAsStream("/user.properties");
p.load(resource);

Now, I want to keep that file outside of the JAR and have something like this :

- execution_folder
   |_ file.jar
   |_ config
      |_ user.properties

I tried many things with maven plugins like maven-jar-plugin, maven-surefire-plugin and maven-resources-plugin but I can't get it working...

Thanks in advance for your help!

GournaySylvain
  • 461
  • 1
  • 3
  • 16
  • Is user.properties just a separate text file you keep beside your jar and want to read on runtime? Because if so... you should probably just treat is as you would any other external file – Deltharis Oct 31 '14 at 10:19
  • Yes, it is just a separate file, but the thing is 1- I dont know where the jar and the config files will be put by the user 2 - I have other resources files used by dependencies (DB connection and others) – GournaySylvain Oct 31 '14 at 10:26
  • If you like to the properties file outside you need to set classpath to point to your `executon_folder/config/` folder otherwise you will not be able to access your `user.properties`. So a simple `java -jar file.jar` will not work. – khmarbaise Oct 31 '14 at 13:57
  • @khmarbaise indeed, I tryed many things and it actually works as I want when I add my "config/" to my MANIFEST's classpath. I tryed to add it using maven surefire plugin (with the additionalClasspathElements tag) but it did not work. Do you know how to have it automatically added by maven ? (Apparently, it's m2e limitation : [yet another maven question](http://stackoverflow.com/a/1328342/1326437)) – GournaySylvain Nov 03 '14 at 16:19

2 Answers2

16

I found what I needed using only maven configuration.

First I add config folder to the classpath:

<build>
<plugins>
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
        <archive>
            <manifestEntries>
                <Class-Path>config/</Class-Path>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>
</plugins>
</build>

I load resources the same way as before:

final InputStream resource = IOParametres.class.getResourceAsStream("/user.properties");
p.load(resource);

And if you want to keep your example resource files in your repo and remove them from your build:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>user.properties</exclude>
                <exclude>conf/hibernate.cfg.xml</exclude>
            </excludes>
        </resource>
    </resources>
</build>

Next to the jar file, I add a config folder holding all the resource files I need.

The result is:

  • user.properties can be loaded using getResourceAsStream
  • other libraries relying on specific resources (I won't argue, but I find it... not that good) can load their resources without any issue.

Thanks for the help, and I hope it may help somebody someday!

GournaySylvain
  • 461
  • 1
  • 3
  • 16
  • I want to do the same but first I need to get the configs directory beside the jar file. How to achieve that? – S.Dan Feb 26 '18 at 08:58
  • I don't really understand your question here... In my scenario, the config files were not stored inside the jar file (excluded in the pom.xml file). The creation and copy of your config files has to be managed on the deployment side – GournaySylvain Feb 26 '18 at 09:29
  • Yes. I want a way to get the config folder outside the jar without manually copyng or pasting. How did you handle it? – S.Dan Feb 26 '18 at 09:32
  • A way to handle this would be to use a deployment automation tool (eg. ansible) if you want to keep resources separated from jar file. You could also deploy a filtered resources jar and extract it on your server (but again, you can do it manually or through automation) – GournaySylvain Feb 26 '18 at 09:41
2

As I mentioned in the comment - it looks like you want to use user.properties file simply as a text file that lies besides your jar. If that's the case, than using it is rather simple - directory containing your jar file is the current directory when checked during runtime. That means that all you need is:

properties.load(new FileInputStream("config/user.properties"));

without trying to put in on the project classpath.

And if anything else is there to be done, it would just by copying your properties from resources directory to target to avoid the hussle of doing it by hand. That can be achieved by maven-antrun-plugin:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-resources</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <mkdir dir="${project.build.directory}" />
                            <copy file="${basedir}/src/main/resources/user.properties" tofile="${project.build.directory}/config/user.properties" />
                        </tasks>
                    </configuration>
                </execution>
            </executions>
        </plugin>
Deltharis
  • 2,320
  • 1
  • 18
  • 29
  • I understand your solution and I could use it for some of my files, but in my resources, I also have a "hibernate.cfg.xml" and some other files that are used by a library I call. And this library is only looking for resource files (with a call to _getResourceAsStream_) – GournaySylvain Nov 03 '14 at 16:02
  • Hey @Deltharis I have added same plugin in `pom.xml` now it copies content of `myfolder` as it is to target folder but when I `run mvn package` command it's not appearing correctly inside `jar` instead it shows `myfolder/maven` rather than `myfolder/abc.jpg` any idea – Naveen Kumar Mar 04 '20 at 10:28