2014-10-12 7 views
0

로드하려는 이미지가 내 항아리 안에 있지만 getResourceAsStream()은 항상 null을 반환합니다.getResourceAsStream이 null을 반환하는 이유는 무엇입니까?

디렉토리 구조 :

com/thesimpzone/watch_pugs/watch_pugs/{all my class files} 
META-INF/MANIFEST.MF 
resources/generic/mouse.png 

Content.java :

public abstract class Content { 

    protected Map<String, BufferedImage> images = new HashMap<String, BufferedImage>(); 

    protected String prefix; 

    public Content(String prefix){ 
     this.prefix = prefix; 
    } 

    protected void loadImage(String name){ 
     System.out.println(name); 
     System.out.println(prefix); 
     String path = (prefix + name); 
     System.out.println(path); 
     String identifier = name.substring(0, name.lastIndexOf(".")); 
     try{ 
      InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path); 
      images.put(identifier, ImageIO.read(in)); 
     }catch(IOException | ClassCastException e){ 
      throw new RuntimeException("Image " + identifier + " at " + path + " could not be loaded."); 
     } 
    } 
    [...] 
} 

GenericContent.java :

public class GenericContent extends Content { 

    public GenericContent(){ 
     super("resources/generic/"); 
     this.loadContent(); 
    } 

    @Override 
    public void loadContent() { 
     loadImage("mouse.png"); 
    } 

} 

스택 트레이스 :

mouse.png 
resources/generic/ 
resources/generic/mouse.png 
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null! 
    at javax.imageio.ImageIO.read(ImageIO.java:1348) 
    at com.thesimpzone.watch_pugs.watch_pugs.content.Content.loadImage(Content.java:29) 
    at com.thesimpzone.watch_pugs.watch_pugs.content.GenericContent.loadContent(GenericContent.java:17) 
    at com.thesimpzone.watch_pugs.watch_pugs.content.GenericContent.<init>(GenericContent.java:12) 
    at com.thesimpzone.watch_pugs.watch_pugs.Canvas.<init>(Canvas.java:45) 
    at com.thesimpzone.watch_pugs.watch_pugs.Framework.<init>(Framework.java:75) 
    at com.thesimpzone.watch_pugs.watch_pugs.Window.<init>(Window.java:50) 
    at com.thesimpzone.watch_pugs.watch_pugs.Window.<init>(Window.java:26) 
    at com.thesimpzone.watch_pugs.watch_pugs.Window$1.run(Window.java:60) 
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744) 
    at java.awt.EventQueue.access$400(EventQueue.java:97) 
    at java.awt.EventQueue$3.run(EventQueue.java:697) 
    at java.awt.EventQueue$3.run(EventQueue.java:691) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:714) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82) 

왜 클래스 로더가 이미지를 찾을 수 없는지 나는 모른다. 나는 컴파일 된 jar 파일을보고 파일이 존재하고 파일이 잘되도록 페인트가 잘 열립니다. getSystemClassLoader(), getClassLoader() 및 Content.class.getClassLoader()를 포함하여 다양한 ClassLoader 변형을 시도했습니다. getResource (path) .openStream() 대신 getResourceAsStream (path)을 사용하십시오. 접두어에 '/'를 붙이지 않고 시도 했으므로 아이디어가 다 빠져서 Google이 도움이되지 못합니다. 또한, '접두어'를 정의하는 일이 매우 어색하고 더 나은 방법이 있다면 누군가 내가 어떻게 보여 주 었는지 기뻐할 것 같습니다.

감사합니다.

+0

사이드 노트 :'prefix'는 이미'String'입니다. 거기에'toString()'을 호출하는 것은 아닙니다. –

+0

오, 그래, 내가 char []를 사용하려 할 때부터 최종 수 있습니다. –

+1

다음 번에 제안 할 내용으로 원래 코드를 재정 의하여 질문을 편집하지 마십시오. 그것은 답을 오도합니다. 필요한 경우 시도중인 새 코드와 결과를 추가하여 편집하십시오. –

답변

1

getResourceAsStream()을 호출 할 때 상대 패키지 대 절대 ​​패키지에 관한 것이므로 Content이 루트 인 패키지와 관련된 것을 찾고 있습니다.

은 선두 /없이 완전한 패키지 Thread.currentThread().getContextClassloader().getResourceAsStream()이다 사용

좋은 점을 패키지, 특히 jar 파일 내부 클래스 패스에는 "디렉토리"없다.

응용 프로그램 컨테이너 내부에는 대개 여러 클래스 로더가 있기 때문에 리소스를로드 할 때주의해야 할 필요가 없습니다. 귀하의 경우에는

:

Thread.currentThread().getContextClassloader().getResourceAsStream("resources/generic/mouse.png");

당신은 여전히이 방법으로 오류가 발생하는 경우 .jar 당신이 또는 생각처럼 내장되지 않은 당신은 아마 당신은 때로 믿을 수 IDE를 내부에서이 문제를 얻는 경우 내용을 resource/generic/의 클래스 경로에 복사하고 있지 않습니다. 항상 당신이 전화를 어느 곳에서 작동하고 어떤 클래스 로더 당신이, 그리고이 찾고 찾을 찾고 있습니다 위치에 대한 명시 적 같이

Thread.currentThread().getContextClassLoader().getResourceAsStream("path/to/resource/file.ext"); :

개인적으로 난 항상 양식을 사용 에 대한.

+0

흠 아직도 똑같은 오류 (현재 코드를 보여주기 위해 업데이트 된 OP)를 제공합니다. 변수가 아니라 리터럴을 사용해 보았지만 null InputStream 때문에 정확한 동일한 IllegalArgumentException을 보여줍니다. –

+0

그렇다면 .jar는 생각대로 빌드되지 않습니다. IDE 내부에서 이것을 얻는다면 아마도 classpath에'resource/generic'을 복사하지 않을 것입니다. 이 부분에 대한 구성 문제입니다. –

+0

내 디렉터리 구조는 내 보낸 .jar 파일의 압축을 풀었 기 때문에 이미지가 있습니다. –

관련 문제