Я пытаюсь перебрать файлы классов в известном каталоге, используя потоки. Конечная цель - получить имена классов для всех классов, которые существуют в конкретном пакете, затем загрузить классы во время выполнения и использовать отражение, чтобы получить имена и значения всех статических констант. Это работает, когда я запускаю программу из источника на моей машине, но когда я запускаю ее как jar, BufferedReader
выбрасывает NPE из ready()
и readLine()
. Вот код (с кратким описанием обработки ошибок и передового опыта):
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
- Из банки:
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream
Заглядывая дальше в JarURLInputStream
, я обнаружил, что унаследованное (от FilterInputStream
) поле InputStream in
равно null
, что приводит к полученному NPE.
К сожалению, это настолько глубоко, насколько я смог получить в отладчике.
Есть идеи, как правильно это сделать? Что я пропускаю или делаю неправильно? Спасибо!