簡體   English   中英

為什么InputStreamReader在從jar讀取時會拋出NPE?

[英]Why does InputStreamReader throw a NPE when reading from a jar?

我正在嘗試使用流來迭代已知目錄中的類文件。 最終目標是獲取特定包中存在的所有類的類名,然后在運行時加載類並使用反射來獲取所有靜態常量的名稱和值。 當我在我的機器上從源運行程序時,這可以工作,但是當我將它作為jar運行時, BufferedReader會從ready()readLine()拋出一個NPE。 這是代碼(為簡潔起見,省略了錯誤處理和最佳實踐):

private void printClassNamesInPackage(final String strPackage) throws Exception {
    // The returned implementation of InputStream seems to be at fault
    final InputStream       packageStream = getClass().getClassLoader().getResourceAsStream( strPackage );
    final InputStreamReader streamReader  = new InputStreamReader( packageStream );
    final BufferedReader    reader        = new BufferedReader( streamReader );
    // Throws NPE from inside ready() - SEE STACKTRACE BELOW
    // reader.ready()
    String strLine;
    // Throws NPE from inside readLine() -  SEE STACKTRACE BELOW
    while ( null != (strLine = reader.readLine()) ) {
        System.out.println( strLine );
    }
}

來自reader.ready()

java.lang.NullPointerException
    at java.io.FilterInputStream.available(FilterInputStream.java:142)
    at sun.nio.cs.StreamDecoder.inReady(StreamDecoder.java:343)
    at sun.nio.cs.StreamDecoder.implReady(StreamDecoder.java:351)
    at sun.nio.cs.StreamDecoder.ready(StreamDecoder.java:165)
    at java.io.InputStreamReader.ready(InputStreamReader.java:178)
    at java.io.BufferedReader.ready(BufferedReader.java:436)

來自reader.readLine()

java.lang.NullPointerException
    at java.io.FilterInputStream.read(FilterInputStream.java:116)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)

單步執行會顯示以下InputStream實現:

  • 來自: java.io.ByteArrayInputStream
  • 來自jar: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream

進一步研究JarURLInputStream我發現繼承的(來自FilterInputStream )字段InputStream innull ,這導致了生成的NPE。

不幸的是,這就像我能夠進入調試器一樣深。

關於如何正確地做到這一點的任何想法? 我錯過了什么或做錯了什么? 謝謝!

文件夾不會返回包含所有文件列表的InputStream 使用JarInputStream以編程方式提取JAR。 你可以在這里找到一個例子。 作為參考,這里有一個略微修改的相關摘錄:

public static List<String> getClassNamesInPackage(String jarName, String packageName) throws IOException {
    JarInputStream jarFile = new JarInputStream(new FileInputStream(jarName));
    packageName = packageName.replace(".", "/");
    List<String> classes = new ArrayList<String>();

    try {
        for (JarEntry jarEntry; (jarEntry = jarFile.getNextJarEntry()) != null;) {
            if ((jarEntry.getName().startsWith(packageName)) && (jarEntry.getName().endsWith(".class"))) {
                classes.add(jarEntry.getName().replace("/", "."));
            }
        }
    } finally {
        jarFile.close();
    }

    return classes;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM