ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JDK, JRI, JVM, and Classloader
    StaticPL/JAVA 2019. 8. 23. 06:32

    1. Overview

    The Java Development Kit (JDK) is a software development environment used for developing Java applications and applets. It includes the Java Runtime Environment (JRE), an interpreter/loader (Java), a compiler (javac), an archiver (jar), a documentation generator (Javadoc) and other tools needed in Java development.

    2. Java Development Kit (JDK)

    It is a kit that provides the environment to develop and execute(run) the Java program. It includes two things:

    • Development Tools
      • To provide an environment to develop java programs
    • JRE
      • To execute a java program

    3. Java Runtime Environment (JRE)

    The Java Runtime Environment provides the minimum requirements for executing a Java application; it consists of the Java Virtual Machine (JVM), core classes, and supporting files. It is an installation package that provides an environment to only run(not develop) the java program(or application) onto your machine. JRE is only used by them who only want to run the Java Programs i.e. end-users of your system.

    3.1 Components

    • Deployment technologies, including deployment, Java Web Start and Java Plug-in.
    • User interface toolkits, including Abstract Window Toolkit (AWT), Swing, Java 2D, Accessibility, Image I/O, Print Service, Sound, drag, and drop (DnD) and input methods.
    • Integration libraries, including Interface Definition Language (IDL), Java Database Connectivity (JDBC), Java Naming and Directory Interface (JNDI), Remote Method Invocation (RMI), Remote Method Invocation Over Internet Inter-Orb Protocol (RMI-IIOP) and scripting.
    • Other base libraries, including international support, input/output (I/O), extension mechanism, Beans, Java Management Extensions (JMX), Java Native Interface (JNI), Math, Networking, Override Mechanism, Security, Serialization and Java for XML Processing (XML JAXP).
    • Lang and util base libraries, including lang and util, management, versioning, zip, instrument, reflection, Collections, Concurrency Utilities, Java Archive (JAR), Logging, Preferences API, Ref Objects and Regular Expressions.
    • Java Virtual Machine (JVM), including Java HotSpot Client and Server Virtual Machines.

    4. How JRE works

    4.1 Compile Time

    To understand how the JRE works let us consider a Java source file saved as Example.java. The file is compiled into a set of Byte Code that is stored in a “.class” file. Here it will be “Example.class“.

    4.2 Runtime

    4.2.1 ClassLoader

    The ClassLoader loads all necessary classes needed for the execution of a program. It provides security by separating the namespaces of the local file system from that imported through the network. These files are loaded either from a hard disk, a network or from other sources.

    4.2.2 Byte Code Verifier

    The JVM puts the code through the Byte Code Verifier that checks the format and checks for an illegal code. Illegal code, for example, is code that violates access rights on objects or violates the implementation of pointers.

    4.2.3 Intrepreter

    At runtime the Byte Code is loaded, checked and run by the interpreter. The interpreter has the following two functions:

    • Execute the Byte Code
    • Make appropriate calls to the underlying hardware

    4.3 Interactions between JDK and JRE

    5. ClassLoader

    Classloaders are responsible for loading Java classes into memory during runtime dynamically to the JVM(Java Virtual Machine). They are part of the JRE(Java Runtime Environment). So JVM doesn't need to know about the underlying files or file systems in order to run Java programs thanks to classloaders. But they aren't loading all of the classes into memory at once. Let's figure out what built-in classloaders and custom classloaders.

    5.1 Types of Built-in Classloaders

    public void printClassLoaders() throws ClassNotFoundException {
     
        System.out.println("Classloader of this class:"
            + PrintClassLoader.class.getClassLoader());
     
        System.out.println("Classloader of Logging:"
            + Logging.class.getClassLoader());
     
        System.out.println("Classloader of ArrayList:"
            + ArrayList.class.getClassLoader());
    }
    Class loader of this class:sun.misc.Launcher$AppClassLoader@18b4aac2
    Class loader of Logging:sun.misc.Launcher$ExtClassLoader@3caeaf62
    Class loader of ArrayList:null
    • Application Classloader or System ClassLoader

    It loads the classes where the example method is contained which is in the classpath. It's a child of Extensions classloader and It can be set using -classpath or cp command-line option.

    • Extension Classloader

    It loads the classes which are an extension of the standard core Java classes where are usually located at $JAVA_HOME/jre/lib/ext.

    • Bootstrap Classloader

    This is written in native code, not Java as part of the core JVM. So it can't be instantiated in Java code. It's usually located at $JAVA_HOME/jre/lib. And different platforms might have different implementations of this particular class loader.

    It's mainly responsible for loading JDK internal classes, typically rt.jar and other core libraries located in $JAVA_HOME/jre/lib directory. Additionally, This primordial class loader serves as a parent of all the other class loader instances.

     

    5.2 Built-in ClassLoader

    • Delegation Model

    When the JVM requests a class, the class loader tries to locate the class and load the class definition into the runtime. java.lang.ClassLoader.loadClass() method is responsible for loading the class definition into runtime using fully qualified name. If the class isn't already loaded, it delegates the request to the parent class loader. This process happens recursively. Eventually, if the parent class loader doesn't find the class, then the child class will call java.net.URLClassLoader.findClass() to look for classes in the file system itself. if the last-child class can't load the class either, it throws java.lang.NoClassDefFoundError or java.lang.ClassNotFoundException as below. classloaders in a JVM follow a hierarchical model such that every class loader has a single parent with the exception of the bootstrap class loader.

    java.lang.ClassNotFoundException: com.baeldung.classloader.SampleClassLoader    
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)    
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)    
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)    
        at java.lang.Class.forName0(Native Method)    
        at java.lang.Class.forName(Class.java:348)

     

    • Unique Classes

    It ensures unique classes as delegating upward. If only parent class loader can't find the class, then-current instance attempt to do so itself. So there's no concern which class is chosen for the same class name.

     

    • Visibility Constraint

    Children class loaders are visible to classes loaded by its parent class loaders but not vice-versa. 

    • Cannot unload classes

     

    5.3 Custom ClassLoader

    If we need to load classes out of the local or a network, need to make use of custom class loaders. 

    public class CustomClassLoader extends ClassLoader {
     
        @Override
        public Class findClass(String name) throws ClassNotFoundException {
            byte[] b = loadClassFromFile(name);
            return defineClass(name, b, 0, b.length);
        }
     
        private byte[] loadClassFromFile(String fileName)  {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(
                    fileName.replace('.', File.separatorChar) + ".class");
            byte[] buffer;
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
            int nextValue = 0;
            try {
                while ( (nextValue = inputStream.read()) != -1 ) {
                    byteStream.write(nextValue);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            buffer = byteStream.toByteArray();
            return buffer;
        }
    }

     

    • loadClass()
    public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {

    This method serves as an entry point for the class loader. If only determining if the class exists or not, then resolve parameter is set to false.

    protected Class<?> loadClass(String name, boolean resolve)
      throws ClassNotFoundException {
         
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
            Class<?> c = findLoadedClass(name);
            if (c == null) {
                long t0 = System.nanoTime();
                    try {
                        if (parent != null) {
                            c = parent.loadClass(name, false);
                        } else {
                            c = findBootstrapClassOrNull(name);
                        }
                    } catch (ClassNotFoundException e) {
                        // ClassNotFoundException thrown if class not found
                        // from the non-null parent class loader
                    }
     
                    if (c == null) {
                        // If still not found, then invoke findClass in order
                        // to find the class.
                        c = findClass(name);
                    }
                }
                if (resolve) {
                    resolveClass(c);
                }
                return c;
            }
        }

    The default implementation of the method searches for classes in the following order

    • Invokes the findLoadedClass(String) to see if already loaded
    • Invokes the loadClass(String) on the parent class loader
    • Invoke the findClass(String) to find class
    • defineClass()
    protected final Class<?> defineClass(
      String name, byte[] b, int off, int len) throws ClassFormatError

    This is responsible for the conversion of an array of bytes into an instance of a class. Before using the class, need to resolve it.

     

    • findClass()

    Finding a class with the fully qualified name as a parameter. needing to override this method in custom classloader implementations that follow the delegation model for loading classes. Also, loadClass() invokes this method if the parent class loader couldn't find the requested class. The default implementation throws a ClassNotFoundException if no parent of the class loader finds the class.

     

    • getParent()

    Returns the parent class loader for delegation. null for a bootstrap class loader.

     

    • getResource

    Firstly, delegate its parent for searching, if a parent is null, the path of the class loader built into VM is searched. if failed, invoking findResource(String) to find the resource and returns a URL object for reading the resource or null.

    Note that Java loads resources from the classpath. Finally, resource loading is considered location-independent as it doesn't matter where the code is running as long as the environment is set to find the resources.

     

    • Context Classloaders

    Sometimes when JVM core classes need to dynamically to load classes or resources provided by application developers but encounter a problem because of visibility constraint. In this case, the java.lang.Thread class provide getContextClassLoader() that returns the ContextClassLoader for the particular thread. The ContextClassLoader is provided by the creator of the thread when loading resources and classes. If not set, it defaults to the class loader context of the parent thread.

    6. Java Virtual machine (JVM)

    Whatever Java program you run using JRE or JDK goes into JVM and JVM is responsible for executing the java program line by line hence it is also known as an interpreter.

    JVM becomes an instance of JRE at runtime of a Java program. It is widely known as a runtime interpreter.JVM largely helps in the abstraction of inner implementation from the programmers who make use of libraries for their programs from JDK.

    7. References

    https://www.baeldung.com/java-classloaders

    https://www.thistechnologylife.com/java-classloader/

    https://www.geeksforgeeks.org/differences-jdk-jre-jvm/

    https://www.geeksforgeeks.org/jvm-works-jvm-architecture/

    'StaticPL > JAVA' 카테고리의 다른 글

    Fork Join framework  (0) 2019.08.23
    Garbage Collection (GC)  (0) 2019.08.23
    Callable  (0) 2019.08.21
    Executors Framework and Thread Pools  (0) 2019.08.21
    CompletableFuture, and Future  (0) 2019.08.20

    댓글

Designed by Tistory.