Вопросы относительно InvalidJarIndexException?
Я просмотрел документ спецификации JAR и обнаружил, что в памяти hashtable
создан с использованием INDEX.LST
файл, чтобы ускорить процесс поиска файла класса.
Если кто-нибудь может ответить на мои следующие вопросы -
Когда
hashtable
построен? Когда приложение загружается или когда приходит запрос на загрузку апплета?Поскольку все классы уже являются частью архива, зачем нужно
InvalidJarIndexException
, Как индексы могут стать недействительными? например, в моем случае я получаюInvalidJarIndexException
когда я используюindex=true
вместе сindexjars
в моей сборке муравьев, но я не вижу исключений, когда indexjars не используются.Как я должен идти о разрешении
InvalidJarIndexException
если я хочу придерживаться индексации?Роль плагина Java-браузера в загрузке файлов JAR?
3 ответа
JarIndex, кажется, полезен для апплетов и сетей. Это может помешать загрузке ненужных архивов.
Здесь у нас есть так называемая корневая банка, которая включает в себя INDEX.LIST
файл и этот файл включает в себя отображение из класса в библиотеку. Загрузчик классов прочитает файл, создаст внутреннюю хеш-таблицу и использует эту таблицу, чтобы определить, где можно найти класс. Если библиотека еще не загружена, она загрузит ее для загрузки класса. В противном случае пришлось бы загружать все библиотеки одновременно, чтобы разрешить один класс (потому что имя класса никогда не дает подсказки, где класс можно найти)
Как только загрузчик классов находит такой индекс, он доверяет этой информации и будет жаловаться на исключение, если информация не соответствует действительности. Скажем, индекс говорит загрузчику классов, что com.example.MyClass
можно найти внутри http://example.com/a.jar
, тогда он загрузит (если еще не сделал) банку и заглянет только внутрь этой библиотеки. Если такого класса нет, он не будет смотреться в разных банках (или даже загружать дополнительные баночки), но будет иметь горб с вами (и выкинет исключение).
Если вы столкнетесь с таким исключением, вы можете быть довольно потеряны. Проблема (поврежденный файл INDEX.LIST) не может быть исправлена на стороне потребителей. Но потому что загрузчик классов ожидает INDEX.LIST
файл в первом jar на пути к классам, изменение порядка библиотек в выражении classpath может решить эту проблему, отключив функцию индексатора.
Дальнейшее чтение
Рабочий пример с муравьем
Я создал два очень простых класса для печати 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 (build.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
работает успешно. Затем я переместил второй класс в другой пакет и снова начал сборку. И снова он создал работающее приложение.
Во время экспериментов я понял, что
- необходимо форсировать создание всех банок, особенно основной. Если муравей восстанавливает
factory.jar
Индекс не будет обновлен и может быть недействительным. Вот почему я добавилdelete
задачи. main.jar
должен быть создан после того, как все другие банки созданы.
Я никогда не сталкивался с этой проблемой, поэтому я боюсь, что я вам мало чем помогу, но я сделаю все возможное, чтобы облегчить ситуацию.
Он создается при загрузке класса: сам загрузчик класса ищет
index.list
файл и использовать его, если он доступен.Вы можете получить это исключение, если
index.list
Файл поврежден, потому что, если загрузчик классов нашел индексный файл, он больше не будет искать путь к классу для загрузки класса: он будет использовать только индекс. Здесь, кажется, он не может даже загрузить его, поэтому он бросаетInvalidJarIndexException
Попробуйте вручную сгенерировать
index.list
сjar
инструмент, используя-i
вариант. Если это работает, то это проблема муравья: сравните сгенерированные файлы для расследования. Если он по-прежнему не работает, проверьте файл index.list вручную (неправильная кодировка "усеченные длинные пути", пропущенные классы ").Ненужные. Процесс загрузки класса выполняется загрузчиком классов. То, как на самом деле работает файл jar, не имеет значения.
Редактировать, чтобы добавить комментарий дьявола Джина:
Индексация в муравье раньше имела ошибки. Вам нужно использовать версии 1.6 или позже, чтобы индексирование работало. Чтобы индексировать jar, вы должны установить index=true вместе с указанием jar-файлов в теге indexjars. http://ant.apache.org/manual/Tasks/jar.html
Может ли этот фрагмент помочь вам в его расследовании:
echo -e "\n`jar -tf main.jar | sed -e '/.class/d' -e '/.properties/d' -e '/services\/./d' -e '/.res/d' -e '/NOTICE/d' -e '/LICENSE/d' -e '/MANIFEST.MF/d' -e 's/.$//'`"
или просто
jar -tf main.jar