[英]Questions regarding InvalidJarIndexException?
我瀏覽了JAR規范文檔,發現使用INDEX.LST
文件創建了一個內存中的hashtable
以加快類文件的查找過程。
什么時候構造hashtable
? 應用程序何時加載或何時請求加載小程序?
由於所有類均已成為歸檔的一部分,因此為什么要獲取InvalidJarIndexException
。 索引如何變為無效? 例如,在我的情況下,當我在我的螞蟻構建indexjars
index=true
連同indexjars
一起使用時,我會收到InvalidJarIndexException
但當不使用InvalidJarIndexException
時,我看不到任何異常。
如果要堅持使用索引,應該如何解決InvalidJarIndexException
?
Java瀏覽器插件在下載jar文件中的作用?
該代碼段可以幫助您進行調查:
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
我從來沒有遇到過這個問題,所以我很害怕我不會幫助您,但是我會盡力減輕一切。
它是在類加載器加載時構造的:類加載器本身會查找index.list
文件,並在可用時使用它。
如果index.list
文件損壞,則可以得到此異常,因為如果類加載器找到了索引文件,它將不再在類路徑中查找以加載類:它將僅使用索引。 在這里,似乎甚至無法加載它,因此拋出InvalidJarIndexException
嘗試使用-i
選項,使用jar
工具手動生成index.list
。 如果可行,那就是一個螞蟻問題:比較生成的文件以進行調查。 如果仍然無法使用,請手動檢查index.list文件(編碼錯誤?截短的長路徑?缺少類?)。
不相關。 類加載過程由類加載器完成。 jar文件實際運行的方式無關緊要。
編輯以添加Devil Jin的評論:
螞蟻的索引較早有錯誤。 您需要使用1.6版或更高版本才能使索引正常工作。 要使jar索引,您必須設置index = true以及在indexjars標記中指定jar文件。 ant.apache.org/manual/Tasks/jar.html#indexjars
JarIndex似乎對applet和網絡很有用。 它可以防止加載不必要的檔案。
在這里,我們有一個所謂的root jar ,它包含INDEX.LIST
文件,並且該文件包含從類到庫的映射。 類加載器將讀取文件,創建一個內部哈希表,並使用該表來確定在哪里可以找到一個類。 如果尚未加載該庫,則它將加載它以加載該類。 否則,它將不得不一次加載所有庫以解決單個類(因為類名永遠不會提供任何線索,可以找到一個類)
一旦類加載器找到了這樣的索引,它就會信任該信息,並且如果信息不正確,則會發出異常投訴。 假設索引告訴類加載器com.example.MyClass
可以在http://example.com/a.jar
內找到,則它將下載(如果尚未完成)jar並僅查看該庫。 如果沒有這樣的類,它將不會出現在不同的jar中(甚至下載其他jar),但會與您發生駝峰(並引發異常)。
如果遇到這樣的異常,您可能會迷路。 問題(損壞的INDEX.LIST文件)無法在使用者方面解決。 但是,因為類加載器希望類路徑的第一個jar中有INDEX.LIST
文件,所以更改類路徑表達式中庫的順序可以通過禁用索引器功能來解決此類問題。
進一步閱讀
螞蟻的工作實例
我創建了兩個非常簡單的類來打印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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.