Only include jar in gwt compile and not in WEB-INF/lib - java

I'm wanting to use the slf4j-gwt library https://github.com/FinamTrade/slf4j-gwt
But I only want to include it in my gwt compile, not in the war that is built as I'm having issues with tomcat startup calling GWT.create...
Is there a simple way to do this? I would expect the maven gwt compiler plugin to support this but I can't see that it does.

<scope>provided</scope> or <optional>true</optional>.
Neither one is semantically satisfying but that's what Maven gives us.
That being said, there are many reasons why you should rather split your project into several modules, with one module containing only client-side code and producing JavaScript and associated resources (through the GWT compiler) and one with only server-side dependencies; that way you never risk putting client-side classes or dependencies into your WAR.
See http://blog.ltgt.net/announcing-gwt-maven-archetypes-project/ for more about it, and sample projects (in the form of Maven archetypes).

If I understand you correctly, you could exclude the artifact when building the WAR. Something like
<build>
...
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.5</version>
...
<configuration>
<packagingExcludes>
WEB-INF/lib/slf4j-gwt-*.jar
</packagingExcludes>
</configuration>
</plugin>
...
</build>
should work.
Cheers,

Related

Intellij not recognising symbols in Maven POM

I'm working with a project that has, historically, been supported and developed in an Eclipse environment. I'm hoping to move this over to Intellij, and I'm currently using the full (Ultimate) package.
There are a few intricacies of the build process that don't appear to be working, which relate to selectively building the resources for the project. I could work around this, but would rather try and understand why IntelliJ and Eclipse are building the same project in a slightly different way.
I've noticed in my parent POM that the following code has an issue:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<includes>
<include>**/*.js</include>
</includes>
<nosuffix>true</nosuffix>
</configuration>
</plugin>
Intellij is saying element includes is not allowed here' and itcannot resolve symbol 'include'`.
As far as I can see, the declarations are valid and in the correct place, and maven appears to be set up as required with the maven plugins installed as required too. The POM uses the http://maven.apache.org/maven-v4_0_0.xsd schema.
This kind of stuff has generally been left untouched for a number of years, but I can't see why it is having issues with this particular symbol/declaration?
As above, I've checked the plugins, Maven settings, all the usual suspects. Another of the plugins uses <excludes> with no errors, which makes it a bit more of a puzzle to me?
Can anyone help?

Why is Maven including multiple versions of the same dependency?

I have a Maven java web app (.WAR) project that includes several libraries, including the Wicket libraries (but I don't think the problem is wicket itself, but rather with maven).
Here's the problem: even tho I only include Wicket 6.20.0, the resulting .WAR contains two copies of the Wicket libraries: 6.20.0 and 6.18.0, as you can see in this screenshot:
Thinking of some conflicting imports I printed the dependency tree using the:
mvn dependency:tree
commnad... but there is no mention of Wicket 6.18.0 in the dependency tree! I also double-checked using Eclipse's "dependency hierarchy" view and I can confirm there's no trace of that import.
I even did a search for string "6.18.0" across the entire workspace with Eclipse, but it's nowhere to be found!
How can I find out what is causing the inclusion of that duplicate version of the library?
Maven doesn't work in this way.
The resolution of more than one dependency with the same artifactId and groupId but with a different version will result to a single dependency (the version used is no determinist).
The presence of two artifacts with the same artifactId and groupId but with two distinct versions in a same lib folder of the WAR is probably related to one of these :
you don't execute mvn clean package but only mvn package.
your use a bugged version of the Maven war plugin. Try to update it to check that.
you have a Maven plugin that copies Wicket jars 6.18.0 in the WEB-INF/lib folder of the target folder during the build of the component.
the maven WAR project you are building has as dependency an artifact of type WAR. In this case, the dependencies of the WAR dependency are so overlaid in the WAR project that you are building.
An interesting Maven issue about duplicated JAR because of WAR dependencies :
JARs with different versions can be in WEB-INF/lib with war as dependencies
Your answer and your comment indicate that actually you have a WAR dependency in your build.
Unfortunately, there is not really a good and long term effective solution to bypass this limitation.
As said in my comment, using the packagingExcludes property of the maven war plugin is a valid workaround for the actual issue :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- ... -->
<packagingExcludes>WEB-INF/lib/wicket-*-6.18.0.jar</packagingExcludes>
</configuration>
</plugin>
But beware, using that will do your build less robust through the time.
The day where you update the version of the WAR dependency and that in its new version, it pulls again a different version of wicket, you have still a risk to have duplicate jars with two distinct versions in your built WAR.
Using the overlay feature by specifying the overlay element of the maven-war-plugin is generally better as it focuses on the overlay applied for the war dependency. It fixes the problem early.
As a result, you could define to exclude any wicket JARs from the WAR dependency :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>2.4</version>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<overlays>
<overlay>
<groupId>com.whatever.youlike</groupId>
<artifactId>myArtifact</artifactId>
<excludes>
<exclude>WEB-INF/lib/wicket-*.jar</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
This way is better but this is still a workaround.
The day where the dependency WAR is updated and that it pulls new dependencies (other than Wicket) that are declared in your actual build but with different versions, you may finish with the same kind of issue.
I think that declaring a dependency on a WAR artifact should be done only as we don't have choice.
As poms and projects refactoring are possible, introducing a common JAR dependency which the two WARs depend on and that contains only common sources and resources for the two WARs makes really things simpler.
Well, I figured it out while poking around.
I had a dependency of type "war" in the project:
<dependency>
<groupId>com.whatever.youlike</groupId>
<artifactId>myArtifact</artifactId>
<version>1.0.7-SNAPSHOT</version>
<type>war</type>
</dependency>
Apparently (I wasn't aware of this, my fault here) these type of dependencies will include themselves in the classpath by copying all libs to the main WAR /libs folder, but these will NOT show app in the dependency tree / dependency hierarchy.
I solved by configuring an explicit exclusion in the WAR plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- ... -->
<packagingExcludes>WEB-INF/lib/wicket-*-6.18.0.jar</packagingExcludes>
</configuration>
</plugin>
Use clean install and the double dependency will probably be gone.
Because other libs can use same libs but different version or you tried different version and didn't make mvn clean
The command mvn dependency:tree is telling you the correct information - what you are looking at here is an eclipse / build issue.
Clear out all the target and build areas in your project. If need be, check it out from source control to a new folder.
Alternatively you can build your project in IntelliJ IDEA, and see if you get the correct dependencies (most likely you will).

Maven War Plugin : Specify Regular Expression to exclude libraries within web-inf/lib

As we have around 8 projects which are having same dependencies and getting deployed to tomcat. Because of memory it used to consume to load all these classes we decided to move all the common jars to custom tomcat base installation and make individual wars having only the required custom libraries.
For this to be done, we need to alter the maven war plugin configuration where we can specify the regular expression for excluding libraries like below :
%regex[WEB-INF/lib/TODO]
I would like some help in figuring out the exact regular expression which i can put in here to avoid all the common libraries and include the required custom libraries. below are some of the custom library names which needs to be part of WEB-INF/lib within war:
xmax-common.jar
xmax-services.jar
xmax-model.jar
momentum-core.jar
Your suggestions are greatly appreciated.
If using regexp to include these libs, try something like:
<configuration>
<packagingExcludes>%regex[WEB-INF/lib/(?!xmax)(?!momentum).*.jar</packagingExcludes>
...
</configuration>
You may try to include only needed packages instead of exclude unnecessary libs
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<packagingIncludes>
WEB-INF/lib/xmax-common.jar,
WEB-INF/lib/xmax-services.jar,
WEB-INF/lib/xmax-model.jar,
WEB-INF/lib/momentum-core.jar
</packagingIncludes>
</configuration>
</plugin>

How to configure custom maven project structure

I know that typically maven structure is like this:
pom.xml
src
- main
- web
- WEB-INF
However, I have a project which has the following structure
src
- main
web
- WEB-INF
The latter of the two above currently does not use maven. I've started using maven for this project locally by making the structure conform to the maven standard. However, I now want to automatically build this project from jenkins by getting it out of the source control (svn). So I would like to just add a pom.xml which is aware of the fact that web isn't inside src
Is this possible to do with maven?
You can configure the maven-war-plugin to use another warSourceDirectory but as Jeff Storey explains in his answer it is really not recommended.
This is how you would do it:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warSourceDirectory>web</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
One of several problems is for example that the maven-jetty-plugin will not run out-of-the-box. It will by default look in src/main/webapp so that has to be configured.
You might not use the maven-jetty-plugin but you get the idea.
Using the maven war plugin properties, you can set the warSourceDirectory property http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html (I'm not sure exactly what problems you're having, so this may or may not solve your specific problem).
However, maven is very opinionated and I would strongly recommend using the expected maven structure. Other plugins may give you unexpected problems down the road, and maven life is generally a lot easier when you follow their conventions.

Moving to Maven from GNUMake

I've been a long time user of the Make build system, but I have decided to begin learning the Maven build system. While I've read through most of the online docs, none seem to give me the analogies I'm looking for. I understand the system's lifecycle, but I have not see one reference to compile step dependencies. For example, I want to generate a JFlex grammar as part of the compile lifecycle step. Currently, I see no way of making that step a pre-compile phase step. Documentation seems to be limited on this. In general, the concept of step dependencies seem to be baked into Maven and require a plugin for any alteration. Is this the case? What am I missing, because currently the Maven build system seems very limited in how you can setup compilation steps.
You can do anything in Maven. It generally has a default way to do each thing, and then you can hook in and override if you want to do something special. Sometimes it takes a lot of Stack Overflowing and head scratching to figure it out.
There is even an official JFlex Maven plugin.
Whenever possible, find someone who has made a Maven plugin do what you want. Even if it isn't 100% right, it may at least give you an idea on how to make maven do something.
Minimal configuration
This configuration generates java code of a parser for all grammar files (.jflex , *.jlex , *.lex , .flex ) found in src/main/jflex/ and its sub-directories. The name and package of the generated Java source code are the ones defined in the grammar. The generated Java source code is placed in target/generated-source/jflex , in sub-directories following the Java convention on package names.
pom.xml
<project>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>de.jflex</groupId>
<artifactId>jflex-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- ... -->
</build>
<!-- ... -->
</project>
This feels like the maven way to do things. Put your stuff in the right folders (src/main/flex), and this plugin will automatically build it into your project. If you want to do fancier custom stuff, there are some options. but Maven is all about favoring convention over configuration.
To be frank I think that your current mindset maps much better to ant than to maven, and I would suggest starting with that.

Categories