Maven - installed to local repo, not getting transitive dependencies - java

I have a maven project that I'd like to share with several of my other projects. It has some custom code, and then a few dependencies on things like log4j, jasypt, etc.
I build it and install it to my local maven repo. I can see it's successfully put there. Looking at .m2/repository/derp/Foo/1.0 it has a .pom with all its dependencies defined.
I can also define it as a dependency in my higher level projects, and it compiles.
<dependency>
<groupId>my.group</groupId>
<artifactId>Foo</artifactId>
<version>1.0</version>
</dependency>
I can see the Jar in my 'Maven Dependencies' in eclipse, and expanding that jar I can see it has the correct pom with dependencies in META-INF/maven/derp/Foo/pom.xml.
But my top level project above Foo isn't getting the dependencies that Foo needs. I get runtime exceptions, and I can see none of the transitive dependency jars are in my maven dependencies in eclipse.
What do I need to do to make sure Maven knows to look at the Pom for Foo in my local repo, so it will get all the transitive dependencies it needs?
----- edit -----
Answer to comment below, they are defined like this, with the dependencies tag at the top level under the project tag.
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.2</version>
</dependency>
etc...
These are the jars that maven correctly finds when I am just building and running this Foo project, but maven doesn't include these jars if a project depends on Foo, (Bar), and I find out when I try to run Bar.

What does "top level project above Foo isn't getting the dependencies" mean?
Anything "above" Foo in the build reactor should depend directly on Foo as you have stated. The <dependency/> specified will resolve to Foo's dependencies (within the scope that Foo specifies).
Without understanding the specifics of your project, it's improbable that we can to help you any further.
Some possible common situations:
You expect to be able to get access to test scoped dependencies in some non-test phase of execution. Just not true.
You expect that specifying a dependency on an artifact causes the java runtime to load those dependencies for you automagically. That's also not true. You'll want to invoke the exec:java goal on the maven exec plugin and specify your desired resolution scope within the <configuration/>, possibly also for that <execution/>.
You've mistaken <dependencyManagement> for <dependencies>. This happens way more than I would have expected.

Related

At which path and when the Transitive Dependencies with the scope test in the maven project are downloaded

I am using maven in my project. In my project, I am using a Java library testcontainers-keycloak. In the pom.xml of that library https://github.com/dasniko/testcontainers-keycloak/blob/2.1.2/pom.xml, many dependencies have been mentioned. I have noticed one thing for the dependencies with the <scope>test</scope> . I am unable to see these dependencies in my .m2 directory. I was curious about it. Can any one tell me that how maven manages the dependencies with the <scope>test</scope> . In which directory, they are downloaded. I know that test scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases but I do not know that where and when maven downloads such dependencies before executing our tests.

Pom.XML Maven Build Dependency of POM Only Looking for Jar

GIVEN:
I have an in house tool built with gradle that includes a dependency that is only a POM file which in turn then includes a bunch of other dependencies. No jar for this particular dependency by itself. The tool builds.
I have a maven project with a pom.xml file that I want to include this tool in because of all the company specific methods needed for some processes. I added the dependency with the type of pom and when I build it fails.
ERROR:
[ERROR] Failed to execute goal on project <MYPROJECT>: Could not resolve dependencies for project <MYPROJECT>:jar:0.0.326: <com.pom.only.dependency>:jar:7.0 was not found in <Company Repo where this POM file exists> during a previous attempt. This failure was cached in the local repository and resolution is not reattempted until the update interval of <company repo> has elapsed or updates are forced
REQUEST:
I have tried making the tool a fat jar in the hopes it would not need this. But it does. The my project builds without this tool jar so I know it is this jar that brings in the dependency. I just have no idea how to resolve this.
ALMOST CODE EXAMPLE
Because of company specific, I can not put the exact POM code but I can put what it looks like removing company specific stuff.
<dependency>
<groupId>com.group</groupId>
<artifactId>tools-app</artifactId>
<version>1.0.11</version>
</dependency>
<dependency>
<groupId>com.group</groupId>
<artifactId>pom only dependency</artifactId>
<version>7.0</version>
<type>pom</type>
</dependency>
So tools app is the one that I am pulling it. It is the gradle build and uses the pom only dependency without any issue. If I pull this into a gradle app it works fine and builds. However, in the app that has this in the pom, if fails for above. So I add the dependency for the pom only dependency and mark it as type pom but still get the error.
So for my situation (and not the best solution), I went into the dependency that has only a pom and pulled the dependencies out of there and built. It worked. But feel there should be a way to make it work without having to do this.

Circular dependencies in Maven and horrible structure of project

