Want this course?
Course: JVM Fundamentals for Clojure
Java has had a way to package compiled code and resources and share them around since almost the beginning. It's called the JAR (Java Archive). Combine that with a artifact, versioning, and dependency management system (called Maven), and we have a complete dependency management system.
This lesson looks at the JAR file format, how the JDK looks for dependencies, and the basics of Maven.
So let's talk about dependency management on the JVM. So we talked about how each JVM has it's own class loader, and that class loader has it's own way of figuring out where the class files are. Turns out that there is a standard way, it's not standardized as in a spec, but its the de facto standard, it's the way that everything happens to work, and so lets talk about it. But first we have to define what a Java Archive is.
This is the JAR file, and this is the unit of dependency. It's just a zip file, it's just a file with a bunch of other files inside of it. It contains the class files, all the code you need for running your Java program, or closure program if it's compiled. It's got a manifest, which is just some metadata about that JAR. It could have this is optional, it could have source code, could have documentation, and you'll see different versions of JAR files out there, you know some that have the source code, some that have documentation, and some that are leaner, that just have the class files in it. And it's all whatever you want to put in there.
You can also put resources in there like images, and other data files that you might need. Those can be loaded by the class loader as well. We're gonna go into that more in the anatomy of a JAR lesson, so you'll see all of that in there. But just so you know what it is. This is a Java Archive, it's just a bunch of source code, or the compiled code put together so that you can use it, and just download one thing. Okay so the classpath. This is how JVM's are going to find classes that they can load and use.
The classpath is kinda like this arcane system, it used to actually be broken, and one of the things you had to do was manually make your classpath, so you have to download the jar, put it into the certain place, add it to an environment variable that kind of thing. Now all of that is handled automatically, but the base system is still the same. So its just a list of directories of packages, which is a directory of code. Right a directory of... you know when you compile a Java class, it has a package, and that package has to correspond to the directory.
So you can put those directories in a single directory, and then reference that. You see how it gets very confusing, what needs to go in your classpath. But its just where to find it on your harddrive. Also JAR files. So you can add JAR files, the whole thing totally on... totally zipped up in that JAR file, you just put it in your classpath, the same way you would put a directory. When you write your classpath it's... if you're writing it out as a string, that either goes in the environment variable or on the command line with a -cp, which overrides the environment variable. What you're doing is writing the name of that directory or JAR file, and then putting a semicolon and then another one semicolon, and then another one. So it's just a semicolon separated list of names of directories and JAR files.
Okay so this thing is usually this classpath string, is usually created by your IEEE if you're in Java, so eclipse or intellij manages that itself right. Or if you're using a build system like Maven or Gradle, that will also build it up. Okay. So in just a second we're gonna be talking about Maven, because it is the predominant way of managing dependencies. Okay so we're back, and you see I've put a new set of information up here. So we're talking about Maven. Maven is a big complicated system for managing dependencies, but you kind of have to understand some of it, because a lot of it is really well thought out. So the thing is lining it in boot, both use that core that's really well done, and so it actually works out well for us, because we can borrow that great stuff, and hook into the JVM ecosystem that way.
Alright so let's go over this piece by piece. There are three things in the name of a resource or a JAR, some kind of library that you're gonna consume. There's the group ID which names the company or the individual, the organization, whatever made it, and usually the recommendation is that you're going to use the domain name. You know in that reverse order, that more technical way, so I would have stuff like com dot list cast right, or see org dot closure, or com dot son dot something right. And the idea is there's already a centralized way of talking about the ownership of domains, and it's already a domain, it's like a name of something, might as well just use. So it makes a name space.
Which means that you won't get conflicts in artifact ID's. You've got a domain name, now you can name your artifact whatever you want, there's no conflict. So the artifact is the actual name of the resource, usually it's the same as the name of the library, so if you're gonna be using jodatime, it's jodatime right. So its gonna be org dot jodatime, is the group id, and the artifact id is jodatime. Okay and then there's a version string, because we can't stop writing software, so we have to release new versions, and we want the old version to still exist, so we put a string on there. I don't think that there's any specific format for it, but usually what you see is numbers separated by periods in the semantic versioning system, but I think it could be anything.
Another thing is you can put tags on the ends, so you do two dot three dot four hyphen snapshot. And what that means is you're releasing this code, so it goes into the deployment system, but it could change it's just a snapshot, it's not a real release, and that will be important, we'll talk about that in a minute. Alright so this all names a JAR file, and this information goes into your POM file. A POM file is an xml file that sits along side the JAR, so that if its on a repo you can download just the POM, it's very small and know all the dependencies that that JAR file has, it's name, it's version, that kind of thing.
So all of that is in the POM file, which is another part of the Maven standard. Okay so there's Maven Central, which is a repository of tons and tons of JAR files of resources with their POM files, and it's organized as a search engine. The Maven system is basically just a way to list a giant directory right. So you list the directory, you see all of the different group id's, and then the POM files for all of the resources, so it's just like a http directory structure. And it's very simple, so you can download the POM, see what things depend on each other, get those POM's and build an entire dependency graph, and then download all the resources that you don't have on your system already. One thing that the Maven Central Repo is very good at, is making sure that you don't overwrite a preexisting JAR, so once you do a release of a certain version of your artifact it cannot be overwritten. So you had to bump your version, if you wanna make a new release.
Which is actually very good because the rest of the world is now depending on that software in a certain state, so it keeps all the old versions, it's really fascinating to go on Maven Central and see how deep it goes, how old software is still there ready to be downloaded if you need to rebuild another old system that depends on it. I mentioned that it's searchable which is really nice, but it's also organized so that you can see well you're using this artifact id, here are all the old versions and this is the most recent version. Okay now Maven Central is where most of the software in the Java World is published, including closure and associated libraries and stuff, you know core acing, closure script compiler, those kinds of things. But there's also a system that is just for closure code. I mean you can put anything you want on there, but it was made for closure. It's called clojars, clojars, and it has the same idea that you're just pushing JAR's up to it, and it maintains that same discipline that you never delete an old JAR.
Okay and this is a free service, obviously it cost money to host all that stuff, they accept donations, they also accept sponsorships, so you should consider donating or sponsoring them to do development or just for their bandwidth. Is Maven compatible its pend only, you'll find that a lot of the closure libraries that you use are hosted there. So that's where lining it and boot will check, they're standard Maven repositories, and those are in Maven, I'm sorry in lining and in boot by default. So this is Maven Central.
This is the search engine for the Central Repository for Maven. So I'm gonna do some, I'm gonna search for closure. And we see that it comes up as the number one artifact id closure, group id org dot closure, tells me the latest version, I can see all the different versions, I can even download the latest version in different varieties. So I can get the JAR, I can also get the sources only, I can get the Java Doc, all that's really useful. Let me click on the org dot closure group id, and I can see all of the artifacts that org dot closure has released to Maven Central. Now if I click on closure and go to all, I can see all of the releases of closure. There's a lot more here this is paged there's actually 103. And we can see all the alphas that are going on right now.
Last one released October 28th oh that's really cool, I can get the POM this is an xml file, and it just describes all of the metadata for this thing, all of the dependencies, see here's the dependencies. And this is usually built by your build tool. Like lining-in can build this, boot can build this, you don't need to worry about this too much, but just know that it's all there and it's all downloadable separately from the JAR file. Cause the JAR file is it's own standard, and they can get kinda big of course, cause they've got huge libraries in them sometimes. So you just wanna download a little bitty thing to know all this dependencies.
The JAR file is there too, see I can download that separately, and this is just a standard way of organizing them so that you can use them from your build tools or from your development tools and they're always there downloadable.