Prevent maven to copy dependencies to WEB-INF\lib folder - maven

I have this dependency in the pom.xml:
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-testing</artifactId>
<version>${appengine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>${appengine.version}</version>
<scope>test</scope>
</dependency>
However although the scope is "test" the jars are still copied to the WEB-INF\lib folder:
src\main\webapp\WEB-INF\lib

I see 2 possible scenarios here.
1) These dependencies are somewhere referenced (directly or not) with compile or runtime scope besides their test-scoped use. Then, this wider scope is effectively used to satisfy all the needs about them.
2) You do (maybe unconsciously) some dependency processing hacking using Maven Dependency Plugin or stuff like that that do this mess.
And one issue at the end: I assume that this src/main/webapp/WEB-INF/lib directory is in fact empty (possibly doesn't even exist) and it's your mistake. As #Ryan said in his comment, all the libs (and any other build artifact) should land at target directory.

Related

javax/inject/Inject.class in lib/javax.inject-1.jar is hidden by lib/javax.inject-2.5.0-b42.jar on onejar executable

I am attempting to create an atomic executable jar (i.e. no dependencies outside of the jar).
To do this I have added a com.jolira:onejar-maven-plugin in my pom.xml. This seems to do the job, but when I execute the jar I get the warnings:
JarClassLoader: Warning: Null manifest from input stream associated with: lib/javax.inject-1.jar
JarClassLoader: Warning: javax/inject/Inject.class in lib/javax.inject-1.jar is hidden by lib/javax.inject-2.5.0-b42.jar (with different bytecode)
JarClassLoader: Warning: javax/inject/Named.class in lib/javax.inject-1.jar is hidden by lib/javax.inject-2.5.0-b42.jar (with different bytecode)
It seems that my dependencies are pulling in both javax.inject-1.jar and javax.inject-2.5.0-b42.jar. To verify this I checked and both have/are being downloaded from the repository. I certainly don't have both listed in the dependencies, so there must be some implied dependency AFAICS.
Anyone know if there is a way to exclude just one jar from a maven dependency, or alternately to prevent onejar-maven-plugin from including it in the executable jar?
Is there a better way to create an atomic (or some call them fat) jar where the java loader can actually load from an embedded jar. I've tried all day with various different recipes and onejar was the only one that actually got the loaded to work.
After some playing I found Alex's solution to be correct, just that I had put the exclude in the wrong place. The solution is to put it here:
<dependency>
<groupId>org.glassfish.jersey.inject</groupId>
<artifactId>jersey-hk2</artifactId>
<version>2.26</version>
<exclusions> <!-- exclude exclude javax.inject-1.jar -->
<exclusion>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</exclusion>
</exclusions>
</dependency>
Just putting this here for future.
I solved the problem in this way:
(It's for project's dependency which has javax.inject in its own dependencies)
<exclusion>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</exclusion>

Where to use which scope in maven pom.xml

I have a project "framework-ws" that contains 3 modules (api, dictionary, webapp).
This project is used has a parent project for multiples other web-services project.
For example, the project "core-ws" has "framework-ws" for parent. It also contains 3 modules (api, dictionary, webapp).
Each of these modules has the framework as dependency.
core-ws-api => framework-ws-api
core-ws-dictionary => framework-ws-dictionary
core-ws-webapp => framework-ws-webapp
(subproject => dependency)
Now I have other dependencies (lombok for example) that is used in every project (framework + child-project).
I don't understand where I need the declare this dependency.
In the parent project with a "provided" scope, and in each
child-project without scope
In the parent project with no scope, and no dependency in each
child-project
Another solution that I didn't think of
The second solution seems cleaner because I don't need to duplicate the dependencies in each pom.xml. But I don't know if it's the best practice.
EDIT : Here is a picture of projects structure.
In your parent pom use a dependency management section see https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
</dependencyManagement>
Then in your child pom you will use the dependency but not specify a version, i.e. the version will be specified in the parent once for all children. You still need to include the dependency in each module.
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
</dependency>
</dependencies>
In terms of scope read this https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope the default scope is compile which is what you will usually use. I think you are confused about the meaning of scope from readinf your question.

Vaadin std prod project includes vaadin-client-compiler and jetty?

I get vaadin-client-compiler artifact (which brings Jetty with it) included with my production project. Am I supposed to ?
To reproduce I'm starting from scratch and letting Maven generate a Vaadin multimodule project for me:
mvn
-DarchetypeGroupId=com.vaadin
-DarchetypeArtifactId=vaadin-archetype-application-multimodule
-DarchetypeVersion=7.6.2
-DarchetypeRepository=http://repo.maven.apache.org/maven2/
-DgroupId=com.acme
-DartifactId=VaadinTest1
-Dversion=1.0.0-SNAPSHOT
-Dpackage=com.acme.vaadintest1
-Dbasedir=D:\\dev\\java
-DthemeName=mytheme
-DwidgetsetName=MyAppWidgetset
-DuiName=MyUI
-Darchetype.interactive=false
--batch-mode archetype:generate
Then in the parent project I execute:
mvn -Pproduction clean install
After this is done I look into the WAR file generated in the "xxx-production" project and notice it contains vaadin-client-compiler, Jetty, and what not.
I've found this ticket and by looking at the last comment it seems I shouldn't have anything like that in my production WAR. I hesitate to change my POMs as they are generated by the archetype and I guess at some level supposed to represent kind of a Vaadin best-practice approach. I wouldn't want to second guess that. Or ?
The problem with these artifacts being part of the classpath is that
it balloons the size of the WAR
it creates some problems wrt Atmosphere which supposedly gets confused because it finds Jetty on the classpath. (Atmosphere is used under the hood by Vaadin)
The result is that you'll get SEVERE error like this in the log when deploying on Tomcat 8:
14-Feb-2016 16:42:30.368 SEVERE [localhost-startStop-1] org.atmosphere.cpr.DefaultAsyncSupportResolver.newCometSupport Failed to create comet support class: class org.
atmosphere.container.JettyServlet30AsyncSupportWithWebSocket, error: null
To sum up:
Is it correct that I'm not supposed to have these artifacts in a
Vaadin 7.6.2 production project ?
How to solve ?
I believe I've found the answer. It seems Vaadin team was/is fully aware of this but it is kind of a left-over from the old days when there was some kind of annoying bug.
In your xxx-widgetset project you'll see something like this in the POM for that project:
<dependencies>
<!-- Versions for these are configured in the parent POM -->
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client</artifactId>
<!-- TODO this should have scope provided once http://dev.vaadin.com/ticket/14788 is resolved -->
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiler</artifactId>
<!-- TODO this should have scope provided once http://dev.vaadin.com/ticket/14788 is resolved -->
<!-- <scope>provided</scope> -->
</dependency>
... you'll see more deps here if you've added
... Vaadin add-ons to your project.
</dependencies>
See the TODO comments ??
Well, it just so happens that the bug mentioned in ticket 14788 doesn't happen anymore, at least not on 7.6.2. So you can now safely do what the TODO comment says.
This has reduced my WAR size by 50-70 pct.
It seems to me there's no longer any good reason why this archetype generation doesn't actually do what TODO comment says. Currently you'll have to manually correct it every time you generate a new project skeleton.
If you work with a different webserver (in your case Tomcat 8) you don't need the provided jetty-plugin.
As the archetype has some jetty-dependencies you can exclude them with the
exclusions tag in the Maven POM file.
Example
<groupId>com.vaadin</groupId>
<artifactId>vaadin-client-compiler</artifactId>
<version>${vaadin.version}</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-util</artifactId>
</exclusion>
</exclusions>
Moreover delete/comment out all unnecessary "jetty" dependencies found in the module POM files.

Why order of Maven dependencies matter?

I thought that the order of Maven dependencies doesn't matter before and regard this as a pro of it. And this is my old pom.xml's dependencies:
<dependencies>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-spring3</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.19</version>
</dependency>
</dependencies>
It works well, and today I wanna move spring dependency to the bottom so that those jersey related can be together. However then I can no longer make it working, my Jetty complains:
[ERROR] Failed to execute goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run (default-cli) on project mtest: Execution default-cli of goal org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run failed: A required class was missing while executing org.eclipse.jetty:jetty-maven-plugin:9.3.0.M1:run: org/apache/commons/logging/LogFactory
That is really confusing, so do I have to concern about dependencies order? How do I know the correct order?
The order of dependencies does matter because of how Maven resolves transitive dependencies, starting with version 2.0.9. Excerpt from the documentation:
(...) this determines what version of a dependency will be used when multiple versions of an artifact are encountered. (...) You can always guarantee a version by declaring it explicitly in your project's POM. (...) since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.
To expand upon the other answer (which states that the declaration order affects Maven's dependency mediation for transitive dependencies), there are a few tools you can use:
mvn dependency:tree [-Dscope=[runtime|test]] will show you what dependencies will be available for the selected scope. See here for details
mvn dependency:build-classpath gives you order in which dependencies are available on your classpath (if two or more classpath entries have the same class, the earlier one wins). See here for details
I don't know much about your situation, but it's often the case that you wind up with the wrong version of 1 or more jars at compile/runtime. Declaring your own version of the library in question or locking down the version with <dependencyManagement> are options here.
Now to answer your other question - how do you know what the right order is when declaring dependencies?
My suggestion - the right declaration order is the one that gets you the versions of the dependencies you want, in the order you want them in. Use the tools above to check your dependencies, and tweak the declared order if necessary.
Note that most jars contain disjointedly-named classes, so the exact order in which jars appear on your classpath is usually not that important. The only exception I've noticed is some jars in SLF4J which intentionally shadow classes from the other logger libraries it's intended to replace.

How to get the source code for the javax:javaee-api-6.0.jar

I use the javax:javaee-api-6.0.jar maven artifact.
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
I would like to download its source code with the dependency:sources mvn goal.
I was looking for the sources in the official maven repositories, but I still can't find it.
Could you give me a bit of advice on how can I achieve my object?
Thank you.
Mich is correct.
The purpose of the javaee-api module is to satisfy compile-time dependencies (That is why the Maven scope is set to provided). The module contains interface declarations (or contract) which must be satisfied by the J2EE container you plan to use.
If you really need/want to see the source code, I'd suggest taking a look at one of the open source J2EE containers.
see if these are any good and if they work for you http://repo1.maven.org/maven2/org/apache/openejb/javaee-api/
Try this: (it has sources attached)
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>3.0.3.Final</version>
<scope>provided</scope>
<type>pom</type>
</dependency>
It pulls in a huge number of dependencies, but as they are all provided you do effectively not alter your artifact.

Resources