Week 126 — How are JAR files structured?

Question of the Week #126
How are JAR files structured?
5 Replies
daysling
daysling7d ago
basic JAR structure JAR files, which are typically used for Java applications and libraries, are essentially zip files containing compiled classes, resources (other files necessary for the application/library) and additional metadata. To extract a JAR file named somejar.jar, one can run the jar xf somejar.jar and the contents will be exported in the current directory. The code is available in bytecode via .class files following the package structure. If a type SomeType is located in the package com.example.somepackage, it must be located in /com/example/somepackage/SomeType.class (starting with the JAR file root). A module descriptor would be located in a module-info.class file entry in the JAR file root. Resources can use the same directory structure. For example, if a resource is loaded with SomeType.class.getResource("someResource.txt"), it is loaded from /com/example/somepackage/someResource.txt (starting from the JAR file root again). On the other hand, if the resource is loaded with SomeType.class.getResource("/someResource.txt") (note the leading / in the String) or SomeType.class.getClassLoader().getResource("someResource.txt"), it is loaded from /someResource.txt directly in the JAR file root. In addition to combiled bytecode and resources, JAR files typically contain metadata in a META-INF directory entry. For instance, JAR files contain a MANIFEST.MF entry containing the main class which is run when the class is executed via java -jar. This file can also contain other information about how the JAR file was built and additional classpath entries that are loaded when the JAR is run with java -jar.
daysling
daysling7d ago
additional contents in META-INF Apart from the META-INF/MANIFEST.MF file, the META-INF directory can contain be used for multi-release JARs. If a META-INF/versions/<number> (with number being replaced with a JDK major version like 21), these classes are available (and replace the "normal" classes at corresponding locations) when running with that JDK version or a later JDK. This feature is often used to include a module descriptor in META-INF/versions/9/module-info.class without impacting how the application runs on JDK 8 or earlier. This type of metadata is also used for service registration with the ServiceLoader mechanism (https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/ServiceLoader.html). While this information can be provided in the module descriptor, services can also be registered in a META-INF/services directory in the JAR. This directory would then contain one file per service and that file then contains one line per service provider. These service providers can then be loaded by the service without the service depending on the service provider. This mechanism is used for mechanisms like JDBC or annotation processors. Another use of the META-INF directory is digital signatures. The contents of JAR files can be signed cryptographically to ensure the JAR has not been modified. While this directory is used by some mechanisms within the JDK, build tools and libraries/frameworks may add or use other things in that directory. For instance, third-party licenses are sometimes included in that directory, Maven can add the content of the pom.xml (or specifically the consumer pom) to the META-INF directory and tools like OSGi are using the META-INF/MANIFEST.MF file for additional metadata about the artifact (in this case OSGi bundle information with required dependencies, exported packages, etc).
📖 Sample answer from dan1st
daysling
daysling7d ago
The structure of the jar needs to be META-INF/MANIFEST.MF mypackage/MyMainFile.class where MyMainFile has to be in the proper package.
daysling
daysling7d ago
idk im a software engineer
Submission from therealar1s
daysling
daysling7d ago
JAR file is a packaged file format similar to a zip or a war file. It's mainly used to collect .class files, and other resources (configuration ymls, images, static contents, etc..) that an application might need during runtime. JAR files contains the java bytecode required to run any application, however, java runtime isn't able to identify the main class it's supposed to run without either expliciting loading the JAR file as a classpath and then specificing the main class to run. Or using a MANIFEST.MF located at META-INF/MANIFEST.MF, which looks something like this:
Manifest-Version: 1.0
Main-Class: com.example.App
Manifest-Version: 1.0
Main-Class: com.example.App
⭐ Submission from daysling

Did you find this page helpful?