Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a java application with the following project structure:

myProject
  |
  |----src
  |     |
  |     |--main
  |     |
  |     |--resources
  |           |   
  |           |--userConfig.properties
  |           |--log4j.properties
  |
  |---target

I am using Maven to build my project. I am using maven command to build jar file as follows:

mvn package -DMaven.test.skip=true

I want to exclude userConfig.properties file from my JAR file so I have updated my pom.xml as follows:

<excludes>
    <exclude>**/userConfig.properties</exclude>
</excludes>

But it excludes from the target folder in which the compiled code resides. And the application won't run because it is unable to find the userConfig.properties file.

Can anyone help me?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
308 views
Welcome To Ask or Share your Answers For Others

1 Answer

I encountered this scenario as well. Basically, you want to be able to run your code locally from Eclipse using some userConfig.properties file that is readily accessible, such as inside /src/main/resources. Additionally, you want to provide a compiled executable JAR with an external userConfig.properties that allows the user to configure the application without cracking the JAR.

My implementation is as follows: running mvn clean install will:

  • create executable JAR with the specified mainClass
  • exclude all .properties files located in src/main/resources from the JAR
  • copy project dependencies into a lib folder in your project root
  • copy all .properties files located in src/main/resources into a conf folder in your project root. Note that this step is an optional convenience for your users of the JAR. You can require the explicitly create this file in the conf directory. This conf directory is effectively added to your runtime classpath via the manifest.
  • add this conf folder to the manifest, providing access to it from your executable JAR

Using these Maven plugins in conjunction with each other in your POM configuration will give you what you need. As to the "best practices" of this solution; I'm not sure.

Using maven-dependency-plugin as follows:

<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>

Using maven-jar-plugin as follows:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.3</version>
  <configuration>
    <excludes>
      <exclude>**/*.properties</exclude>
    </excludes>                    
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>
        <classpathPrefix>lib/</classpathPrefix>
        <mainClass>package.path.to.your.main.class.MainClass</mainClass>
      </manifest>
      <manifestEntries>
        <Class-Path>conf/</Class-Path>
      </manifestEntries>
    </archive>
  </configuration>
</plugin>

Using maven-resources-plugin as follows:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>2.3</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>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

Using this project setup, I can run in Eclipse using one config, and provide my users a properties file to configure, without properties stepping on each other.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...