Bootstrap class loader java

Class ClassLoader

A class loader is an object that is responsible for loading classes. The class ClassLoader is an abstract class. Given the binary name of a class, a class loader should attempt to locate or generate data that constitutes a definition for the class. A typical strategy is to transform the name into a file name and then read a «class file» of that name from a file system.

Every Class object contains a reference to the ClassLoader that defined it.

Class objects for array classes are not created by class loaders, but are created automatically as required by the Java runtime. The class loader for an array class, as returned by Class.getClassLoader() is the same as the class loader for its element type; if the element type is a primitive type, then the array class has no class loader.

Applications implement subclasses of ClassLoader in order to extend the manner in which the Java virtual machine dynamically loads classes.

Class loaders may typically be used by security managers to indicate security domains.

In addition to loading classes, a class loader is also responsible for locating resources. A resource is some data (a » .class » file, configuration data, or an image for example) that is identified with an abstract ‘/’-separated path name. Resources are typically packaged with an application or library so that they can be located by code in the application or library. In some cases, the resources are included so that they can be located by other libraries.

The ClassLoader class uses a delegation model to search for classes and resources. Each instance of ClassLoader has an associated parent class loader. When requested to find a class or resource, a ClassLoader instance will usually delegate the search for the class or resource to its parent class loader before attempting to find the class or resource itself.

Class loaders that support concurrent loading of classes are known as parallel capable class loaders and are required to register themselves at their class initialization time by invoking the ClassLoader.registerAsParallelCapable method. Note that the ClassLoader class is registered as parallel capable by default. However, its subclasses still need to register themselves if they are parallel capable. In environments in which the delegation model is not strictly hierarchical, class loaders need to be parallel capable, otherwise class loading can lead to deadlocks because the loader lock is held for the duration of the class loading process (see loadClass methods).

Читайте также:  Php function argument callback

Run-time Built-in Class Loaders

  • Bootstrap class loader. It is the virtual machine’s built-in class loader, typically represented as null , and does not have a parent.
  • Platform class loader. The platform class loader is responsible for loading the platform classes. Platform classes include Java SE platform APIs, their implementation classes and JDK-specific run-time classes that are defined by the platform class loader or its ancestors. The platform class loader can be used as the parent of a ClassLoader instance. To allow for upgrading/overriding of modules defined to the platform class loader, and where upgraded modules read modules defined to class loaders other than the platform class loader and its ancestors, then the platform class loader may have to delegate to other class loaders, the application class loader for example. In other words, classes in named modules defined to class loaders other than the platform class loader and its ancestors may be visible to the platform class loader.
  • System class loader. It is also known as application class loader and is distinct from the platform class loader. The system class loader is typically used to define classes on the application class path, module path, and JDK-specific tools. The platform class loader is the parent or an ancestor of the system class loader, so the system class loader can load platform classes by delegating to its parent.

Normally, the Java virtual machine loads classes from the local file system in a platform-dependent manner. However, some classes may not originate from a file; they may originate from other sources, such as the network, or they could be constructed by an application. The method defineClass converts an array of bytes into an instance of class Class . Instances of this newly defined class can be created using Class.newInstance .

The methods and constructors of objects created by a class loader may reference other classes. To determine the class(es) referred to, the Java virtual machine invokes the loadClass method of the class loader that originally created the class.

For example, an application could create a network class loader to download class files from a server. Sample code might look like:

ClassLoader loader = new NetworkClassLoader(host, port); Object main = loader.loadClass("Main", true).newInstance(); . . .

The network class loader subclass must define the methods findClass and loadClassData to load a class from the network. Once it has downloaded the bytes that make up the class, it should use the method defineClass to create a class instance. A sample implementation is:

class NetworkClassLoader extends ClassLoader < String host; int port; public Class findClass(String name) < byte[] b = loadClassData(name); return defineClass(name, b, 0, b.length); >private byte[] loadClassData(String name) < // load the class data from the connection . . . >>

Binary names

Any class name provided as a String parameter to methods in ClassLoader must be a binary name as defined by The Java Language Specification .

Читайте также:  Примеры switch case php

Examples of valid class names include:

"java.lang.String" "javax.swing.JSpinner$DefaultEditor" "java.security.KeyStore$Builder$FileBuilder$1" "java.net.URLClassLoader$3$1"

Any package name provided as a String parameter to methods in ClassLoader must be either the empty string (denoting an unnamed package) or a fully qualified name as defined by The Java Language Specification .

Источник

Загрузка классов в Java. Теория

Одной из основных особенностей платформы Java является модель динамической загрузки классов, которая позволяет загружать исполняемый код в JRE не перезагружая основое приложение. Такая особенность широко используется в серверах приложений, получивших последнее время высокую популярность.

В статье рассмотрены базовые понятия, аспекты и принципы модели динамической загрузки кода. В следующей статье будет рассмотрена реализация собственного загрузчика классов, как основного механизма приложения с плагино-модульной архитектурой.

Введение

Любой класс (экземпляр класса java.lang.Class в среде и .class файл в файловой системе), используемый в среде исполнения был так или иначе загружен каким-либо загрузчиком в Java. Для того, чтобы получить загрузчик, которым был загружен класс А, необходимо воспользоваться методом A.class.getClassLoader().

