I have CSS and JavaScript files in src/main/webapp directory of my project.
I want to join add joined and minified version of these resources to my WAR file and to the place where tomcat-maven-plugin picks it up.
I used yuicompressor-maven-plugin to create the files and put it to ${project.build.directory}/${project.build.finalName}. It works great for maven package and those resources make their way to WAR file, but somehow tomcat-maven-plugin does not see those at all. Should I use a different directory for it?
My pom:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<path>/MyApp</path>
<warDirectory>${project.build.directory}/${project.build.finalName}</warDirectory>
</configuration>
</plugin>
<plugin>
<version>2.5.1</version>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<optimize>true</optimize>
<debug>true</debug>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/resources/META-INF</directory>
<filtering>true</filtering>
<targetPath>META-INF</targetPath>
<includes>
<include>context.xml</include>
</includes>
</resource>
</webResources>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<excludes>
<exclude>**/*</exclude>
</excludes>
<aggregations>
<aggregation>
<output>${project.build.directory}/${project.build.finalName}/js/commons-pack.js</output>
<includes>
<include>${project.build.sourceDirectory}/../webapp/js1.js</include>
<include>${project.build.sourceDirectory}/../webapp/js2.js</include>
...
What should I do to make mvn tomcat:run to also pick up my generated files?
Use warSourceDirectory:
<warSourceDirectory>${project.build.directory}/${project.build.finalName}</warSourceDirectory>
Instead of this configuration property (warDirectory) for the tomcat-maven-plugin:
<warDirectory>${project.build.directory}/${project.build.finalName}</warDirectory>
According to the tomcat-maven-plugin documentation, warSourceDirectory is where the web resources get picked up, and its default value is ${basedir}/src/main/webapp. This means that if you don’t set that property, you need to generate your unified/minified JavaScript file under ${basedir}/src/main/webapp.
If you set warSourceDirectory to the output folder, this means you need to generate this file before starting Tomcat.
Alternatively, you can also use the run-war goal instead of run, e.g. mvn tomcat6:run-war. This wil use the exploded war in your build directory (and thus filtered resources). See this site. There is also run-war-only which skips the packaging phase.
Note the plugin is now maintained at Apache (so upgrade a bit :-) ) see http://tomcat.apache.org/maven-plugin-2.0/.
Even it works using install I'm not sure it's the optimum solution (regarding io and build time).
The tomcat run must be able to use resources from more than one directory (I'm not sure it's possible with the current tomcat embeded api).
Can you add a feature request here https://issues.apache.org/jira/browse/MTOMCAT
Thanks
Related
I have these folders in my project structure
/src/main/java
/src/main/resources
In the "resources" folder I have 2 files: "config.properties" and "logging.properties".
And I have the following "" in my pom.xml:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>myapp.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
When I run "mvn clean package", it does generate the "target" folder with the jar and the "classes" folder containg the properties file as mentioned above.
To read one of the properties files (after clicking on a Button), I'm using the following code:
Properties prop = new Properties();
prop.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("logging.properties"));
String logFolder = prop.getProperty("myApp.property");
//Do something with 'logFolder'
It runs OK.
But if I change the "myApp.property" in "logging.properties" file, the change doesn't affect the "logFolder" value.
What must I do to be able to dinamically change the property value and make my application read the new value WITHOUT RECOMPILING THE PROJECT?
Thank you.
You can invoke respective plugins manually:
mvn resources:resources maven-assembly-plugin:single
Though this is not the best option anyway. It's better to eliminate re-packaging all together for local deploys:
Just start the app in IDE instead of building a JAR. IDE will detect changes in the configs.
And in general allow overriding your variables with either env vars or system variables. So after reading the file also check if the values are overriden and use those.
For remote deploys we usually don't keep configuration files in JAR (you don't want to keep PRD passwords in there, right?). So deploying to remote envs should use config files from restricted sources. This means that the app needs to be able to read configs that are not inside JAR.
Here's what I added to my pom file so Maven loads the resources into the jar at the root level.
<resources>
<resource>
<directory>src/my-resources</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.jpg</include>
</includes>
</resource>
</resources>
</build>
Notice how my folder, called my-resources, is not placed under main, it's placed under src. Of course, without telling Maven about your resource in the pom it won't do anything for you.
I didn't check your code, but there's how to tell Maven to pack your resources into your jar for you. And at a glance at your code, when working from inside a jar, you need to prefix your filename with a '/' because it's now using a relative path, not an absolute path.
getResourceAsStream("logging.properties") works outside a jar.
getResourceAsStream("/logging.properties") is what you need inside a jar.
I managed to solve this issue.
The other answers are correct. The real problem (I think) is with this "maven-assembly-plugin" that I was using to build.
For some reason, it does not read my properties files after build, maybe I was doing something wrong with it.
So, I changed my <build> script in my pom.xml to the following:
<build>
<finalName>myapp</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<includeEmptyDirs>true</includeEmptyDirs>
</configuration>
<executions>
<execution>
<id>copy-resources</id>
<phase>install</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>logs</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>myApp.Main</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/logs</include>
<include>**/*.properties</include>
<include>**/*.gif</include>
</includes>
</resource>
</resources>
</build>
In short: I replaced the "maven-assembly-plugin" with "maven-dependency-plugin" (I'm using an Oracle DB in this project), "maven-resources-plugin" (copying all of my resources to "/target" folder after build) and the "maven-jar-plugin" setting the "Class-path" property to ".".
In the resources in the profile folder there is a configuration file, depending on the profile it should be taken and put in the resource root
Actually, what I encountered
He puts it in the project itself, and not in the original jar
When the second time you collect this file already comes
So that the folder itself in the jar does not fall
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
<executions>
<execution>
<id>copy-properties</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources/profile/${profile.dir}</directory>
<includes>
<include>server.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>${maven-ejb-plugin.version}</version>
<configuration>
<filterDeploymentDescriptor>true</filterDeploymentDescriptor>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
<ejbVersion>3.0</ejbVersion>
</configuration>
</plugin>
</plugins>
Tell me where I was wrong?
In which plugin to configure maven-ejb-plugin or maven-resources-plugin
I have src/main/recoursces/profile/
serverA/server.properties
serverB/server.properties
serverC/server.properties
I want jar
- It did not have a folder profile
- and have one server.properties
I'm not sure if I understand your question. I believe the resources phase package is not correct, it should be on a previous one like process-resources.
Here you have the Maven Lifecycle Reference
process-resources: copy and process the resources into the destination directory, ready for packaging.
package: take the compiled code and package it in its distributable format, such as a JAR.
I was trying to achieve a custom directory structure for my war with maven build.
Below is my build command used in pom.xml.
<build>
<finalName>abc</finalName>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<configuration>
<tasks>
<mkdir dir="bin" />
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>bin</outputDirectory>
<resources>
<resource>
<directory>src/main/webapp/</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>bin</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
Please find below the current directory structure of war file after unzip the war. Maven is including complete webapp directory under WEB-INF/Classes , But i want only java class files(ndaws directory). I have tried a lot of excluding techniques, But nothing works.
Got the solution, My changes in pom is not reflecting, war is being created from build folder under target.
Thanks
remove resource directory from maven-resources-plugin
and add warSourceDirectory to maven-war-plugin
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
</configuration>
</plugin>
or if using intelij and webapp folder marked 'resoures', select the folder.
open context menu.
Mark Directory as > Unmark as Resources Root
I tryed alot of solutions. In the end I found one that solve my problem... It's a similiar case, but I need to exclude a folder inside the webapp.
I opened my war file using 7zip... The folder that I want to exclude were in the main page.
I used this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<packagingExcludes>myfolder/**</packagingExcludes>
</configuration>
</plugin>
Just change "myfolder" with the folder that you want to exclude.
If that is more than one folder, multiply this line.
This question prompted me to post a follow up question. During a maven build, empty directories are not copied from src/main/webapp, even though I have set the pom.xml to include empty directories:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<includeEmptyDirs>true</includeEmptyDirs>
</configuration>
</plugin>
How come empty directories are not copied?
I just met the same problem. This worked for me:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<includeEmptyDirectories>true</includeEmptyDirectories> <!-- since 2.4 -->
</configuration>
</plugin>
Your method didn't work because that "src/main/webapp" was not a resource directory.
The reason is due to bug MWAR-128 in maven. The solution is to upgrade Maven to r1498124. Alternately, you can include a placeholder file (ex. empty.tmp) and filter it like so:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.plugin.version}</version>
<configuration>
<packagingExcludes>**/empty.tmp</packagingExcludes>
</configuration>
</plugin>
I want to find a maven native (i.e. without calling external programs) to inject the svn revision in the war manifest.
Does anybody know a way to do that?
I found mention to how to add the subversion revision to manifests in jar files but not with war files.
I searched SO but could not find this issue specifically.
I want to find a maven native (i.e. without calling external programs) to inject the svn revision in the war manifest.
This is possible with the Build Number Maven Plugin using the svnjava provider:
If you need to execute the plugin on
machine without any svn in the path
you can configure the mojo to use the
svnjava provider.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>true</doCheck>
<doUpdate>true</doUpdate>
<providerImplementations>
<svn>javasvn</svn>
</providerImplementations>
</configuration>
</plugin>
</plugins>
</build>
The Build Number Maven Plugin sets the build number in the ${buildNumber} property that you can then use in your POM.
I found mention to how to add the subversion revision to manifests in jar files but not with war files.
Then, to add the build number in the MANIFEST of a war, configure the plugin as mentioned in the Usage page:
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Try this. About halfway down, look for maven-war-plugin
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>