2009-02-22 2 views
21

항아리에 포함 된 리소스로드 :나는이 방식으로 자원을로드 내 응용 프로그램에서

WinProcessor.class.getResource("repository").toString(); 

을이 날 수 있습니다 : 나는 IDE에서 내 응용 프로그램을 실행할 때

file:/root/app/repository (and I replace "file:" with empty string) 

이 잘 작동합니다 내 응용 프로그램의 항아리를 실행할 때,하지만 :

java -jar app.jar 

경로가된다 :

,536,
jar:/root/app.jar!/repository 

이 문제를 해결할 방법이 있습니까?

나는이 만들기 위해 "저장소"디렉토리 이름을 사용합니다 : 같은 방법으로

ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null); 

를, 내가 (대신 디렉토리의) 하나의 파일 이름을거야 내가 사용합니다 그것은이 방법 :

System.setProperty("javax.net.ssl.trustStore", fileNameString) 

답변

35

그런 다음 FileInputStream 또는 이와 비슷한 것을 사용하여 리소스를로드하려고하는 것처럼 들립니다. 하지 마십시오 : getResource에 전화하는 대신 getResourceAsStream으로 전화하여 그 데이터를 읽으십시오.

(당신은 대신 URL에서 자원을로드하지만, getResourceAsStream를 호출하면 좀 더 편리 할 수있다.)

편집 : 업데이트 된 대답을 본 데, 코드의 다른 비트는 데이터가에있는에 의존하는 것 파일 시스템의 물리적 단일 파일. 대답은 따라서 jar 파일로 묶는 것이 아닙니다. 이 별도의 파일인지 여부를 확인하고 임시 파일에 압축을 풀지는 않았지만 꽤 해킹 된 IMO 일 수 있습니다.

+1

동의합니다. 물리적 단일 파일 (Java Web Start for one)을 100 % 확신 할 수 없다고 말할 때마다 항상 스트림으로 코드해야합니다. –

5

는 (심지어 jar 파일에) 당신은 다음 리소스를로드 할 수 있습니다하는 URL 구축합니다 openStream 방법을 사용하여.

+1

입니다. 이것이'getResourceAsStream'의 기능입니다. –

9

java -jar app.jar을 사용하여 코드를 실행하면 java는 JAR 파일의 매니페스트에 정의 된 클래스 경로 (예 : Class-Path 속성) 만 사용합니다. 클래스가 app.jar이거나 클래스가 JAR 매니페스트의 Class-Path 속성에 설정된 클래스 경로에 있으면 다음 코드 스 니펫을 사용하여 해당 클래스를로드 할 수 있습니다. 여기서 className은 정규화 된 클래스 이름입니다.

final String classAsPath = className.replace('.', '/') + ".class"; 
final InputStream input = ClassLoader.getSystemResourceAsStream(path/to/class); 

지금 클래스가 JAR의 일부가 아닌 경우, 그것은 매니페스트의 Class-Path에없는 다음 클래스 로더를 찾을 수 없습니다. 대신 URLClassLoader을 사용할 수 있습니다. Windows와 Unix/Linux/MacOSX의 차이점을주의해서 처리해야합니다.

// the class to load 
final String classAsPath = className.replace('.', '/') + ".class"; 

// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below) 
final URL url = new URL("file", null, "///C:/Users/diffusive/app.jar"); 
//final URL url = new URL("file", null, "/Users/diffusive/app.jar"); 

// create the class loader with the JAR file 
final URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url }); 

// grab the resource, through, this time from the `URLClassLoader` object 
// rather than from the `ClassLoader` class 
final InputStream input = urlClassLoader.getResourceAsStream(classAsPath); 
당신이 예외를 처리해야합니다 두 예에서

및 리소스가 발견되지 않는 경우는 입력 스트림이 null 사실. 또한 InputStreambyte[]으로 가져와야하는 경우 Apache의 공용 주소 IOUtils.toByteArray(...)을 사용할 수 있습니다. Class을 원하면 클래스 로더의 defineClass(...) 메서드를 사용할 수 있습니다.이 메서드는 byte[]을 사용할 수 있습니다.

당신은 Windows 및 Unix/Linux 용 URL을 만들 github.com/robphilipp/diffusive

그리고 방법에 소스 포지 (SourceForge)에서 찾을 수 있습니다 확산 소스 코드에 ClassLoaderUtils 클래스에서이 코드를 찾을 수 있습니다

/상대 경로와 절대 경로의 MacOSX는 RestfulDiffuserManagerResource.createJarClassPath(...)

관련 문제