Классы загружаются по мере надобности, за небольшим исключением. Некоторые базовые классы из rt.jar (java.lang.* в частности) загружаются при старте приложения. Классы расширений ($JAVA_HOME/lib/ext), пользовательские и большинство системных классов загружаются по мере их использования.

Виды загрузчиков

Различают 3-и вида загрузчиков в Java. Это — базовый загрузчик (bootstrap), системный загрузчик (System Classloader), загрузчик расширений (Extension Classloader).

Bootstrap — реализован на уровне JVM и не имеет обратной связи со средой исполнения. Данным загрузчиком загружаются классы из директории $JAVA_HOME/lib. Т.е. всеми любимый rt.jar загружается именно базовым загрузчиком. Поэтому, попытка получения загрузчика у классов java.* всегда заканчиватся null’ом. Это объясняется тем, что все базовые классы загружены базовым загрузчиком, доступа к которому из управляемой среды нет.

Управлять загрузкой базовых классов можно с помощью ключа -Xbootclasspath, который позволяет переопределять наборы базовых классов.

System Classloader — системный загрузчик, реализованный уже на уровне JRE. В Sun JRE — это класс sun.misc.Launcher$AppClassLoader. Этим загрузчиком загружаются классы, пути к которым указаны в переменной окружения CLASSPATH.

Управлять загрузкой системных классов можно с помощью ключа -classpath или системной опцией java.class.path.

Extension Classloader — загрузчик расширений. Данный загрузчик загружает классы из директории $JAVA_HOME/lib/ext. В Sun JRE — это класс sun.misc.Launcher$ExtClassLoader.

Управлять загрузкой расширений можно с помощью системной опции java.ext.dirs.

Читайте также:  Стандартные спреи для css

Понятия

Различают текущий загрузчик (Current Classloader) и загрузчик контекста (Context Classloader).

Current Classloader — это загрузчик класса, код которого в данный момент исполняется. Текущий загрузчик используется по умолчанию для загрузки классов в процессе исполнения. В часности, при использовании метода Class.forName(«»)/ClassLoader.loadClass(«») или при любой декларации класса, ранее не загруженного.

Context Classloader — загрузчик контекста текущего потока. Получить и установить данный загрузчик можно с помощью методов Thread.getContextClassLoader()/Thread.setContextClassLoader(). Загрузчик контекста устанавливается автоматически для каждого нового потока. При этом, используется загрузчик родительского потока.

Модель делегирования загрузки

Начиная с версии Java 2 Platform, Standard Edition, v1.2 загрузчики классов образуют иерархию. Корневым является базовый (у него предка нет). Все остальные загрузчики при инициализации инстанциируют ссылку на родительский загрузчик. Такая иерархия необходима для модели делегирования загрузки. В общем случа, иерархия выглядит следующим образом.

Право загрузки класса рекурсивно делегируется от самого нижнего загрузчика в иерархии к самому верхнему. Такой подход позволяет загружать классы тем загрузчиком, который максимально близко находится к базовому. Так достигается максимальная область видимости классов. Под областью видимости подразумевается следующее. Каждый загрузчик ведет учет классов, которые были им загружены. Множество этих классов и назвается областью видимости.

Рассмотрим процесс загрузки более детально. Пусть в систем исполнения встретилась декларация переменной пользовательского класс Student.

1) Системный загрузчик попытается поискать в кеше класс Student.
_1.1) Если класс найден, загрузка окончена.
_1.2) Если класс не найден, загрузка делегируется загрузчику расширений.
2) Загрузчик расширений попытается поискать в кеше класс Student.
_2.1) Если класс найден, загрузка окончена.
_2.2) Если класс не найден, загрузка делегируется базовому загрузчику.
3) Базовый загрузчик попытается поискать в кеше класс Student.
_3.1) Если класс найден, загрузка окончена.
_3.2) Если класс не найден, базовый загрузчик попытается его загрузить.
__3.2.1) Если загрузка прошла успешно, она закончена 😉
__3.2.2) Иначе управление предается загрузчику раширений.
_3.3) Загрузчик расширений пытается загрузить класс.
__3.3.1) Если загрузка прошла успешно, она закончена 😉
__3.3.2) Иначе управление предается системному загрузчику.
_3.4) Системный загрузчик пытается загрузить класс.
__3.4.1) Если загрузка прошла успешно, она закончена 😉
__3.4.2) Иначе генерируется исключение java.lang.ClassNotFoundException.

Если в системе присутствуют пользовательские загрузчики, они должны
а) расширять класс java.lang.ClassLoader;
б) поддерживать модель динамической загрузки.

Inside

Запустим простейшее приложениие с ключем -verbose:class.

public static void main( String args[]) C c = new C();
B b = new B();
A a = new A();
>
>

* This source code was highlighted with Source Code Highlighter .

Вывод показывает, что классы были загружены не в том порядке в котором были использованы. Это обусловлено наследованием.

[Loaded Main from file:/C:/devel/CL/bin/]
[Loaded A from file:/C:/devel/CL/bin/]
[Loaded B from file:/C:/devel/CL/bin/]
[Loaded C from file:/C:/devel/CL/bin/]

Источник

Оцените статью