2

We recently ran into a scenarium that we have two corporate dependencies and each one of them has a specific method with the same name, parameters and class, probably a copy-and-paste. Both dependencies are declared as direct dependency in my actual microservice.

Imagine something like:

-- Microservice
    |-- Corporate dependency A
        |-- com.enterprise.project.UtilityClass
            | public static String someMethod(String someParameter)
    |-- Corporate dependency B
        |-- com.enterprise.project.UtilityClass
            | public static String someMethod(String someParameter)

We noticed the problem because maven reported it in our build when we added the second dependency, we checked and even thought the output is the same, they have slightly different implementations. My question is, how does the JVM decides which one of this methods to use in runtime?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Philippe Gioseffi
  • 1,488
  • 3
  • 24
  • 41

2 Answers2

1

In a "usual" situation, there is a -classpath property that you supply in a startup script of your application for example, and it contains a list of jars that will be "known". Now, if the UtilityClass resides in A.jar and B.jar, the order of appearance of these jars in the classpath will determine which class implementation will load:

Example:

java -classpath A.jar B.jar <whatever>

means that the UtilityClass from A.jar will be loaded, only because it comes first.

Now things become more complicated when you run things through maven, because it manages the -classpath by itself. Since maven 2.0.9 it uses order in pom.xml for classpath (see here for example).

If you have more "advanced" ways of loading the jars (like custom classloaders, then the answer can be different)...

Anyway, probably the best way is to come up with one dependency and exclude the other if its possible.

Mark Bramnik
  • 39,963
  • 4
  • 57
  • 97
  • Since Maven uses the order that the dependencies are declared why does it state a warning such as "unpredictable runtime behaviour" if it is know that the first declared dependency will be used? – Philippe Gioseffi Feb 01 '22 at 00:25
  • I meant if you run things via maven for tests or something, however, after all, maven is just a build tool. In production, you'll have an artifact that enlists both jars in the classpath and doesn't run with maven at all... – Mark Bramnik Feb 01 '22 at 00:29
  • Yes, and that is actually my question, how does the JVM in my production environment decides which method of which dependency to use? Could you edit your answer if you know the JVM behaviour? – Philippe Gioseffi Feb 01 '22 at 00:38
  • I can't - it all depends on what exactly do you run in production and how... If you have a "traditional" artifact - somewhere there must be a script that runs the application, and also sets the "-classpath", right? I don't know who "prepares" this script, so you should check in your application.... Another use case is if you have custom classloaders, like in spring boot. Then I think it will be determined by the order of jars in boot-inf/lib... There are many possible situations. But all-in-all I think you shouldn't "assume" that its ok to run 2 versions of the same class - its is error-prone – Mark Bramnik Feb 01 '22 at 00:59
  • We use spring-boot, so maybe the order in the lib actually does it, I don't think it is the case because of the warning emitted by Maven. I think this is an issue resolved by the JVM itself indeed. We already asked one of the corporate teams to exclude the repeated classes and use the original dependency as its own. – Philippe Gioseffi Feb 01 '22 at 01:03
0

It will depend upon which dependency is first on the classpath.

synergy77
  • 19
  • 6
  • How do you guarantee that it maven itself reports it as a runtime problem scenarium with unpredicted runtime behaviours? – Philippe Gioseffi Feb 01 '22 at 00:20
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 01 '22 at 07:44