Java Tutorial
- Java - Home
- Java - Overview
- Java - History
- Java - Features
- Java vs C++
- Java Virtual Machine (JVM)
- Java - JDK vs JRE vs JVM
- Java - Hello World Program
- Java - Environment Setup
- Java - Basic Syntax
- Java - Variable Types
- Java - Data Types
- Java - Type Casting
- Java - Unicode System
- Java - Basic Operators
- Java - Comments
Java Control Statements
- Java - Loop Control
- Java - Decision Making
- Java - If-else
- Java - Switch
- Java - For Loops
- Java - For-Each Loops
- Java - While Loops
- Java - do-while Loops
- Java - Break
- Java - Continue
Object Oriented Programming
- Java - OOPs Concepts
- Java - Object & Classes
- Java - Class Attributes
- Java - Class Methods
- Java - Methods
- Java - Variables Scope
- Java - Constructors
- Java - Access Modifiers
- Java - Inheritance
- Java - Aggregation
- Java - Polymorphism
- Java - Overriding
- Java - Method Overloading
- Java - Dynamic Binding
- Java - Static Binding
- Java - Instance Initializer Block
- Java - Abstraction
- Java - Encapsulation
- Java - Interfaces
- Java - Packages
- Java - Inner Classes
- Java - Static Class
- Java - Anonymous Class
- Java - Singleton Class
- Java - Wrapper Classes
- Java - Enums
- Java - Enum Constructor
- Java - Enum Strings
Java Built-in Classes
Java File Handling
- Java - Files
- Java - Create a File
- Java - Write to File
- Java - Read Files
- Java - Delete Files
- Java - Directories
- Java - I/O Streams
Java Error & Exceptions
- Java - Exceptions
- Java - try-catch Block
- Java - try-with-resources
- Java - Multi-catch Block
- Java - Nested try Block
- Java - Finally Block
- Java - throw Exception
- Java - Exception Propagation
- Java - Built-in Exceptions
- Java - Custom Exception
Java Multithreading
- Java - Multithreading
- Java - Thread Life Cycle
- Java - Creating a Thread
- Java - Starting a Thread
- Java - Joining Threads
- Java - Naming Thread
- Java - Thread Scheduler
- Java - Thread Pools
- Java - Main Thread
- Java - Thread Priority
- Java - Daemon Threads
- Java - Thread Group
- Java - Shutdown Hook
Java Synchronization
- Java - Synchronization
- Java - Block Synchronization
- Java - Static Synchronization
- Java - Inter-thread Communication
- Java - Thread Deadlock
- Java - Interrupting a Thread
- Java - Thread Control
- Java - Reentrant Monitor
Java Networking
- Java - Networking
- Java - Socket Programming
- Java - URL Processing
- Java - URL Class
- Java - URLConnection Class
- Java - HttpURLConnection Class
- Java - Socket Class
- Java - Generics
Java Collections
Java Interfaces
- Java - List Interface
- Java - Queue Interface
- Java - Map Interface
- Java - SortedMap Interface
- Java - Set Interface
- Java - SortedSet Interface
Java Data Structures
Java Collections Algorithms
Advanced Java
- Java - Command-Line Arguments
- Java - Lambda Expressions
- Java - Sending Email
- Java - Applet Basics
- Java - Javadoc Comments
- Java - Autoboxing and Unboxing
- Java - File Mismatch Method
- Java - REPL (JShell)
- Java - Multi-Release Jar Files
- Java - Private Interface Methods
- Java - Inner Class Diamond Operator
- Java - Multiresolution Image API
- Java - Collection Factory Methods
- Java - Module System
- Java - Nashorn JavaScript
- Java - Optional Class
- Java - Method References
- Java - Functional Interfaces
- Java - Default Methods
- Java - Base64 Encode Decode
- Java - Switch Expressions
- Java - Teeing Collectors
- Java - Microbenchmark
- Java - Text Blocks
- Java - Dynamic CDS archive
- Java - Z Garbage Collector (ZGC)
- Java - Null Pointer Exception
- Java - Packaging Tools
- Java - Sealed Classes
- Java - Record Classes
- Java - Hidden Classes
- Java - Pattern Matching
- Java - Compact Number Formatting
- Java - Garbage Collection
- Java - JIT Compiler
Java Miscellaneous
- Java - Recursion
- Java - Regular Expressions
- Java - Serialization
- Java - Strings
- Java - Process API Improvements
- Java - Stream API Improvements
- Java - Enhanced @Deprecated Annotation
- Java - CompletableFuture API Improvements
- Java - Streams
- Java - Datetime Api
- Java 8 - New Features
- Java 9 - New Features
- Java 10 - New Features
- Java 11 - New Features
- Java 12 - New Features
- Java 13 - New Features
- Java 14 - New Features
- Java 15 - New Features
- Java 16 - New Features
Java APIs & Frameworks
Java Class References
- Java - Scanner Class
- Java - Arrays Class
- Java - Strings
- Java - Date & Time
- Java - ArrayList
- Java - Vector Class
- Java - Stack Class
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - The IdentityHashMap Class
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet Class
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection Interface
- Java - Array Methods
Java Useful Resources
Java - Multi-Release Jar Files
Multi-release JAR feature was introduced in Java 9. It allows to use of multiple versions of a class pertaining to multiple versions of Java. For example, many third-party libraries or frameworks use Java. As Java as a language is continuously evolving and with every major release, many new features are getting added to the language. As third-party libraries/frameworks have to rewrite their code base in order to accommodate new features, teams are highly reluctant to use the new features. It acts as a hindrance to them to move to the new versions of Java.
In order to counter this problem of maintenance of multiple source codes of the same file or platform-specific version of a file, the Multirelease JAR feature was introduced. Consider the following example:
A typical jar file has all the classes at the root level.
jar root - Calculator.class - Util.class - Math.class - Service.class
If we've Java 9 feature specific Util class then that jar cannot be used in JRE 8 or lower.
In multi-release Jar, the format has been enhanced to have different versions of Java classes or resources that can be maintained and used as per the platform. In JAR, a file MANIFEST.MF file has an entry Multi-Release: true in its main section. META-INF directory also contains a versions subdirectory whose subdirectories (starting with 9 for Java 9 ) store version-specific classes and resource files.
Using MANIFEST.MF, we can specific Java 9 or higher version-specific classes in separate locations as shown below:
Java Multi-Release Jar Files Directory Structure
jar root - Calculator.class - Util.class - Math.class - Service.class META-INF - versions - 9 - Util.class - Math.class - 10 - Util.class - Math.class
Now if JRE is not support Multi-release jar, then it will choose the root level classes to load and execute otherwise, version specific classes will be loaded. For example, if above jar is used in Java 8, then root level Util.class will be used. If same jar is executed by Java 9, then java 9 version specific class will be picked and so on. This way, third party libraries/frameworks can support new features without changing their source codes which was written targeting the lower versions.
Creating and Using Multi-Release Jar Files in Java
In this example, we'll be creating and using a multi-release jar to have two versions of Tester.java file, one for jdk 7 and one for jdk 9 and run it on different jdk versions.
The following are the steps for creating and using multi-release jar files in Java -
Step 1: Create Java 7 Specific Java Class
Let's create a Java class that may have Java 7 specific code and features which is not available prior to Java 9. In this example, we're simply printing a message just to showcase the usage of this feature.
Create a folder c:/test/java7/com/tutorialspoint. Create Tester.java with following content −
Tester.java
This is a simple code where we're printing a Java 7 specific message when program is executed.
package com.tutorialspoint; public class Tester { public static void main(String[] args) { System.out.println("Inside java 7"); } }
Step 2: Create Java 9 Specific Java Class
Let's create a Java class that may have code specific to Java 9 enhancements and features which is not available prior to Java 9. In this example, we're simply printing a message just to showcase the usage of this feature.
Create a folder c:/test/java9/com/tutorialspoint. Create Tester.java with following content −
Tester.java
This is also similar code as above where we're printing a Java 9 specific message when program is executed.
package com.tutorialspoint; public class Tester { public static void main(String[] args) { System.out.println("Inside java 9"); } }
In order to use multi-release jar feature, we must ensure that signature of both class should be same. Public interface like method signatures should be same in both the classes.
Step 3: Compile with Target Versions
C:\test > javac --release 9 java9/com/tutorialspoint/Tester.java C:\JAVA > javac --release 7 java7/com/tutorialspoint/Tester.java
Step 4: Create a Multi-Release JAR
C:\JAVA > jar -c -f test.jar -C java7 . --release 9 -C java9. Warning: entry META-INF/versions/9/com/tutorialspoint/Tester.java, multiple resources with same name
Step 5: Run the JAR with JDK 7
C:\JAVA > java -cp test.jar com.tutorialspoint.Tester Inside Java 7
Step 6: Run the JAR JDK 9
C:\JAVA > java -cp test.jar com.tutorialspoint.Tester Inside Java 9
Conclusion
We can see, that with multi-release Jar feature, we can create multiple version of a class without having backwards compatibility issues. We've showcased that same command can be used to execute a class. Based on the JRE version listed in META-INF file, the corresponding class is picked. In case of lower JRE version which is not supporting Multi-Release jar, the root level classes are picked instead of version specific classes. And lastly, the signature of public methods of the versioned classes should be same so this functionality can work perfectly.