Spec-Zone .ru
спецификации, руководства, описания, API
|
JarClassLoader class расширяет java.net.URLClassLoader. Поскольку его имя подразумевает, URLClassLoader разрабатывается, чтобы использоваться для того, чтобы загрузить классы и ресурсы, к которым получают доступ, ища ряд URL. URL могут сослаться или на каталоги или на файлы JAR.
В дополнение к разделению на подклассы URLClassLoader JarClassLoader также использует функции в двух других новых связанных с JAR API, пакете java.util.jar и java.net.JarURLConnection class. В этом разделе мы будем подробно смотреть на конструктора и два метода JarClassLoader.
Конструктор берет экземпляр java.net.URL как параметр. URL, который передают этому конструктору, будет использоваться в другом месте в JarClassLoader, чтобы найти файл JAR, из которого должны быть загружены классы.
public JarClassLoader(URL url) { super(new URL[] { url }); this.url = url; }
Объект URL передают конструктору суперкласса, URLClassLoader, который берет массив URL[], а не единственный экземпляр URL, как параметр.
Как только объект JarClassLoader создается с URL связанного JAR приложения, это собирается нуждаться в способе определить, который class в файле JAR является точкой входа приложения. Это - задание метода getMainClassName:
public String getMainClassName() throws IOException { URL u = new URL("jar", "", url + "!/"); JarURLConnection uc = (JarURLConnection)u.openConnection(); Attributes attr = uc.getMainAttributes(); return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null; }
Можно вспомнить из предыдущего урока, что точка входа связанного JAR приложения определяется заголовком Main-Class декларации файла JAR. Чтобы понять, как getMainClassName получает доступ к значению заголовка Main-Class, давайте смотреть на метод подробно, обращая особое внимание на новые обрабатывающие JAR функции, которые это использует:
Метод getMainClassName использует JAR формат URL, определенный java.net.JarURLConnection class. Синтаксис для URL файла JAR как в этом примере:
jar:http://www.example.com/jarfile.jar!/
Завершающийся разделитель !/ указывает, что URL обращается ко всему файлу JAR. Что-либо после разделителя обращается к определенному содержанию файла JAR, как в этом примере:
jar:http://www.example.com/jarfile.jar!/mypackage/myclass.class
Первая строка в методе getMainClassName:
URL u = new URL("jar", "", url + "!/");
Этот оператор создает новый объект URL представление JAR URL, добавляя разделитель !/ к URL, который использовался в создании экземпляра JarClassLoader.
Этот class представляет линию связи между приложением и файлом JAR. У этого есть методы для того, чтобы получить доступ к декларации файла JAR. Вторая строка getMainClassName:
JarURLConnection uc = (JarURLConnection)u.openConnection();
В этом операторе экземпляр URL, создаваемый в первой строке, открывает URLConnection. Экземпляр URLConnection тогда бросается к JarURLConnection, таким образом, это может использовать в своих интересах обрабатывающие JAR функции JarURLConnection.
С JarURLConnection, открытым для файла JAR, можно получить доступ к информации о заголовке в декларации файла JAR при использовании метода getMainAttributes JarURLConnection. Этот метод возвращает экземпляр java.util.jar.Attributes, class, который отображает имена заголовка в декларациях файла JAR с их связанными строковыми значениями. Третья строка в getMainClassName создает объект Attributes:
Attributes attr = uc.getMainAttributes();
Чтобы получить значение заголовка Main-Class декларации, четвертая строка getMainClassName вызывает метод Attributes.getValue:
return attr != null ? attr.getValue(Attributes.Name.MAIN_CLASS) : null;
Параметр метода, Attributes.Name.MAIN_CLASS, определяет, что это - значение заголовка Main-Class, который Вы хотите. (Attributes.Name class также обеспечивает статические поля, такие как MANIFEST_VERSION, CLASS_PATH, и SEALED для того, чтобы определить другие стандартные явные заголовки.)
Мы видели, как JarURLClassLoader может идентифицировать основной class в связанном JAR приложении. Последний метод, который рассмотрит, JarURLClassLoader.invokeClass, позволяет тому основному class быть вызванным, чтобы запустить связанное JAR приложение:
public void invokeClass(String name, String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException { Class c = loadClass(name); Method m = c.getMethod("main", new Class[] { args.getClass() }); m.setAccessible(true); int mods = m.getModifiers(); if (m.getReturnType() != void.class || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) { throw new NoSuchMethodException("main"); } try { m.invoke(null, new Object[] { args }); } catch (IllegalAccessException e) { // This should not happen, as we have disabled access checks } }
Метод invokeClass берет два параметра: имя точки входа приложения class и массив строковых параметров, чтобы передать к методу main class точки входа. Во-первых, основной class загружается:
Class c = loadClass(name);
Метод loadClass наследован от java.lang.ClassLoader.
Как только основной class загружается, API Reflection пакета java.lang.reflect используется, чтобы передать параметры class и запустить его. Можно сослаться на учебное руководство на API Reflection для анализа отражения.