AbtPst
AbtPst

Reputation: 8018

Uber jar not reading external properties files

I am creating an uber jar i.e. jar with dependencies for my project. I have a bunch of properties files that the project uses. I want to be able to change these properties files before running my project so i want them to be outside of the jar. Here is the relevant sections of my pom

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2</version>
                <configuration>

                    <artifactSet>
                        <excludes>
                            <exclude>**/*.properties</exclude>
                            <exclude>**/*.json</exclude>
                        </excludes>
                    </artifactSet>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>path.to.main.Main</mainClass>
                        </manifest>
                        <manifestEntries>
                            <Class-Path>.</Class-Path> 
                            <Class-Path>conf/</Class-Path>
                        </manifestEntries>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id> 
                        <phase>package</phase> 
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.4</version>
                <executions>
                    <execution>
                        <id>copy-resources</id>
                        <phase>install</phase>
                        <goals>
                            <goal>copy-resources</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${basedir}/target/conf</outputDirectory>
                            <resources>
                                <resource>
                                    <directory>src/main/resources</directory>
                                    <includes>
                                        <include>**/*.properties</include>
                                        <include>**/*.json</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

so essentially, I want to create a folder ${basedir}/target/conf and copy all the .properties and .json files to it. Also, here is how I am reading the files

InputStream in = this.getClass().getClassLoader().getResourceAsStream("filename.properties");

I am facing a couple of problems

  1. When i do mvn clean install, i still see the all the .properties and .json files in the classes folder. Shouldn't they have been excluded?

  2. The conf folder is created with all of the files, but when I run the jar adn try to change the properties, the changes are not picked up. How can i ensure that the conf folder is being added to the classpath?

  3. I want to be able to load the .properties and .json files from the src/main/resources folder while i am developing so i dont want to put them in a separate folder. Is this possible?

Upvotes: 0

Views: 1320

Answers (1)

Sam
Sam

Reputation: 422

I was facing the same issue where Uber jar is not reading the external configuration file. I tried below configuration and it worked like charm. Refer below configuration it may help someone having the issue with uber jar not reading extenarl files. I am not sure if this is the best way but haven't found any soultion online :)

  1. I have included the resources using IncludeResourceTransformer.
  2. Using filter removed the properties file from uber jar.
  3. In classpath /conf reading the properties from external folder.

    <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>2.3</version>
            <executions>            <!-- Run shade goal on package phase -->
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                    <configuration>
                        <transformers>
                            add Main-Class to manifest file
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                <manifestEntries>
                                    <Main-Class>JobName</Main-Class>
                                    <Class-Path>conf/</Class-Path>
                                </manifestEntries>
                            </transformer>
                            <transformer
                                implementation="org.apache.maven.plugins.shade.resource.IncludeResourceTransformer">
                                <resource>src/main/resources/config.properties</resource>
                                <file>${project.basedir}/src/main/resources/config.properties</file>
                            </transformer>
                        </transformers>
                        <finalName>FinalJarName</finalName>
                        <filters>
                            <filter>
                                <artifact>groupId:artifactId</artifact>
                                <excludes>
                                    <exclude>**/*.properties</exclude>
                                </excludes>
                            </filter>
                        </filters>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    

good luck.

Upvotes: 1

Related Questions