You learn by comparing to what you already know. I was recently bitten by assuming Rust worked as Java regarding transitive dependency version resolution. In this post, I want to compare the two.You learn by comparing to what you already know. I was recently bitten by assuming Rust worked as Java regarding transitive dependency version resolution. In this post, I want to compare the two.

Transitive Dependency Version Resolution in Rust and Java: Comparing the Two

2025/09/21 23:00

You learn by comparing to what you already know. I was recently bitten by assuming Rust worked as Java regarding transitive dependency version resolution. In this post, I want to compare the two.

Dependencies, Transitivity, and Version Resolution

Before diving into the specifics of each stack, let's describe the domain and the problems that come with it.

\ When developing any project above Hello World level, chances are you'll face problems that others have faced before. If the problem is widespread, the probability is high that somebody was kind and civic-minded enough to have packaged the code that solves it, for others to re-use. Now, you can use the package and focus on solving your core problem. It's how industry builds most projects today, even if it brings other problems: you sit on the shoulders of giants.

\ Languages come with build tools that can add such packages to your project. Most of them refer to packages you add to your project as dependencies. In turn, projects' dependencies can have their own dependencies: the latter are called transitive dependencies.

Transitive dependencies

In the above diagram, C and D are transitive dependencies.

\ Transitive dependencies have issues on their own. The biggest one is when a transitive dependency is required from different paths, but in different versions. In the diagram below, A and B both depend on C, but on different versions of it.

Which version of C should the build tool include in your project? Java and Rust have different answers. Let's describe them in turn.

Java Transitive Dependency Version Resolution

Reminder: Java code compiles to bytecode, which is then interpreted at runtime (and sometimes compiled to native code, but this is outside of our current problem space). I'll first describe runtime dependency resolution and build-time dependency resolution.

\ At runtime, the Java Virtual Machine offers the concept of a classpath. When having to load a class, the runtime searches through the configured classpath in order. Imagine the following class:

public static Main {     public static void main(String[] args) {         Class.forName("ch.frankel.Dep");     } } 

\ Let's compile it and execute it:

java -cp ./foo.jar:./bar.jar Main 

\ The above will first look in the foo.jar for the ch.frankel.Dep class. If found, it stops there and loads the class, regardless of whether it might also be present in the bar.jar; if not, it looks further in the bar.jar class. If still not found, it fails with a ClassNotFoundException.

\ Java's runtime dependency resolution mechanism is ordered and has a per-class granularity. It applies whether you run a Java class and define the classpath on the command line as above, or whether you run a JAR that defines the classpath in its manifest.

\ Let's change the above code to the following:

public static Main {     public static void main(String[] args) {         var dep = new ch.frankel.Dep();     } } 

\ Because the new code references Dep directly, new code requires class resolution at compile-time. Classpath resolution works in the same way:

javac -cp ./foo.jar:./bar.jar Main 

\ The compiler looks for Dep in foo.jar, then in bar.jar if not found. The above is what you learn at the beginning of your Java learning journey.

\ Afterwards, your unit of work is the Java Archive, known as the JAR, instead of the class. A JAR is a glorified ZIP archive, with an internal manifest that specifies its version.

\ Now, imagine that you're a user of foo.jar. Developers of foo.jar set a specific classpath when compiling, possibly including other JARs. You'll need this information to run your own command. How does a library developer pass this knowledge to downstream users?

\ The community came up with a few ideas to answer this question: The first response that stuck was Maven. Maven has the concept of Project Object Model, where you set your project's metadata, as well as dependencies. Maven can easily resolve transitive dependencies because they also publish their POM, with their own dependencies. Hence, Maven can trace each dependency's dependencies down to the leaf dependencies.

\ Now, back to the problem statement: how does Maven resolve version conflicts? Which dependency version will Maven resolve for C, 1.0 or 2.0?

\ The documentation is clear: the nearest.

Dependency resolution with the same dependency in different versions

In the above diagram, the path to v1 has a distance of two, one to B, then one to C; meanwhile, the path to v2 has a distance of three, one to A, then one to D, then finally one to C. Thus, the shortest path points to v1.

\ However, in the initial diagram, both C versions are at the same distance from the root artifact. The documentation provides no answer. If you're interested in it, it depends on the order of declaration of A and B in the POM! In summary, Maven returns a single version of a duplicated dependency to include it on the compile classpath.

\ If A can work with C v2.0 or B with C 1.0, great! If not, you'll probably need to upgrade your version of A or downgrade your version of B, so that the resolved C version works with both. It's a manual process that is painful–ask me how I know. Worse, you might find out there's no C version that works with both A and B. Time to replace A or B.

Rust Transitive Dependency Version Resolution

Rust differs from Java in several aspects, but I think the following are the most relevant for the sake of our discussion:

  • Rust has the same dependency tree at compile-time and at runtime
  • It provides a build tool out of the box, Cargo
  • Dependencies are resolved from source

\ Let's examine them one by one.

\ Java compiles to bytecode, then you run the latter. You need to set the classpath both at compilation time and at runtime. Compiling with a specific classpath and running with a different one can lead to errors. For example, imagine you compile with a class you depend on, but the class is absent at runtime. Or alternatively, it's present, but in an incompatible version.

\ Contrary to this modular approach, Rust compiles to a unique native package the crate's code and every dependency. Moreover, Rust provides its own build too, thus avoiding having to remember the quirks of different tools. I mentioned Maven, but other build tools likely have different rules to resolve the version in the use case above.

