sitelink1 http://pmguda.com/514 

Jar 파일에 리소스를 포함하여 배포하였을 경우 그 리소스에 접근하는 방법입니다.

예제코드:

package com.pmguda.resjar;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.sound.sampled.*;
import java.net.*;

public class JarResourceLoading extends JFrame
    implements ActionListener {

    JButton button;
    ImageIcon buttonIcon;
    Clip buhClip;

    public final static String SOUND_PATH = "res/gudaMid.wav";
    public final static String IMAGE_PATH = "res/gudaImage.jpg";

    public JarResourceLoading () {
        super ("Resources from .jar");
        // get image and make button
        URL imageURL = getClass().getClassLoader().getResource (IMAGE_PATH);
        System.out.println ("found image at " + imageURL);
        buttonIcon = new ImageIcon (imageURL);
        button = new JButton ("Click to Buh!", buttonIcon);
        button.setHorizontalTextPosition (SwingConstants.CENTER);
        button.setVerticalTextPosition (SwingConstants.BOTTOM);
        button.addActionListener (this);
        getContentPane().add (button);
        // load sound into Clip
        try {
            URL soundURL = getClass().getClassLoader().getResource (SOUND_PATH);
            System.out.println ("found sound at " + soundURL);
            Line.Info linfo = new Line.Info (Clip.class);
            Line line = AudioSystem.getLine (linfo);
            buhClip = (Clip) line;
            AudioInputStream ais = AudioSystem.getAudioInputStream(soundURL);
            buhClip.open(ais);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void actionPerformed (ActionEvent e) {
        System.out.println ("click!");
        if (buhClip != null) {
            buhClip.setFramePosition (0);
            buhClip.start();
        }
        else
            JOptionPane.showMessageDialog (this,
                                           "Couldn't load sound",
                                           "Error",
                                           JOptionPane.ERROR_MESSAGE);
    }

    public static final void main (String[] args) {
        JFrame frame = new JarResourceLoading();
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

그림 1.
jar.png

이클립스에서 jar 파일로 자동 배포 하였습니다. Jar 파일의 내부 구조도 이와 비슷하다.(압축을 풀어보면 알게된다.)

jar 파일안에 있는 이미지의 URL 은  Jar:file:/D:/resource.jar!/res/gudaImage.jpg

위의 코드에 대해 자세히 알아보고자 다른 자료를 찾아보았다.
다른 자료를 조금 인용하기 위해 긁어왔다.. 영문이다. ㅡㅡ;
해석해보면 그리 어렵지 않다. 위의 코드와 조금 다른 부분이 있을것이다. 잘 생각해 보자.


If you want to access a resource (configuration files, images, etc.) then you can certainly put it in a jar file, provided that jar file is in your classpath.

Then to access the resource, you can get a URL to it like this:
            URL url = this.getClass().getResource("/hello.jpg");
or you can get an InputStream to read it like this:
            InputStream is = this.getClass().getResourceAsStream("/app.properties");
Note that these methods will search for the resource in the directory tree relative to the package that "this" is in, so you will generally need the leading "/" to avoid that. But as for executable files in a jar file, forget it, there's no way to execute them from there. You can copy them out to a file and execute them from there, but that's the best you can do.


여기서 짚고 넘어가야 할 것은
패키지: com.pmguda.resjar
클래스: com.pmguda.resjar.JarResourceLoading
1.   getClass().getResource("gudaImage.jpg");
      현재 클래스의 위치에서 리소스를 찾는다
     클래스와 리소스의 위치가 같은 곳에 존재해야 한다.

2.   getClass().getResource("/res/gudaImage.jpg");
     패키지와 동일 루트에서 검색
3.   getClass().getClassLoader.getResource("res/gudaImage.jpg"); 
      패키지와 동일 루트에서의 상대 위치를 나타낸다.

java.lang.Class.getResource(String name)
Class.png

 

번역이 완전하지가 않아 이해하기 어려울듯 하다.

java.lang.Class.getResource(String name)에서
name 가 "/gudaImage.jpg" 일 경우 절대 경로명(/gudaImage.jpg)으로 사용되고
"gudaImage.jpg" 일 경우 현 클래스의 위치에서 시작하는 상대경로가 되겠지요 이를
절대경로로
나타내면 (/com/pmguda/resjar/gudaImage.jpg)

java.lang.ClassLoader.getResource(String name)
ClassLoader.png

1. getClass().getResource("/res/gudaImage.jpg"); 
2. getClass().getClassLoader.getResource("res/gudaImage.jpg"); 
동일한 URL을 리턴한다. 2번예시에서 앞에 "/" 을 넣어 시작하지 말도록 하자.
2번은 항상 상대경로만 인식하여 사용된다고 명심하시길..
ex)getClass().getClassLoader.getResource("/res/gudaImage.jpg");  

조금더 알아보고자 한다면 ClassLoader 에 대해 알아보는 것도 좋을듯 하다.

번호 제목 글쓴이 날짜 조회 수
347 java.util.Optional 에서의 map() 함수의 이해 황제낙엽 2026.06.24 666
346 linux(ubuntu) 의 jdk 21 이 설정된 환경에서 jdk 17 로 다운그레이드 절차 황제낙엽 2025.09.22 1532
345 [ChatGPT] javax.* 패키지와 jakarta.* 패키지의 혼합 사용 방안 황제낙엽 2025.04.15 2459
344 [ChatGPT] *.servlet.http.HttpServlet 클래스를 사용할 수 있는 주요 WAS 목록 황제낙엽 2025.04.14 2038
343 [ChatGPT] JDBC API에서 java.sql과 javax.sql 패키지의 차이점 황제낙엽 2025.01.31 2218
342 jakarta.servlet 패키지를 이용한 File Upload 구현 (2024.03.03, Servlet 5.0) 황제낙엽 2025.01.02 2310
341 [ChatGPT] Java EE가 Jakarta EE로 전환 황제낙엽 2025.01.01 2525
340 [ChatGPT] File.delete() 함수로 파일 삭제가 되지 않는 경우 황제낙엽 2024.12.10 2809
339 [ChatGPT] <jsp:include>에서 flush="true"를 설정시의 몇 가지 문제점 과 대안 황제낙엽 2024.07.19 2493
338 [Copilot] JSP, Servlet, web.xml, mysql 한글 설정 황제낙엽 2024.07.12 2555
337 Base64 클래스의 encode, decode 에서 URL-safe 황제낙엽 2024.07.10 2624
336 [Copilot] JSP 에서 다른 페이지를 현재 페이지에 포함시키는 문법 (include) 황제낙엽 2024.06.26 2570
335 Exception 출력에 대한 고찰 황제낙엽 2024.06.10 2198
334 google-auth-library-oauth2-http 라이브러리 다운로드 황제낙엽 2023.11.19 4026
333 firebase-admin-java 라이브러리 다운로드 (firebase admin sdk library) 황제낙엽 2023.11.19 2805
332 Enum 활용 (개인블로그, Effective Java) file 황제낙엽 2023.11.02 2760
331 Enum 활용 (우아한기술블로그) file 황제낙엽 2023.11.02 2790
330 servlet name 에 camel case 를 사용해서는 안되는 이유 황제낙엽 2023.10.24 2508
329 org.apache.commons.fileupload.servlet.ServletFileUpload 이용 예시 황제낙엽 2023.08.25 3336
328 ServletFileUpload.parseRequest() 실행 결과 리스트가 비어있는 오류 황제낙엽 2023.08.25 2935