This question already has answers here:
Building two different versions a given war with maven profiles and filtering from eclipse
(2 answers)
Closed 6 years ago.
#Jarrod Roberson, Spring in this question is about version 1.2 so the other solution was not possible. This solution uses a simple Maven configuration and Spring's PropertyPlaceholderConfigurer in applicationContext.xml.
I have upgraded a webapp I work on from Windows XP, Eclipse 3.2 to OS X, Eclipse Mars.
I started with a Dynamic Web Project on Mars and completed the upgrade. I have since converted it to a Maven Project. I was hoping to use Maven Profiles for switching between Dev and Test environments.
The environments differ only in config.properties which gets pulled into applicationContext.xml. For Test I only intend to export to a war with the 'correct' config.properties.
But I cannot get the config.properties file to be updated from the profile dependent versions when switching profiles.
I have in pom.xml:-
<profiles>
<profile><!-- The configuration of the development profile -->
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<build.profile.id>dev</build.profile.id>
</properties>
</profile>
<profile><!-- The configuration of the test profile -->
<id>test</id>
<properties>
<build.profile.id>test</build.profile.id>
</properties>
</profile>
</profiles>
<build>
<sourceDirectory>src</sourceDirectory>
<filters>
<filter>profiles/${build.profile.id}/config.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
I feel that I am close but something is missing. I tried adding the maven-resources-plugin but that made no difference.
Any help would be much appreciated.
Instead of having your config.properties file placed in the src/ folder you should have it inside your src/main/resources folder.
Your project structure should look like this:
project-root
|_ src
|_ main
|_ java
|_ resources
|_ profiles
|_ dev
|_ config.properties
|_ test
|_ config.properties
|_ webapp
|_ WEB-INF
After that you've to change your pom.xml in order to include your config.properties as a resource.
And notice that the filters have been removed since Maven is already filtering your resources when you have <filtering>true</filtering>.
Your pom.xml will look like this:
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources/profiles/${build.profile.id}</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<includes>
<include>*.properties</include>
</includes>
</resource>
</resources>
...
</build>
Finally, you'll have your config.properties inside your WEB-INF/classes folder, according to the selected profile.
This worked for me:-
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>profiles/${build.profile.id}</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<includes>
<include>*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
I am using a Dynamic Web folder structure not a 'pure' Maven folder structure (eg. src/main/java).
My profiles folder is directly under the project (webapp) folder at the same level as src. Under profiles I have two folders, dev and test each with their respective config.properties file.
It now works as expected, when I change profile the correct config.properties appears in WEB-INF/classes ready to be picked up by applicationContext.xml...
Related
I am unable to add images from my resources directory (which is marked as resources root) to the final jar that I want t generate. I have tried building a jar using File -> Project Structure -> Project Settings -> Artifacts -> Click green plus sign -> Jar -> From modules with dependencies. But failed. I have also tried building a jar from the Maven project window in Intellij. Which failed as well.
Here is my pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample.project</groupId>
<artifactId>login</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<resources>
<resource>
<directory>
src/main/resources
</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>com.sample.project.Login</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
My project structure looks like this: Project structure
zip file of my sample project:
Archive
<build>
<finalName>${project.artifactId}</finalName>
<defaultGoal>dependency:sources</defaultGoal>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
Above code in pom.xml would copy xml files located in resources. You can change to some other files or remove
<includes>
<include>**/*.xml</include>
</includes>
will copy all files in resources.
The files that you have in the directory src/resources/ need to be moved to src/main/resources/, otherwise Maven will ignore them.
Additionally, remove this
<resources>
<resource>
<directory>
src/main/resources
</directory>
</resource>
</resources>
because this is the default convention that Maven will use anyway.
I have a log4j.xml file in src/main/resources that I'm trying to exclude from the jar file. I have a property with version 3.0.0 in the parent pom file.
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven-jar-plugin.version}</version>
<configuration>
<excludes>
<exclude>**/log4j.xml</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<configuration>
<!-- specify UTF-8, ISO-8859-1 or any other file encoding -->
<encoding>UTF-8</encoding>
</configuration>
</plugin>
...
According to maven manual (https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html), you have to put the files to include/exclude in resources section. So, if the file is located on src/resources, the configuration will be:
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/resources</directory>
<excludes>
<exclude>**/log4j.xml</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>
Hope that helps.
I upgraded to version 3.0.0 of the maven-jar-plugin and also changed the exclude back to "**/log4j.xml" from "src/main/resources/log4j.xml", which I had temporarily switched it to, so I'm not sure if one ore both fixes were required.
If you use <exclude>**/*log4j*</exclude> It should work if this pattern is acceptable for you.
Note what's written at the bottom of the doc: https://maven.apache.org/plugins/maven-jar-plugin/examples/include-exclude.html
Note that the patterns need to be relative to the path specified for the plugin's classesDirectory parameter.
Currently I have a sample maven project with the following build part where I specify a second resource location directory:
<project>
...
<build>
<resources>
<resource>
<directory>src/main/second-resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>${artifactId}</finalName>
<outputDirectory>${jarBuildPath}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
I can get my jar packaged with this configuration having my classes and resource files just in right place and with no issue.
But when adding the property <classesDirectory> to my maven-jar-plugin configuration snippet with value src/main/java:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<classesDirectory>src/main/java</classesDirectory>
<finalName>${artifactId}</finalName>
<outputDirectory>${jarBuildPath}</outputDirectory>
</configuration>
</plugin>
then when packaging my archive, hell, my resource files are no longer there.
From maven official documentation for the classesDirectory property, it says that Directory containing the classes and resource files that should be packaged into the JAR. and that makes all sense for me and it is quite fair that my resource files get disappeared since maven assumes that no file has the right to be packaged unless it is under src/main/java.
But my big thought was when specifying my resource files location (with one of the options below), Maven will be aware of the files location even if I had specified the <classesDirectory> entry.
With top level <resources> entry
<resources>
<resource>
<directory>src/main/second-resources</directory>
</resource>
</resources>
or via the maven-resource-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<resources>
<resource>
<directory>src/main/second-resources</directory>
</resource>
</resources>
</configuration>
</plugin>
I can tell you that I'm quite familiar with maven but this issue seemed weird for me: Is it not recommended to have in maven-jar-plugin when you have a some custom resource directory?
Can anyone kindly drop some light on this?
BR.
The classesDirectory is the directory where
the compiler plugin stores compiled java classes
the resources-plugin copies resources to be included in the file
created by the jar-plugin.
You have changed it to your java source code directory in the jar-plugin configuration.
Therefore, I imagine that your jar now only contains java source files.
Is this what you want, or are you just trying to include a second source of resource files?
If the latter, then just adding:
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/second-resources</directory>
</resource>
</resources>
should accomplish what you want without adding any configuration to the jar plugin. Note that the first <resource>..</resource> section is needed if you still have stuff you want in the default src/main/resources location.
I've been developing a standard web app and its really annoying to have Eclipse show src/main/resources and src/main/java in such a convenient flat-package way, yet I have to frequently drill down into src/main/webapp and all its subdirectories to modify my css, js, and html files.
I've never seen a project use additional source folders for resources like those, but is it out of the question to try? Ideally I'd love to have a directory structure like
src/main/java
src/main/resources
src/main/jsp
src/main/javascript
src/main/css
Has anyone setup a project like this? Does it become more of a hassle to even try, breaking existing plugins and whatnot?
Add resource folders this way.
<project>
...
<build>
...
<resources>
<resource>
<directory>resource1</directory>
</resource>
<resource>
<directory>resource2</directory>
</resource>
<resource>
<directory>resource3</directory>
</resource>
</resources>
...
</build>
...
</project>
More information
However, if you want multiple web resources (WEB-INF directory in WAR file) than you need to configure Maven War plugin.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<directory>src/main/jsp</directory>
</resource>
<resource>
<directory>src/main/javascript</directory>
</resource>
<resource>
<directory>src/main/css</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
By default, files under web-app are served, in an application container like tomcat, as static resources. So if I save a file like helloworld.html in those I can view it from my browser at
http://localhost:8080/myapp/helloworld.html
Is it possible to configure additional folders other than web-app to serve static content. I would prefer to do this from within the war file itself instead of having to configure it on a tomcat-wide way.
Any suggestions?
Maven's war plugin is a good fit here. This offers several configuration options when building the war so it'll be independent of your web server.
And an example where a different directory can be hosted as you suggest
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>resource2</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
Here's an another example they give where a different webapp folder can be used.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>