Cannot find maven dependencies when importing from another module - java

I have a maven project with multiple submodules.
I have a root pom file in which I have the jackson dependency
<dependency>
<groupId>fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
I have the jackson dependency in one module called 'api'.
<dependency>
<groupId>fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
I have a new module named 'client' in which I import the maven dependency of 'api'
<dependency>
<groupId>abc.com</group>
<artifactId>api</artifactId>
<version>0.1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
I am using the following command to compile.
mvn -Djackson.version=2.4.4 compile
I am getting a compile error if I try to import jackson libraries to the client module unless I add the jackson dependency explicitly again to the client module
Why is adding the api dependency not sufficient as it already contains the jackson dependency

You define the jackson dependency in api as provided, so it is not transitive:
provided
This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.
- https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope (emphasis added)

Related

Dependency of Type "POM"

I am trying to get an ESB system running using ServiceMix and ActiveMQ. But even before I get that far, I had a question about dependency types of POM. I got the maven dependency as:
<!-- https://mvnrepository.com/artifact/org.apache.servicemix/servicemix -->
<dependency>
<groupId>org.apache.servicemix</groupId>
<artifactId>servicemix</artifactId>
<version>7.0.1</version>
<type>pom</type>
</dependency>
Now when I run "clean install" on the the project in which I included this dependency, I don't see any of the activeMQ jars being copied in the classpath or available for compilation (I have copy-dependency written, so I can see what jar files are included). In this case, do I still have to explicitly mention the activeMQ dependency in my pom file? Like:
<!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-core -->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
</dependency>
Any guidance would be appreciated. This ServiceMix is frustrating with the lack of documentation.
If you put a dependency of type pom into your <dependencies>, Maven will use the content of the POM as transitive dependencies. So everything in that POM will become a part of the classpath unless it has something like test scope or its version is overridden by some other part of the POM.
Putting a POM into the <dependencyManagement> is a different thing. Note that scope import is only for <dependencyManagement>.

Replace glassfish javax.servlet.jsp in jetty

The default jsp dependencies changed from glasfish to apache in jetty version 9.2.
http://www.eclipse.org/jetty/documentation/current/configuring-jsp.html
I have tried to replace all jsp dependencies in a project to apache but I have not succeeded to replace javax.servlet.jsp to a working apache dependency:
groupId: org.glassfish.web
artifactId: javax.servlet.jsp
version: 2.3.2
So are there any alternative dependency which I should use instead or is org.glassfish.web:javax.servlet still the best dependency to use when packaging a runnable war?
The exception thrown when removing the javax.servlet.jsp dependency is:
java.lang.ClassNotFoundException: org.apache.jasper.servlet.JspServlet
You only need the api libraries on the build time classpath. These should be marked with scope 'provided' which indicates that they should not be bundled in any generated artifact (WAR) as they will be provided by the Servlet container at runtime.
Thus in your pom you should have the following:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
In the absence of any other container specific behaviour, the above change makes your application portable across all containers compliant with the relevant version of the Servlet specification.

Maven war plugin: Is all dependencies specified in pom get added to war?

I use maven-war-plugin in my pom to build my Vaadin application. My question is, if I added an unnecessary dependency (dependent library is not actually used in code) to my pom, Will maven-war-plugin still bundle the dependency into the war file it generates?
The answer to your question depends on the scope you specify in the <dependency> tag. Consider the following dependency tag:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
The provided scope tells Maven to use the log4j JAR when compiling but to exclude it from the build, so it would not appear in your WAR. If, on the other hand, you used a scope of compile or runtime, then it would appear in the WAR.
If you don't specify any <scope>, then the default is compile, which means that the depedency will appear in the build output.

What is the difference between the GeoIP2 MaxMind pom and my local one?

I'm following this guide:
https://github.com/maxmind/GeoIP2-java
It says:
We recommend installing this package with Maven. To do this, add the dependency to your pom.xml:
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.2.0</version>
</dependency>
There is also pom.xml file in the Git repository of GeoIP2 which is much longer - what is the difference between them?
Cited from the official homepage:
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
Think of the pom.xml as the heart of Maven. In the file you can specify dependencies (most typically jar files), and other information, such as how the project should be built. Without digging to deep into this, one of Maven's strengths is that it manages the dependencies of projects.
To answer your concrete question, GeoIP2 manages its dependencies using Maven. This section of its pom.xml defines them:
<dependencies>
<dependency>
<groupId>com.maxmind.db</groupId>
<artifactId>maxmind-db</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client</artifactId>
<version>1.20.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
</dependencies>
By using Maven in your own project, you will only need to add the one dependency to GeoIP2. Maven will then search for the dependency in a repository, typically the Maven Central Repository if Maven isn't configured to use another. It will also automatically download all other needed dependencies (transitive dependencies), in this case it would be the dependencies listed above, plus any other dependencies those in turn depend on, and so on.
So, a short recap: Without a dependency management tool like Maven, you would need to manually make sure you have all the correct dependencies on the classpath. Maven fixes this for you.

Maven dependency management issue

I have a multi pom project, the parent pom imports an external module as such. This external module uses certain Saxon classes, I import it as such:
<dependency>
<groupId>org.test</groupId>
<artifactId>test-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
In the child pom, we import it as such:
<dependency>
<groupId>org.test</groupId>
<artifactId>test-framework</artifactId>
<scope>provided</scope>
</dependency>
I was under the impression that if you imported it as such in the parent pom, all the transitive dependencies of the external module would be imported. When I'm building my project the saxon classes are missing and the only way I can get them to appear is to explicitly pull them down in my pom. Doesn't that defeat the point of transitive dependency resolution. am I going to have explicitly pull down all transitive dependencies in any project that imports that external module?
Have you tried changing the scope of the dependency?
<dependency>
<groupId>org.test</groupId>
<artifactId>test-framework</artifactId>
<scope>compile</scope>
</dependency>
This should do the job.
Read on dependency scopes here:
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

Categories