I have a problem with maven. I have a huge multi-module project with limited possibilities to change the structure of it.
So, let's say I have 3 modules: A,B,C.
A is a parent of B and C.
C uses classes from B, so we have a B as a dependency in C's POM file.
B doesn't need to have a C as a dependency to be successfully compiled.
For now, there aren't any problems.
Unfortunately, B uses C during the runtime (spring, ioc, ...), so someone added C as B's dependency, so we have a horrible cycle in Maven. Build finishes with failure (something like "cycle detected" in log).
I would like to keep it this way (provide somehow C dependency in B module) as I need to compile and deliver B with all needed JAR archives (including JARs from C).
Can I somehow build C and copy its JARs to B's target directory after the full compilation of B? Is there a plugin or tool which can be used by maven to do this?
If this post is not clear, I will try to describe it in more details.
Thanks in advance ;)
It sounds like there are two issues:
How to tell Maven about a runtime-only dependency between artifacts.
How to get Maven to leverage the dependency to pull together all the relevant dependencies.
Maven has a feature of dependency management that allows you to inform maven of such nuances using the "scope" element of the dependency element. In this case, I think you want
<scope>runtime</scope>
See the documentation. In particular:
runtime - This scope indicates that the dependency is not required for compilation, but is for execution. It is in the runtime and test classpaths, but not the compile classpath.
Proper utilization of the runtime scope should resolve the circular dependency issue.
Regarding the second issue, you have not supplied enough information to provide a definitive answer. However, you almost certainly want to use a maven plugin in order to leverage maven's information about the dependencies. For example, if you want to produce a single "fat" jar that contains everything, you want to look at maven-shade-plugin. Another option is maven-assembly-plugin, which is extremely flexible and can include all dependencies in the assembly. There are other plugins that excel at handling various other common circumstances. You may want to formulate a separate question if you have problems with how to use a specific plugin.
Here is how I would do it. From C's pom file:
<profile>
<id>compile</id>
<dependencies>
<dependency>
use B here but do not use in the main dependencies section
</dependency>
+ other dependencies
</dependencies>
</build>
</profile>
For example you can compile C module using mvn compile -Pcompile
From B's pom file:
<profile>
<id>run</id>
<dependencies>
<dependency>
use C here but do not use in the main dependencies section
</dependency>
+ other dependencies
</dependencies>
</build>
</profile>
you run B module using mvn yourcommandforrunning -Prun
In this way you can escape the cyclic dependencies issue.

Introducing dependency breaks existing dependency?

I'm working on a project that builds and deploys fine. I'm trying to add some code that uses JWebUnit, and use the following Maven code to bring it in:
<dependency>
<groupId>net.sourceforge.jwebunit</groupId>
<artifactId>jwebunit-htmlunit-plugin</artifactId>
<version>3.2</version>
<scope>test</scope>
</dependency>
Maven seems to resolve this fine and it's bringing everything in (I'm using Intellij, and it now appears under 'Dependencies' in the 'Maven Projects' tab, and also under 'External Libraries' in the Project tab).
However, when I bring this dependency in, the IDE is not able to find it (e.g. if I use import net.sourceforge.jwebunit.junit.WebTester, it can't find it).
But an even bigger issue is it actually breaks some existing code -- I have some JUnit tests that use org.apache.commons.httpclient.HttpClient, and now on Maven's install goal I get a
NoClassDefFoundError - Could not initialize class for that class.
If I remove the JWebUnit dependency, the Maven install goal exits successfully.
I'm used to seeing errors about dependency version convergence when bringing new dependencies, and I feel like chasing this 'no class def found' error could be a red herring, but I'm not sure of the general types of issues in Maven that could be causing it.
EDIT: the dependency code for pulling in HttpClient is:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
jwebunit-htmlunit-plugin includes transitive dependencies which seem like they're conflicting with some of your dependencies (likely because they are different versions).
Maven puts classpath priority on artifacts declared earlier. Try moving jwebunit to the end of your dependencies section, or at least after where you pull in the httpclient classes. Alternatively, you can manually exclude certain transitive dependencies from being pulled in, but this can be tedious.
As for your IDE not allowing imports on the library, remember that you have this declared in the test scope. Production classes cannot see test dependencies.

add external jar to our dependency

There is a jar file lets say "abc.jar" which maven dependency does not exist(ie created a jar by using java command of own classes). I want to add this jar as maven dependency so that at build time it will automatically copy that jar in lib folder as like other maven dependency. how i will do. please help .
Add it as a dependency with a system scope. See the docs here.
However, rather than adding it as a system dependency it might be better to mavenize the jar itself, then you can build and install it into your dependency management system.
Also, see this question: Can I add jars to maven 2 build classpath without installing them?
You can use the systemPath attribute in the dependency tag in the POM file of your project.
In your pom.xml, use the following snippet corresponding to abc.jar:
<dependencies>
<!-- Other dependencies -->
<dependency>
<groupId>abc</groupId>
<artifactId>x</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>{path_to_abc.jar}</systemPath>
</dependency>
</dependencies>
The scope parameter corresponding to this artifact must be set to system, for the artifact to be picked up from the specified systemPath.
Hope this helps!
A normal maven dependency is always resolved by looking into a repository. So you must put your JAR file into a repository.
You could install your JAR into your local repository. Have a look at the install plugin. The install-file goal is your friend.
If other developers also need this JAR (because they are working with the same project), they either need to install it locally too, or - better - you deploy the JAR to a remote repository. Have a look at the deploy plugin. Here the deploy-file goal is your friend. For deploying artifacts, you need a repository manager like Nexus or Artifactory.
However, a dependency could also have the system scope (look at the other answers).

Categories