26

My project consists of some dependencies which are pulling the same common dependency.

The common dependency storm-kafka has a new version 1.0.2 and an old version 0.10.0

On building a shaded jar, I see classes from both the versions in my fat jar and somehow during execution, the older one is getting picked up which gives a ClassNotFoundError because other dependencies related to the older version are not there.

jar -xvf my_shaded_fat_jar.jar
find . -name KeyValueSchemeAsMultiScheme.class
./org/apache/storm/kafka/KeyValueSchemeAsMultiScheme.class
./storm/kafka/KeyValueSchemeAsMultiScheme.class

storm/kafka is older one and org/apache/storm/kafka is the new one I want.

Surprising part is that I do not see 0.10.0 in my ~/.m2 repo:

ls ~/.m2/repository/org/apache/storm/storm-kafka/
1.0.2
# no 0.10.0 here !

How do I debug maven to find out from where the older dependency is creeping into?

EDIT:

On running mvn dependency:tree -Dverbose -Dincludes=storm.kafka, I get:

[WARNING] The POM for org.apache.storm:flux-core:jar:1.0.2 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[WARNING] The POM for org.apache.storm:storm-kafka:jar:1.0.2 is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
[INFO] 
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli)  ---
[WARNING] Failed to build parent project for org.apache.storm:flux-core:jar:1.0.2
[WARNING] Invalid POM for org.apache.storm:flux-core:jar:1.0.2, transitive dependencies (if any) will not be available, enable debug logging for more details
[WARNING] Invalid POM for org.apache.storm:storm-kafka:jar:1.0.2, transitive dependencies (if any) will not be available, enable debug logging for more details
[WARNING] Failed to build parent project for org.apache.storm:flux-core:jar:1.0.2
[WARNING] Invalid POM for org.apache.storm:flux-core:jar:1.0.2, transitive dependencies (if any) will not be available, enable debug logging for more details

Why the poms are invalid? I just cleaned my .m2 repo by removing everything in ~/.m2/repository/org/apache/storm

1
  • 2
    Finding a certain dependency by a class name would be very usefull in some cases. After I did some research it looks like that this is not easily possible. Did you find a solution?
    – eztam
    Commented Oct 23, 2017 at 14:05

4 Answers 4

13
mvn dependency:build-classpath -Dmdep.outputFile=f

gives a list of all dependend jars.

now iterate of them and add their content into a file:

for f in `cat f | tr ';:' '  '`
do
    echo $f >> out
    unzip -v $f >> out
done
3
  • easily scriptable
    – weberjn
    Commented Sep 7, 2019 at 7:37
  • 2
    In my system, the tr command needs a colon instead of a semicolon as the output of mvn dependency:build-classpath is separated by :. Otherwise, great way to obtain files inside dependencies.
    – Nirro
    Commented Dec 5, 2019 at 12:01
  • Thanks! Since I am in a "DOS-Prompt" and the outputFile-Option does not work, I added a modification as a new answer...
    – el_schalo
    Commented Jan 24 at 12:13
5

You can use the Maven tree goal to show all dependencies that are used. This prints out the full dep tree by default but you can also get it to find a particular dependency you're interested in - for example try:

mvn dependency:tree -Dverbose -Dincludes=storm.kafka

to see what's pulling in Kafka. More info can be found here:

http://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html

6
  • 3
    Hi @adamskoye, I updated my question with more details from your command. I think the problem I want to solve is the exact dependency which pulls in a given class and not a given dependency itself because at this point I do not know which dependency is bringing in wrong class files. Commented Sep 13, 2016 at 1:24
  • Well, the debugging flag is -X so if you could try mvn -X dependency:tree -Dverbose -Dincludes=storm.kafka it might give more info?
    – adamskoye
    Commented Sep 13, 2016 at 1:27
  • I did try -X but it did not provide any clue. All through the logs, there was no mention of storm/kafka or storm.kafka or 0.10.0 Commented Sep 13, 2016 at 1:28
  • I got a comment in my log that -Dverbose uses the Maven2 algorithm. That might explain the invalid POMs. Please try again without -Dverbose
    – adamskoye
    Commented Sep 13, 2016 at 1:35
  • tried this and got: [INFO] Verbose not supported since maven-dependency-plugin 3.0
    – z atef
    Commented Sep 5, 2023 at 0:37
0

This seems to work if you're into ammonite:

#!/usr/bin/env amm

import $ivy.`com.lihaoyi::os-lib:0.7.0`

// Run in the root of a maven project to find which jars contain the class
// Example: all_classes.sc org.redangus.core.func.Ex
// amm, mvn and jar must be in PATH

@main
def main(fullClassName: String): Unit = {
  val clazz = fullClassName.replace('.', '/') + ".class"
  println("Searching for file " + clazz)
  val file = os.root / "tmp" / s"all_classes_${System.getProperty("user.name")}"
  if (os.exists(file)) os.remove(file)
  if (os.proc("mvn", "dependency:build-classpath",
    s"-Dmdep.outputFile=$file").call().exitCode != 0) {
    println("Something is amiss")
    sys.exit(1)
  }
  var found = false
  os.read(file).split(":").foreach(f => {
    os.proc("jar", "-tf", f).call().toString().split("\n").foreach(l => {
      if (l == clazz) {
        println(s"$f")
        found = true
      }
    })
  })
  os.remove(file)
  if (! found) println("No matches found.")
}
0

Here a way to find the JAR (and thereby the Maven dependency), where a specific class files comes from for Windows10/11 "DOS" command prompt:

  1. dependency:build-classpath > cp.txt (in case -Dmdep.outputFile=cp.txt does not work, like for me)
  2. modify cp.txt to cp_sorted.txt (e.g. by using Notepad++):
    1. removing all non-classpath-lines (esp. those lines starting with [INFO])
    2. substituting all Classpath-Separators (;) with newlines
    3. order the one-jar-per-line-list
    4. de-duplicate the one-jar-per-line-list
  3. @FOR /F %f IN (cp_sorted_test.txt) DO 7z.exe e -y -o"CLASSPATH_FULL_EXPANDED_TEST_FINAL\%~nf" "%f"
  4. make a DIR /B /S for the desired class, e.g. DIR /B /S HttpServlet.class

Not the answer you're looking for? Browse other questions tagged or ask your own question.