\ Finally, Java resolves dependencies from binaries: JARs. On the contrary, Rust resolves dependencies from sources. At build time, Cargo resolves the entire dependency tree, downloads all required sources, and compiles them in the correct order.

\ With this in mind, how does Rust resolve the version of the C dependency in the initial problem? The answer may seem strange if you come from a Java background, but Rust includes both. Indeed, in the above diagram, Rust will compile A with C v1.0 and compile B with C v2.0. Problem solved.

Conclusion

JVM languages, and Java in particular, offer both a compile-time classpath and a runtime classpath. It allows modularity and reusability, but opens the door to issues regarding classpath resolution. On the other hand, Rust builds your crate into a single self-contained binary, whether a library or an executable.

\ To go further:

  • Maven - Introduction to the Dependency Mechanism
  • Effective Rust - Item 25: Manage your dependency graph

Originally published at A Java Geek on September 14th, 2025

Disclaimer: The articles reposted on this site are sourced from public platforms and are provided for informational purposes only. They do not necessarily reflect the views of MEXC. All rights remain with the original authors. If you believe any content infringes on third-party rights, please contact [email protected] for removal. MEXC makes no guarantees regarding the accuracy, completeness, or timeliness of the content and is not responsible for any actions taken based on the information provided. The content does not constitute financial, legal, or other professional advice, nor should it be considered a recommendation or endorsement by MEXC.

You May Also Like

Soluna Holdings Announces $32 Million Equity Offering

Soluna Holdings Announces $32 Million Equity Offering

The post Soluna Holdings Announces $32 Million Equity Offering appeared on BitcoinEthereumNews.com. Key Points: Soluna Holdings initiates $32 million offering for Bitcoin and AI projects. Funds targeted at expanding Bitcoin mining infrastructure. Soluna positions itself at the intersection of renewable energy and computing power. Soluna Holdings announced a $32 million registered direct offering, involving the issuance of 18,079,144 shares and Series C warrants at $1.77 each, as per Nasdaq regulations. This funding supports Bitcoin mining and AI infrastructure, potentially impacting related markets by expanding Soluna’s renewable energy-driven computing capacity. Equity Offering Fuels Bitcoin and AI Growth Soluna Holdings has entered into definitive agreements to issue 18,079,144 shares and Series C warrants at $1.77 per share. The $32 million raised will be directed at enhancing Bitcoin mining capabilities and advancing artificial intelligence initiatives, emphasizing Soluna’s strategic positioning in green energy sectors. “We strategically co-locate our data centers with renewable power sources to support Bitcoin mining, generative AI, and other compute-intensive applications.” – Soluna Press Release Bitcoin Market Faces Volatility Amid Funding News Did you know? Soluna’s funding strategy mirrors trends seen in other data-center companies supporting cryptos and AI, highlighting a shift towards sustainable tech infrastructure. Bitcoin (BTC) currently trades at $89,257.47 with a market cap of approximately $1.78 trillion. Recent declines include a -2.79% drop over the past 24 hours, according to CoinMarketCap. Bitcoin(BTC), daily chart, screenshot on CoinMarketCap at 00:01 UTC on December 7, 2025. Source: CoinMarketCap Insights from the Coincu research team suggest that Soluna’s strategy may catalyze further investments in technology that thrives on renewable energy, reinforcing its practical application in cryptocurrency and AI sectors. DISCLAIMER: The information on this website is provided as general market commentary and does not constitute investment advice. We encourage you to do your own research before investing. Source: https://coincu.com/bitcoin/soluna-holdings-raises-32-million/
Share
BitcoinEthereumNews2025/12/07 08:08
The Psychology Behind Why People Stay, Leave, Or Tune Out At Work

The Psychology Behind Why People Stay, Leave, Or Tune Out At Work

The post The Psychology Behind Why People Stay, Leave, Or Tune Out At Work appeared on BitcoinEthereumNews.com. The Psychology Behind Why People Stay, Leave, Or Tune Out At Work getty Leaders spend a lot of time wondering why some employees stay loyal, why others leave quickly, and why so many slip into disengagement long before they walk out the door. People often assume the main reason employees leave is pay or promotion. Those things matter, but they only scratch the surface. The bigger explanation is based in psychology. Employees make decisions based on how they feel, what they fear, what they assume, and whether their daily experiences reinforce a sense of meaning and connection. That is the part leaders overlook. The clues are always there, but they are often hidden in everyday interactions that seem small and routine. What Does The Psychology Of Daily Work Reveal About Why People Stay? getty What Does The Psychology Of Daily Work Reveal About Why People Stay? People stay in workplaces where they feel understood. Any organization can offer flexibility or better benefits, but those are not what keep people committed long term. Employees stay when they believe their voice matters, when support feels steady instead of controlling, and when their manager shows genuine interest in how they experience the workday. Microsoft’s Satya Nadella has talked about this often. He highlights how people perform at a higher level when leaders approach conversations with a learning mindset instead of an answer mindset. That shift changes the tone of the relationship. When employees sense curiosity from leaders, it lowers defensiveness, builds trust, and strengthens commitment. Curiosity also signals interest, and interest signals value. When people feel valued, they stay. When they do not, they begin to explore other options. This is why the tone of daily interactions matters so much. A single moment where someone feels dismissed can outweigh months of positive intentions.…
Share
BitcoinEthereumNews2025/12/07 07:45