I struggling with Java class filtering in a Maven WAR. The Maven compile a lot of Java classes and all of them appear in
target/classes
and I have packages like these:
a/A.class
a/b/B.class
a/b/C.class
Up to this point is OK. But what I need is to have a single Java class inside of
WEB-INF/classes
like this one:
a/b/B.class
This is the plugin's section from my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warName>${project.artifactId}</warName>
<webXml>${basedir}/src/main/application/WEB-INF/web.xml</webXml>
<packagingExcludes>WEB-INF/lib/*.jar,a/A.class,a/b/C.class</packagingExcludes>
<webResources>
<resource>
<directory>${basedir}/src/main/application/WEB-INF</directory>
<includes>
<include>jboss-web.xml</include>
</includes>
<targetPath>WEB-INF</targetPath>
</resource>
<resource>
<directory>${basedir}/src/main/application/META-INF</directory>
<includes>
<include>standard-jaxws-endpoint-config.xml</include>
</includes>
<targetPath>META-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
Unfortunately all the classes are packaged into my WAR.
Any hint?
Best regards,
SK
I believe this will filter the classes based on a relative location to the app that is built in the target directory. Which means your class files are stored in WEB-INF/classes at this stage.
Try changing this:
<packagingExcludes>WEB-INF/lib/*.jar,a/A.class,a/b/C.class
To
<packagingExcludes>WEB-INF/lib/*.jar,WEB-INF/classes/a/A.class,WEB-INF/classes/a/b/C.class
Related
How to create multiple war files from one maven eclipse Jersey Rest API project? As i have multiple Rest APIs in this project. I want to have one war file per each Rest API. How to do? As i don't want to use multi module maven project.
I think your best bet is using Maven's executions feature (i.e. "run" any plugin, multiple times, in your case maven-war-plugin).
So basically you "run" maven-war-plugin multiple times, and configure it differently for each war you want to make. Below is an example taken from SO (you need to tailor the configuration section for each execution.
Please be aware, that this is considered "last-resort" build design, and it is still advisable to use multi-module.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>list</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
<configuration>
<warName>myProj-list.war</warName>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</webResources>
<filtering>true</filtering>
<filters>
<filter>src/main/filters/list.properties</filter>
</filters>
</configuration>
</execution>
...
<!-- more executions -->
</execution>
</executions>
</plugin>
I am currently trying to exclude some resource from my built war.
I have read the documentation and the forums, and found a lot of informations.
Unfortunately nothing worked in my case...
I have an Eclipse Maven project, and if I'm right, maven-war-plugin is the default "war builder", so I have to override it in my pom.xml in order to exclude the resource from the buildt war.
I tried warSourceExcludes, packagingExcludes and webResources/excludes :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven.war.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warSourceExcludes>src/main/webapp/frontEndWorkspace</warSourceExcludes>
<packagingExcludes>src/main/webapp/frontEndWorkspace
</packagingExcludes>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/webapp</directory>
<!-- the list has a default value of ** -->
<excludes>
<exclude>**/frontEndWorkspace</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
Despite this configuration, I still have the frontEndWorkspace directory pushed in my Tomcat...
I wonder if it comes from the fact that I use it in my Eclipse environment?
Thanks in advance!
The parameters that you can use are packagingExcludes which is more generic (applies on the complete war structure) or warSourceExcludes if the files you want to exclude are specifically in the folder defined by the parameter warSourceDirectory (default being ${basedir}/src/main/webapp) (see here). It works easily when you know that it starts considering the folder structure of the war.
Example :
This will exclude all the files finishing by *.jsp contained in the folder WEB-INF of the folder defined by the parameter warSourceDirectory (default being ${basedir}/src/main/webapp) :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceExcludes>WEB-INF/**/*.jsp</warSourceExcludes>
</configuration>
</plugin>
This will exclude all the files contained in all the folders pouet contained in the war (but not the folder structure) :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<packagingExcludes>**/pouet/**/*.*</packagingExcludes>
</configuration>
</plugin>
The problem of your configuration <warSourceExcludes>src/main/webapp/frontEndWorkspace</warSourceExcludes> is that you start from the source folder which is wrong. You just have to remove src/main/webapp and add /** after frontEndWorkspace to have <warSourceExcludes>/frontEndWorkspace/**</warSourceExcludes> working (or <warSourceExcludes>frontEndWorkspace/**</warSourceExcludes>).
I am finding the same issue within Intellij IDEA which is using Maven 3.
The war file it generates contains the directory I am excluding.
UPD
Solution is to use syntax as below to eliminate the myFolder directory
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/resources</directory>
<excludes>
<exclude>**/myFolder/**</exclude>
</excludes>
</resource>
</webResources>
I'm trying to filter a Spring configuration file using Maven filtering. My POM is configured like this:
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<targetPath>WEB-INF/context</targetPath>
<directory>src/main/webapp/WEB-INF/context</directory>
<includes>
<include>applicationContext.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
...
and
<profiles>
<profile>
<id>desarrollo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<filters>
<filter>src/main/properties/dev.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>pruebas</id>
<build>
<filters>
<filter>src/main/properties/test.properties</filter>
</filters>
</build>
</profile>
...
It works great when invoking Maven directly.
Unfortunately, when hot-deploying the webapp in Tomcat 6 with Eclipse WTP and m2e it always picks the unfiltered version of applicationContext.xml. (The file applicationContext.xml in the folder target/m2e-wtp/web-resources/WEB-INF/context is never filtered)
I can't find any useful documentation on the subject. I'm not even sure if it is implemented in m2e.
Is something wrong with my configuration or this is an unimplemented feature?
Well, finally I got it.
First of all, I did what khmarbaise pointed out. I moved applicationContext.xml to the resources folder. War plugin webResources are meant to work with external resources, and filtering a file in the destination folder itself was not the best practice.
I updated the POM to reflect the new configuration
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
and
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<targetPath>WEB-INF/context</targetPath>
<directory>src/main/resources/WEB-INF/context</directory>
<includes>
<include>applicationContext.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
So, half of the credit to him.
But that's was not enough, it still didn't work.
I realized that Maven/m2e was indeed filtering my file, but it didn't get my defined properties files. After some testing I found out that m2e is ignoring the activeByDefault option in the profiles activation section.
So, I added my default profile to the project Maven configuration and then it worked
I had a similar problem with filtering the web.xml. I solved the problem by reimporting the whole project in eclipse.
The reason was a corrupt /.settings/org.eclipse.wst.common.component file. In this file the order of the files copied to the local web servers deploy directory is defined. For example:
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="liquidvote-rest">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="myapp"/>
<property name="java-output-path" value="/myapp/target/classes"/>
</wb-module>
</project-modules>
If the web.xml or application.xml exists in several directories it will be taken from the first directory found. Therefore its important that
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
is the first entry.
You will find more informations at http://wiki.eclipse.org/M2E-WTP_FAQ in the section "What is this web resources folder?"
Have you tried to put the resources under src/main/resources/WEB-INF/... instead of and configured the resources area to filter the resources instead of putting configuration into a non default maven location.
I just had a similar problem. My solution is not elegant and I am not proud of it, but let's say it is acceptable. In my case I have a spring boot mvc application with swagger application (for testers to test our API). The thing is we are using this app in two environments, so I created two profiles - dev and test. In dev env we would like to fire application from eclipse with just "run as" so the context path is blank (I know it can be set in spring java config, but it is not the only placeholder we would like to switch) and in test env the application is run in our customized version of tomcat... so the context path is the same as war file name.
and here is the problem - swagger is calling rest docs on this context path and it depends on spring profile. So we have a web resource that needs to be filtered. At first I tried to use m2e-wtp filtering:
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/scripts.js</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
...
it was working but only run in embedded in eclipse tomcat or from commandline java -jar it was not working with "run as" from eclipse.
The resource was filtered and I saw them in web-resource in target, but eclipse seems to be running on a source code directly or is making a copy I do not know... it cannot see filtered resources... so I thought that I will make something like this:
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<filtering>true</filtering>
<directory>src/main/resources/webapp/swagger</directory>
<targetPath>${basedir}/src/main/webapp/swagger</targetPath>
<includes>
<include>scripts.js</include>
</includes>
</resource>
</resources>
It is not most fortunate solution, because it is modifing code and not the target, but at least it is working. If anyone would have any suggestions how to make it work without code modifications I would be greateful.
Today I had similar problem when several jars were included into war. I set the filtering on,and compared the original jars with filtered. They seem to be same,but this is not true. I tried to rename jar to zip and I was not able to unpack the content due to corrupted structure inside jar(zip) whereas the original one were ok. It is also mentioned here adding filtering web resources where is said that filtering has to be set false to prevent corrupting your binary files.
I've tried everything described above without success. The files were filtered and generated correctly at the "m2e-wtp" folder, but for some reason Eclipse was copying files from "target/classes".
Thus, I've changed my pom.xml, changing the destination folder from "m2e-wtp" to "target/classes", like code ahead.
Important: everytime you need to run a maven build on project, you must change the pom in order to build de project.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<filters>
<filter>${project.basedir}/src/main/filters/${build.profile.id}/config.properties</filter>
</filters>
<webResources>
<resource>
<filtering>true</filtering>
<directory>${project.basedir}/src/main/resources</directory>
<targetPath>${project.basedir}/target/classes</targetPath>
<includes>
<include>*.properties</include>
<include>*.xml</include>
<include>META-INF/spring/*.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
I am trying to integrate GWT with SEAM. i followed the Docs and tried to run the
example as follows.
I created a GWT project, using Eclipse Galileo and created the classes as given in the example
I then added the Seam 2.0.2 jars to the build path
I compiled the application, using Google GWT Compiler using the eclipse UI.
Finally i ran the application.
First I would like to know whether the above steps are correct. After running the application I do not get the desired result.
Also is this the only way to integrate GWT with Seam ?
Update
I have got this example running using ant. But the aim of my exercise will be to run it via eclipse ui.
I created my own project by name GWTTest and tried to recreate the example in the Eclipse
UI. There are a few things that I have noticed. GWT Compile via Eclipse UI creates a directory by name gwttest inside the war file. Where as the directory structure created by ant is different.
In the example there is a piece of code in AskQuestionWidget getService functions as follows
String endpointURL = GWT.getModuleBaseURL() + "seam/resource/gwt";
How do I modify this code to suit my directory structure ?
We use seam+richfaces+gwt and it works very well. Although we build everything with maven, I suppose you can use ant as well. The general idea is to start the whole web application in GWT Development Mode. You don't have to compile everything (which takes a long time in case of GWT compiler). Development mode will compile requested resources on demand. By running GWT application this way, you can also debug client side code.
It is also possible to call GWT methods in response to seam actions.
Update:
I can elaborate on our solution a bit:
Maven
Your project should be configured with packaging: war. There are some official instructions on setting seam with maven (also richfaces):
http://docs.jboss.org/seam/2.2.1.CR2/reference/en-US/html/dependencies.html#d0e34791
http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/SettingsForDifferentEnvironments.html
For GWT add following sections to your pom.xml:
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<version>2.1.0</version>
<scope>provided</scope> <!-- prevents from including this in war -->
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<version>2.1.0</version>
<scope>provided</scope> <!-- prevents from including this in war -->
</dependency>
<dependency>
<groupId>pl.ncdc.gwt</groupId>
<artifactId>gwt-servlet-war</artifactId>
<version>2.1.0</version>
<type>war</type> <!-- adds gwt-servlet.jar to your war, but not to your classpath -->
</dependency>
<!-- build section -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/client/**/*.java</include>
<include>**/client/**/*.properties</include>
<include>**/shared/**/*.java</include>
<include>**/shared/**/*.properties</include>
<include>**/*.gwt.xml</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<directory>src/test/java</directory>
<includes>
<include>**/client/**/*.java</include>
<include>**/client/**/*.properties</include>
<include>**/shared/**/*.java</include>
<include>**/shared/**/*.properties</include>
<include>**/*.gwt.xml</include>
</includes>
</testResource>
</testResources>
<plugins>
<plugin> <!-- dirty hack for GWT issue #3439 - it is not really fixed -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>remove-javax</id>
<phase>compile</phase>
<configuration>
<tasks>
<delete dir="${project.build.directory}/classes/javax" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>1.3.2.google</version>
<configuration>
<extraJvmArgs>-Xmx512M</extraJvmArgs>
<gwtVersion>${gwt.version}</gwtVersion>
<modules>
<module>com.company.gwt.project.module.Module</module>
</modules>
<soyc>false</soyc>
<draftCompile>${gwt.draft.compile}</draftCompile> <!-- you can control this with profiles -->
<localWorkers>2</localWorkers><!-- in theory should speed things up on our quad CPU hudson -->
<style>${gwt.style}</style> <!-- you can control this with profiles -->
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>prepare-package</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>gwt-test</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<includes>**/*GwtTestSuite.java</includes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1</version>
<configuration>
<archiveClasses>true</archiveClasses>
<warSourceDirectory>src/main/webapp-empty</warSourceDirectory> <!-- just empty dir for workaround -->
<webResources>
<resource>
<directory>src/main/webapp</directory>
<excludes>
<exclude>app.*</exclude> <!-- name of you gwt module(s) - rename-to in gwt.xml -->
<exclude>WEB-INF/web.xml</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/webapp</directory>
<includes>
<include>WEB-INF/web.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
This configuration should produce war with both - seam and gwt compiled. If you want to use such project in development mode put also this in pom.xml:
<dependency>
<groupId>com.xemantic.tadedon</groupId>
<artifactId>tadedon-gwt-dev</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
And add -server com.xemantic.tadedon.gwt.dev.JettyLauncher to your google web application launcher. This is maven friendly jetty launcher which might be necessary in some situations.
I hope it will help you. Are you interested in communication between gwt and richfacaes application?
If you want, take a look at <SEAM_HOME>/examples/remoting/gwt. From there, run (Make sure you have installed ANT before using it)
ant
Here goes its readme.txt file
You can view the example at:
http://localhost:8080/seam-helloworld/org.jboss.seam.example.remoting.gwt.HelloWorld/HelloWorld.html
GWT: If you want to rebuild the GWT front end, you will need to download GWT, and configure build.properties to point to it. You can then run "ant gwt-compile" from this directory. It is pre-built by default. If you want to use the GWT hosted mode, well, read all about it from the GWT docs !
In my project, I have a resources directory (src/main/resources) that contains properties and XML files.
I want to filter only the properties files, but not any others kind of files (XML for example). Thus, I've set this in my pom.xml:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
</build>
This is working well when I run a Maven 2 package command, i.e. both XML and properties files are included in my final JAR, and only properties files have been filtered.
However, as I want to include this project in Eclipse, when I run the command mvn eclipse:eclipse, and import the project, then I have a problem with the source declared in my project properties.
In the "Java Build Path" option of Eclipse for my project, in tab "Source", I see the src/main/resources directory, but Eclipse also add filters which say to exclude all java files (Excluded: **/*.java) and include only properties files (Included: **/*.properties).
In the .classpath file generated, I get this line:
<classpathentry kind="src" path="src/main/resources" including="**/*.properties" excluding="**/*.java"/>
This way, the JAR built by Eclipse is not correct as all my XML files are not in the JAR.
How can I solve this problem?
Edit, regarding this page, I've added this in my pom.xml:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.6</version>
<configuration>
<sourceIncludes>
<sourceInclude>**/*.xml</sourceInclude>
</sourceIncludes>
</configuration>
</plugin>
</plugins>
However, the .classpath generated is not modified with the adequate information...
Edit again.
The addition in my previous edit works only for version 2.6.1+ of the Eclipse plugin, not for 2.6. So, I've tried with version 2.7. However, I don't know how to force the Eclipse plugin to not define the including attribute:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.7</version>
<configuration>
<sourceIncludes>
<sourceInclude>*</sourceInclude>
</sourceIncludes>
</configuration>
</plugin>
</plugins>
If I run the mvn eclipse:eclipse command, I get the following error:
Request to merge when 'filtering' is not identical. Original=resource src/main/resources: output=target/classes, include=[**/*.properties], exclude=[**/*.java], test=false, filtering=true, merging with=resource src/main/resources: output=target/classes, include=[], exclude=[**/*.properties|**/*.java], test=false, filtering=false
Well maven-eclipse-plugin is very bugy :( and we use version 2.5. The solution we found is copy resources to different folder. For regular maven bulid we use default filtering but for eclipse we have special profile. Here is maven-eclipse=plugin configuration in this profile:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources-step1</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>initialize</phase>
<configuration>
<outputDirectory>${project.build.directory}/for-eclipse/resources</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
<execution>
<id>copy-resources-step2</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>initialize</phase>
<configuration>
<outputDirectory>${basedir}/src/main/resources</outputDirectory>
<resources>
<resource>
<directory>${project.build.directory}/for-eclipse/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
Of course you must modify include/exclude section for your needs.
I did some testing with the maven eclipse plugin 2.6, 2.5.1, 2.7 and 2.8-SNAPSHOT and none of them is indeed producing the expected result.
The only workaround I've been able to find is to use another directory for the resources you don't want to filter. Something like this:
...
<build>
<resources>
<resource>
<directory>src/main/resources1</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources2</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
I agree that this is ugly. But at least, it produces a .classpath with the following entries:
<classpathentry kind="src" path="src/main/resources1" including="**/*.properties" excluding="**/*.java"/>
<classpathentry kind="src" path="src/main/resources2" including="**/*.xml" excluding="**/*.java"/>
That should allow you to deploy on Tomcat.
By the way, I wouldn't use the version 2.7 of the plugin because it's not working (see this thread). The version 2.6 may not produce the expected output but at least, it works.
Use properties to have Eclipse and Maven build into different directories. Now you can use Eclipse to quickly develop your code and use Maven to deploy it as a JAR.
I suggest that you either the mvn package goal as an external tool from Eclipse. I don't think that Eclipse can handle complex Maven workflows.
Even the m2eclipse plugin, which I use and highly recommend, has troubles with complex workflows.