Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven : add external resources

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!

like image 326
GournaySylvain Avatar asked Oct 31 '14 10:10

GournaySylvain


People also ask

What is external dependency in Maven?

External dependencies (library jar location) can be configured in pom. xml in same way as other dependencies. Specify groupId same as the name of the library. Specify artifactId same as the name of the library. Specify scope as system.

How do I add a resource file to a jar file?

1) click project -> properties -> Build Path -> Source -> Add Folder and select resources folder. 2) create your JAR! EDIT: you can make sure your JAR contains folder by inspecting it using 7zip. Save this answer.

What does Maven resources plugin do?

The Resources Plugin handles the copying of project resources to the output directory. There are two different kinds of resources: main resources and test resources.


2 Answers

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>
like image 161
Deltharis Avatar answered Oct 15 '22 12:10

Deltharis


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!

like image 21
GournaySylvain Avatar answered Oct 15 '22 13:10

GournaySylvain