JarIndex, кажется, полезен для апплетов и работы в сети.Это может предотвратить загрузку ненужных архивов.
Здесь у нас есть так называемый root jar , который включает в себя файл INDEX.LIST
, и этот файл включает в себя отображение из класса в библиотеку.Загрузчик классов прочитает файл, создаст внутреннюю хеш-таблицу и использует эту таблицу, чтобы определить, где можно найти класс.Если библиотека еще не загружена, она загрузит ее для загрузки класса.В противном случае пришлось бы загружать все библиотеки одновременно, чтобы разрешить один класс (поскольку имя класса никогда не дает подсказки, где класс можно найти)
Как только загрузчик классов находит такой индекс, он доверяет этой информациии будет жаловаться с исключением, если информация не соответствует действительности.Скажем, индекс сообщает загрузчику классов, что com.example.MyClass
можно найти внутри http://example.com/a.jar
, затем он загрузит (если еще не сделал) флягу и заглянет только внутрь этой библиотеки.Если такого класса нет, он будет не искать в разных банках (или даже загружать дополнительные банки), но будет иметь горб с вами (и выбрасывать исключение).
Если вы столкнетесь с такимисключение, вы можете быть довольно потеряны.Проблема (поврежденный файл INDEX.LIST) не может быть исправлена на стороне потребителей.Но поскольку загрузчик классов ожидает файл INDEX.LIST
в первом jar на пути к классам, изменение порядка библиотек в выражении classpath может решить такую проблему, отключив функцию индексатора.
Дополнительное чтение
Рабочий пример с ant
Я создал два очень простых класса для печати Hello world:
package test;
public class Hello {
public static void main(String[] args) {
System.out.println(HelloTextFactory.createResponse());
}
}
и
package test;
public class HelloTextFactory {
public static String createResponse() {
return "Hello world";
}
}
и файл ant (сборка.xml) для создания архивов:
<project name="test">
<target name="jar" description="description">
<delete file="main.jar" />
<delete file="factory.jar" />
<jar destfile="factory.jar" includes="test/HelloTextFactory.class" basedir="bin" />
<jar destfile="main.jar" includes="test/Hello.class" basedir="bin" index="true">
<indexjars>
<fileset dir="." id="jars">
<include name="factory.jar" />
</fileset>
</indexjars>
<manifest>
<attribute name="Main-Class" value="test.Hello" />
<attribute name="Class-Path" value="factory.jar" />
</manifest>
</jar>
</target>
</project>
Этот файл сборки предполагает, что классы были скомпилированы в папку bin
перед запуском сценария.
При запуске сценария сборки создаются два jar-файла, main.jar содержит индекс и java -jar main.jar
успешно выполняется.Затем я переместил второй класс в другой пакет и снова начал сборку.И снова, он создал рабочее приложение.
Во время экспериментов я понял, что
- необходимо принудительно создать все банки, особенно основной сосуд.Если ant перестроит
factory.jar
, индекс не будет обновлен и может быть недействительным.Вот почему я добавил delete
задач. main.jar
должен быть создан после все остальные банки созданы.