10
votes

I am developing a web application using Spring Boot, and want to generate war instead of jar.

It works very fine using the conversion from jar to war described here : http://spring.io/guides/gs/convert-jar-to-war/

But I want to exclude the application.properties from the war, because I use @PropertySource(value = "file:${OPENSHIFT_DATA_DIR}/application.properties") to get the file path on production environment.

  • This method works when generating my war, but in eclipse I can't run my application because application.properties not copied at all to target/classes :

    <build>
        <resources> 
            <resource> 
                <directory>src/main/resources</directory> 
                <excludes> 
                    <exclude>application.properties</exclude> 
                </excludes> 
            </resource> 
         </resources> 
    </build>
    
  • This method doesn't work at all, I think that spring-boot-maven-plugin doesn't support packagingExcludes :

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration> 
                    <packagingExcludes>WEB-INF/classes/application.properties</packagingExcludes> 
                </configuration> 
            </plugin>
        </plugins>
    </build>
    

Have you another suggestion?

Thanks

5
My approach to this problem is to just override the packaged configuration using spring.config.location parameter. I set it in Tomcat's context file for example to point to the configuration file I use in production environment. Have you tried doing it like this or is this solution not ideal for you? Or you could perhaps achieve exactly what you are trying to do by using different Maven build profiles for dev and production? I mean that application.properties would be excluded only if you packaged your app with production Maven profile ... - Bohuslav Burghardt
I want only exclude application.properties when I package my war using maven, everything else works fine. I don't want to delete application.properties after generating the war. - amgohan

5 Answers

13
votes

Try using the solution below. This will work:

<build>
    <resources>
         <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <excludes>
                <exclude>**/*.properties</exclude>
            </excludes>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

If you are using the above solution , while running the project in Eclipse IDE you may get error that the properties file is not found. To get rid of this you need to add the resources folder in Run as configuration.(Run configurations... -> Classpath -> User Entries -> Advanced... -> Add Folders)

4
votes

When running in Eclipse, at your Run Configuration, you need to specify the path of the propeties to Spring Boot:

--spring.config.location=${workspace_loc:/YOURPROYECTNAME}/src/main/resources/
2
votes

The solution I added is to unzip my packaged war, delete the file application.properties and create a new war named ROOT.war using maven-antrun-plugin and run some ant tasks.

this is what i added to my plugins in pom.xml :

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
    <execution>
        <id>package</id>
        <phase>package</phase>
        <configuration>
            <target>
                <unzip src="target/${artifactId}-${version}.${packaging}" dest="target/ROOT/" />
                <delete file="target/ROOT/WEB-INF/classes/application.properties"/>
                <zip destfile="target/ROOT.war" basedir="target/ROOT" encoding="UTF-8"/>
                <delete dir="target/ROOT"/>
            </target>
        </configuration>
        <goals>
            <goal>run</goal>
        </goals>
    </execution>
</executions>
</plugin>

I named my target war as ROOT.war because I am using tomcat on openshift PaaS, so I just copy my ROOT.war and push to my openshift repo. That's it

2
votes

What I understand from your question is, you want to use application.properties for your development. But you dont want to use it for production.

I would suggest using Spring profiles to achieve this. In your properties file

  1. Create a profile for development. Put all your development properties under it.
  2. Do not create a profile for production in your properties file.
  3. When you are developing, set active profile to development, so that the properties are loaded from your application.properties file.
  4. When you run it in production, set active profile to Production. Though application.properties will be loaded into your WAR, since there is no profile for production, none of the properties will be loaded.

I have done something similar using YML. I am sure there must be a way to do the same thing using .properties file too.

spring:
  profiles.active: development
--
spring:
  profiles: development
something:
  location: USA
  unit1: Test1
  unit2: Test2

You could change the profile in run time using

-Dspring.profiles.active=production
0
votes

Try to using this solution:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring.version}</version>
    <configuration>
        <addResources>false</addResources>
    </configuration>
</plugin>

<addResources>false</addResources> will keep properties when you run mvn spring-boot:run