내 코드는 foo.jar 와 같은 JAR 파일 내에서 실행되며 코드에서 foo.jar 실행 폴더가 무엇인지 알아야합니다 .
경우에 따라서, foo.jar에이 에 C:\FOO\
, 나는 상관없이 나의 현재 작업 디렉토리가 무엇인지 그 경로를 얻을 싶어요.
내 코드는 foo.jar 와 같은 JAR 파일 내에서 실행되며 코드에서 foo.jar 실행 폴더가 무엇인지 알아야합니다 .
경우에 따라서, foo.jar에이 에 C:\FOO\
, 나는 상관없이 나의 현재 작업 디렉토리가 무엇인지 그 경로를 얻을 싶어요.
답변:
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getPath();
"MyClass"를 클래스 이름으로 바꾸십시오.
클래스가 파일이 아닌 위치에서로드 된 경우 분명히 이상한 일을합니다.
toURI()
단계는 공백과 플러스를 포함한 특수 문자의 문제를 피하기 위해 필수적입니다. 올바른 한 줄짜리는 다음과 같습니다 . 많은 특수 문자에는 return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
사용 URLDecoder
이 작동하지 않습니다. 자세한 내용은 아래 답변을 참조하십시오.
getProtectionDomain
stracktrace에서 수업을받는 경우 null입니다.val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
나를위한 최고의 솔루션 :
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
공백과 특수 문자의 문제를 해결해야합니다.
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
Linux 에서 @Iviggiani one ( ) 과 함께 완벽한 솔루션으로 보입니다 . 그러나 Windows에서는 시도하지 않았습니다.
URLDecoder
특수 문자를 해독하는 데 사용하지 않는 것이 좋습니다 . 특히, 같은 문자 +
는 공백으로 잘못 디코딩됩니다. 자세한 내용은 내 답변을 참조하십시오.
File
주어진에 대한를 얻으려면 Class
두 단계가 있습니다.
Class
A를URL
URL
A를File
두 단계를 이해하고 혼동하지 않는 것이 중요합니다.
일단 당신이 File
getParentFile
있으면 필요한 경우 포함 폴더를 얻기 위해 전화 를 걸 수 있습니다 .
Class
에URL
다른 답변에서 논의 된 바와 같이, URL
관련성을 찾는 두 가지 주요 방법 이 Class
있습니다.
URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
둘 다 장단점이 있습니다.
이 getProtectionDomain
접근 방식은 클래스의 기본 위치 (예 : 포함하는 JAR 파일)를 생성합니다. 그러나를 SecurityException
호출 할 때 Java 런타임의 보안 정책이 getProtectionDomain()
발생할 수 있으므로 응용 프로그램을 다양한 환경에서 실행해야하는 경우 모두 테스트하는 것이 가장 좋습니다.
이 getResource
접근 방식은 클래스의 전체 URL 리소스 경로를 생성하므로 추가 문자열 조작을 수행해야합니다. 그것은있을 수 있습니다 file:
경로뿐만 아니라 될 수 jar:file:
또는 같은 천하고도 뭔가 bundleresource://346.fwk2106232034:4/foo/Bar.class
OSGi 프레임 워크 내에서 실행하는 경우. 반대로,이 getProtectionDomain
방법 file:
은 OSGi 내에서도 URL을 올바르게 생성합니다 .
모두 참고 getResource("")
하고 getResource(".")
클래스가 JAR 파일 내에 거주 할 때, 내 테스트에서 실패; 두 호출 모두 null을 반환했습니다. 따라서 위의 # 2 호출이 더 안전 해 보이므로 대신 권장합니다.
URL
에File
어느 쪽이든, 일단 URL
다음 단계는로 변환됩니다 File
. 이것은 그 자체의 도전이다. 참조 그것에 대해 Kohsuke 가와구치의 블로그 게시물을 전체 세부 사항은 있지만, 짧은에, 당신은 사용할 수 있습니다new File(url.toURI())
URL의 형식이 올바른 한 .
마지막 으로을 사용 하지 않는 것이 좋습니다URLDecoder
. 의 URL의 일부 문자 :
와 /
특히는 유효한 URL 인코딩 된 문자 수 없습니다. 로부터 URLDecoder의 자바 독 :
인코딩 된 문자열의 모든 문자는 "a"~ "z", "A"~ "Z", "0"~ "9"및 "-", "_", "중 하나 인 것으로 가정합니다. . "및"* ". "%"문자는 허용되지만 특수 이스케이프 된 시퀀스의 시작으로 해석됩니다.
...
이 디코더가 잘못된 문자열을 처리 할 수있는 두 가지 방법이 있습니다. 잘못된 문자를 그대로 두거나 IllegalArgumentException을 발생시킬 수 있습니다. 디코더가 취하는 접근법은 구현에 맡겨져 있습니다.
실제로, URLDecoder
일반적으로 IllegalArgumentException
위의 위협 으로 던져지지 않습니다 . 파일 경로에로 인코딩 된 공백 %20
이 있으면이 방법이 작동하는 것처럼 보일 수 있습니다. 그러나 파일 경로에 영숫자가 아닌 다른 문자가 있으면 파일 경로를 조작하는 +
데 문제가 있습니다 URLDecoder
.
이러한 단계를 수행하기 위해 다음과 같은 방법이있을 수 있습니다.
/**
* Gets the base location of the given class.
* <p>
* If the class is directly on the file system (e.g.,
* "/path/to/my/package/MyClass.class") then it will return the base directory
* (e.g., "file:/path/to").
* </p>
* <p>
* If the class is within a JAR file (e.g.,
* "/path/to/my-jar.jar!/my/package/MyClass.class") then it will return the
* path to the JAR (e.g., "file:/path/to/my-jar.jar").
* </p>
*
* @param c The class whose location is desired.
* @see FileUtils#urlToFile(URL) to convert the result to a {@link File}.
*/
public static URL getLocation(final Class<?> c) {
if (c == null) return null; // could not load the class
// try the easy way first
try {
final URL codeSourceLocation =
c.getProtectionDomain().getCodeSource().getLocation();
if (codeSourceLocation != null) return codeSourceLocation;
}
catch (final SecurityException e) {
// NB: Cannot access protection domain.
}
catch (final NullPointerException e) {
// NB: Protection domain or code source is null.
}
// NB: The easy way failed, so we try the hard way. We ask for the class
// itself as a resource, then strip the class's path from the URL string,
// leaving the base path.
// get the class's raw resource path
final URL classResource = c.getResource(c.getSimpleName() + ".class");
if (classResource == null) return null; // cannot find class resource
final String url = classResource.toString();
final String suffix = c.getCanonicalName().replace('.', '/') + ".class";
if (!url.endsWith(suffix)) return null; // weird URL
// strip the class's path from the URL string
final String base = url.substring(0, url.length() - suffix.length());
String path = base;
// remove the "jar:" prefix and "!/" suffix, if present
if (path.startsWith("jar:")) path = path.substring(4, path.length() - 2);
try {
return new URL(path);
}
catch (final MalformedURLException e) {
e.printStackTrace();
return null;
}
}
/**
* Converts the given {@link URL} to its corresponding {@link File}.
* <p>
* This method is similar to calling {@code new File(url.toURI())} except that
* it also handles "jar:file:" URLs, returning the path to the JAR file.
* </p>
*
* @param url The URL to convert.
* @return A file path suitable for use with e.g. {@link FileInputStream}
* @throws IllegalArgumentException if the URL does not correspond to a file.
*/
public static File urlToFile(final URL url) {
return url == null ? null : urlToFile(url.toString());
}
/**
* Converts the given URL string to its corresponding {@link File}.
*
* @param url The URL to convert.
* @return A file path suitable for use with e.g. {@link FileInputStream}
* @throws IllegalArgumentException if the URL does not correspond to a file.
*/
public static File urlToFile(final String url) {
String path = url;
if (path.startsWith("jar:")) {
// remove "jar:" prefix and "!/" suffix
final int index = path.indexOf("!/");
path = path.substring(4, index);
}
try {
if (PlatformUtils.isWindows() && path.matches("file:[A-Za-z]:.*")) {
path = "file:/" + path.substring(5);
}
return new File(new URL(path).toURI());
}
catch (final MalformedURLException e) {
// NB: URL is not completely well-formed.
}
catch (final URISyntaxException e) {
// NB: URL is not completely well-formed.
}
if (path.startsWith("file:")) {
// pass through the URL as-is, minus "file:" prefix
path = path.substring(5);
return new File(path);
}
throw new IllegalArgumentException("Invalid URL: " + url);
}
SciJava Common 라이브러리 에서 이러한 메소드를 찾을 수 있습니다 .
다음을 사용할 수도 있습니다.
CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
ClassLoader.getResource ()를 사용하여 현재 클래스의 URL을 찾으십시오.
예를 들면 다음과 같습니다.
package foo;
public class Test
{
public static void main(String[] args)
{
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("foo/Test.class"));
}
}
(이 예제 는 비슷한 질문 에서 가져온 것입니다 .)
디렉토리를 찾으려면 URL을 수동으로 분리해야합니다. jar URL 형식에 대해서는 JarClassLoader 학습서 를 참조하십시오 .
NPE
당신이 묻는 질문에 대한 답변을 하지 않았기 때문에 ( 아니오 JAR 디렉토리에 대한 경로가 요청되었고 당신은 전혀 다른 질문에 대답했습니다 : 수업의 경로). 2. 다른 사람들이 지적했듯이 동일한 문제가 발생했지만 애플릿에서는 작동하지 않습니다. 3. 리턴 된 경로는 정식 경로 표시가 아닙니다 jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class
..
최근에 사용을 제안한 사람이 없다는 것이 놀랍습니다 Path
. 여기에는 인용이 있습니다. " 이 Path
클래스에는 경로에 대한 정보를 얻거나, 경로의 요소에 액세스하거나, 경로를 다른 형식으로 변환하거나, 경로의 일부를 추출하는 데 사용할 수있는 다양한 방법이 포함되어 있습니다 "
따라서 좋은 대안은 다음 Path
과 같이 목표 를 얻는 것입니다.
Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
Linux, Mac 및 Windows에서 작동하는 유일한 솔루션 :
public static String getJarContainingFolder(Class aclass) throws Exception {
CodeSource codeSource = aclass.getProtectionDomain().getCodeSource();
File jarFile;
if (codeSource.getLocation() != null) {
jarFile = new File(codeSource.getLocation().toURI());
}
else {
String path = aclass.getResource(aclass.getSimpleName() + ".class").getPath();
String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
jarFile = new File(jarFilePath);
}
return jarFile.getParentFile().getAbsolutePath();
}
나는 같은 문제가 있었고 그 방법으로 해결했습니다.
File currentJavaJarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String currentJavaJarFilePath = currentJavaJarFile.getAbsolutePath();
String currentRootDirectoryPath = currentJavaJarFilePath.replace(currentJavaJarFile.getName(), "");
나는 당신에게 도움이 되었기를 바랍니다.
다른 의견으로의 업그레이드는 다음과 같습니다.
jar 파일의 동일한 위치에있는 .jar 파일 외부의 상대 "폴더"사용 :
String path =
YourMainClassName.class.getProtectionDomain().
getCodeSource().getLocation().getPath();
path =
URLDecoder.decode(
path,
"UTF-8");
BufferedImage img =
ImageIO.read(
new File((
new File(path).getParentFile().getPath()) +
File.separator +
"folder" +
File.separator +
"yourfile.jpg"));
URLDecoder
특수 문자를 해독하는 데 사용하지 않는 것이 좋습니다 . 특히, 같은 문자 +
는 공백으로 잘못 디코딩됩니다. 자세한 내용은 내 답변을 참조하십시오.
URLDecoder
이름에도 불구하고 URL이 아닌 URL 및 양식 매개 변수 이름과 값을 디코딩하기위한 것입니다.
jar 파일을 실행하는 경로를 얻기 위해 위의 솔루션을 연구하고 서로 다른 차이점이있는 모든 방법을 시도했습니다. 이 코드가 Eclipse IDE에서 실행중인 경우 모두 표시된 클래스를 포함하여 파일의 경로를 찾고 찾은 경로로 표시된 파일을 열거 나 작성할 수 있어야합니다.
그러나 실행 가능한 jar 파일을 직접 또는 명령 줄을 통해 실행할 때 위의 방법에서 얻은 jar 파일의 경로가 jar 파일의 내부 경로를 제공하므로 항상 경로를 제공하므로 까다로워집니다. 같이
rsrc : project-name (아마도 메인 클래스 파일의 패키지 이름-표시된 클래스라고 말해야 할 수도 있습니다)
rsrc : ... 경로를 외부 경로로 변환 할 수 없습니다. 즉, Eclipse IDE 외부에서 jar 파일을 실행할 때 jar 파일의 경로를 가져올 수 없습니다.
Eclipse IDE 외부에서 jar 파일을 실행하는 경로를 얻는 유일한 방법은
System.getProperty("java.class.path")
이 코드 라인은 java 문서와 일부 사람들이 모든 클래스 파일의 경로를 반환한다고 말한 것처럼 실행중인 jar 파일 (리턴 경로는 작업 디렉토리가 아님)의 살아있는 경로 (파일 이름 포함)를 반환 할 수 있습니다 동일한 디렉토리에 있지만 동일한 디렉토리에 많은 jar 파일이 포함되어있는 경우 내 테스트로 실행중인 jar의 경로 만 반환합니다 (실제로 Eclipse에서 발생한 다중 경로 문제에 대해).
java.class.path
여러 값을 가질 수 있습니다. 이러한 값 중 하나 는 현재 클래스가있는 디렉토리 또는 JAR 파일을 제공하지만 어느 것입니까?
Gnome 데스크탑 환경에서 스크립트를 클릭하여 항아리를 실행하면 위의 선택된 답변이 작동하지 않습니다 (스크립트 또는 터미널이 아닌).
대신 다음 솔루션이 모든 곳에서 작동한다는 것을 좋아합니다.
try {
return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
URLDecoder
특수 문자를 해독하는 데 사용하지 않는 것이 좋습니다 . 특히, 같은 문자 +
는 공백으로 잘못 디코딩됩니다. 자세한 내용은 내 답변을 참조하십시오.
NullPointerException
NPE
어떤 자원이 JAR에 존재하지 않는 경우.
실제로 여기에 더 나은 버전이 있습니다. 폴더 이름에 공백이 있으면 이전 버전은 실패했습니다.
private String getJarFolder() {
// get name and path
String name = getClass().getName().replace('.', '/');
name = getClass().getResource("/" + name + ".class").toString();
// remove junk
name = name.substring(0, name.indexOf(".jar"));
name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');
// remove escape characters
String s = "";
for (int k=0; k<name.length(); k++) {
s += name.charAt(k);
if (name.charAt(k) == ' ') k += 2;
}
// replace '/' with system separator char
return s.replace('/', File.separatorChar);
}
애플릿에 실패하면 일반적으로 로컬 파일에 액세스 할 수 없습니다. JWS에 대해 잘 모르지만 로컬 파일을 처리하기 위해 앱을 다운로드하지 못할 수 있습니다.?
항아리를 사용하여 경로를 얻으려고했습니다.
String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();
c : \ app> java -jar application.jar
" c : \ app " 폴더의 Windows에서 "application.jar"라는 jar 응용 프로그램을 실행하면 문자열 변수 "folder"의 값이 " \ c : \ app \ application.jar "이고 테스트에 문제가있었습니다. 경로의 정확성
File test = new File(folder);
if(file.isDirectory() && file.canRead()) { //always false }
그래서 나는 "test"를 다음과 같이 정의하려고 시도했다.
String fold= new File(folder).getParentFile().getPath()
File test = new File(fold);
" \ c : \ app \ application.jar " 대신 " c : \ app " 와 같은 올바른 형식의 경로를 얻으려면 작동한다는 것을 알았습니다.
String path = getClass().getResource("").getPath();
경로는 항상 jar 파일 내의 리소스를 나타냅니다.
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
와 getResource(".")
내 시험에서 실패 클래스가 JAR 파일 내에 거주하는 경우; 두 호출 모두 null을 반환했습니다.
NullPointerException
.
public static String dir() throws URISyntaxException
{
URI path=Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
String name= Main.class.getPackage().getName()+".jar";
String path2 = path.getRawPath();
path2=path2.substring(1);
if (path2.contains(".jar"))
{
path2=path2.replace(name, "");
}
return path2;}
Windows에서 잘 작동
실망스러운 것은 Eclipse에서 개발할 때 훌륭한 디렉토리를 MyClass.class.getProtectionDomain().getCodeSource().getLocation()
반환 /bin
하지만 jar로 컴파일 할 때 경로에 /myjarname.jar
잘못된 파일 이름을 제공 하는 부분이 포함된다는 것 입니다.
코드가 IDE에서 작동하고 항아리로 컴파일되면 다음 코드 조각을 사용합니다.
URL applicationRootPathURL = getClass().getProtectionDomain().getCodeSource().getLocation();
File applicationRootPath = new File(applicationRootPathURL.getPath());
File myFile;
if(applicationRootPath.isDirectory()){
myFile = new File(applicationRootPath, "filename");
}
else{
myFile = new File(applicationRootPath.getParentFile(), "filename");
}
다른 것에 대해서는 확실하지 않지만 제 경우에는 "Runnable jar"와 함께 작동하지 않았으며 phchen2 답변 과이 링크에서 다른 코드를 함께 수정하여 작동하게했습니다 . 실행중인 JAR 파일의 경로를 얻는 방법? 코드:
String path=new java.io.File(Server.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.getPath())
.getAbsolutePath();
path=path.substring(0, path.lastIndexOf("."));
path=path+System.getProperty("java.class.path");
몇 가지 솔루션을 시도했지만 실행 가능한 jar이 Eclipse의 "외부 라이브러리 패키징"으로 익스포트 된 (아마도 특별한) 경우에 대한 올바른 결과를 얻지 못했습니다. 어떤 이유로 ProtectionDomain을 기반으로하는 모든 솔루션은이 경우 null이됩니다.
위의 일부 솔루션을 결합하여 다음 작업 코드를 달성했습니다.
String surroundingJar = null;
// gets the path to the jar file if it exists; or the "bin" directory if calling from Eclipse
String jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()).getAbsolutePath();
// gets the "bin" directory if calling from eclipse or the name of the .jar file alone (without its path)
String jarFileFromSys = System.getProperty("java.class.path").split(";")[0];
// If both are equal that means it is running from an IDE like Eclipse
if (jarFileFromSys.equals(jarDir))
{
System.out.println("RUNNING FROM IDE!");
// The path to the jar is the "bin" directory in that case because there is no actual .jar file.
surroundingJar = jarDir;
}
else
{
// Combining the path and the name of the .jar file to achieve the final result
surroundingJar = jarDir + jarFileFromSys.substring(1);
}
System.out.println("JAR File: " + surroundingJar);
아카이브의 코드에서 호출 된이 메소드는 .jar 파일이있는 폴더를 리턴합니다. Windows 또는 Unix에서 작동해야합니다.
private String getJarFolder() {
String name = this.getClass().getName().replace('.', '/');
String s = this.getClass().getResource("/" + name + ".class").toString();
s = s.replace('/', File.separatorChar);
s = s.substring(0, s.indexOf(".jar")+4);
s = s.substring(s.lastIndexOf(':')-1);
return s.substring(0, s.lastIndexOf(File.separatorChar)+1);
}
코드에서 파생 : JAR에서 실행 중인지 확인
그것이 체크인 Windows
되었지만 다른 운영 체제에서 완벽하게 작동한다고 생각합니다 Linux,MacOs,Solaris
.
같은 디렉토리에 2 개의 .jar
파일 이있었습니다 . 한 .jar
파일 .jar
에서 같은 디렉토리에있는 다른 파일 을 시작하고 싶었습니다 .
문제는 cmd
현재 디렉토리 에서 시작할 때 입니다 system32
.
경고!
;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
또는()%&$%^@#
그것을 잘 작동합니다.ProcessBuilder
다음과 같이 아래를 사용하고 있습니다.🍂 ..
//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath= new File(path + "application.jar").getAbsolutePath();
System.out.println("Directory Path is : "+applicationPath);
//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()`
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();
//...code
🍂 getBasePathForClass(Class<?> classs)
:
/**
* Returns the absolute path of the current directory in which the given
* class
* file is.
*
* @param classs
* @return The absolute path of the current directory in which the class
* file is.
* @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
*/
public static final String getBasePathForClass(Class<?> classs) {
// Local variables
File file;
String basePath = "";
boolean failed = false;
// Let's give a first try
try {
file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
basePath = file.getParent();
} else {
basePath = file.getPath();
}
} catch (URISyntaxException ex) {
failed = true;
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (1): ", ex);
}
// The above failed?
if (failed) {
try {
file = new File(classs.getClassLoader().getResource("").toURI().getPath());
basePath = file.getAbsolutePath();
// the below is for testing purposes...
// starts with File.separator?
// String l = local.replaceFirst("[" + File.separator +
// "/\\\\]", "")
} catch (URISyntaxException ex) {
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (2): ", ex);
}
}
// fix to run inside eclipse
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
basePath = basePath.substring(0, basePath.length() - 4);
}
// fix to run inside netbeans
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
basePath = basePath.substring(0, basePath.length() - 14);
}
// end fix
if (!basePath.endsWith(File.separator)) {
basePath = basePath + File.separator;
}
return basePath;
}
이 코드는 저에게 효과적이었습니다.
private static String getJarPath() throws IOException, URISyntaxException {
File f = new File(LicensingApp.class.getProtectionDomain().().getLocation().toURI());
String jarPath = f.getCanonicalPath().toString();
String jarDir = jarPath.substring( 0, jarPath.lastIndexOf( File.separator ));
return jarDir;
}
이 코드는 프로그램이 JAR 파일 또는 IDE 내에서 실행되고 있는지 식별하는 데 도움이되었습니다.
private static boolean isRunningOverJar() {
try {
String pathJar = Application.class.getResource(Application.class.getSimpleName() + ".class").getFile();
if (pathJar.toLowerCase().contains(".jar")) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
JAR 파일의 Windows 전체 경로를 가져와야하는 경우이 방법을 사용하고 있습니다.
private static String getPathJar() {
try {
final URI jarUriPath =
Application.class.getResource(Application.class.getSimpleName() + ".class").toURI();
String jarStringPath = jarUriPath.toString().replace("jar:", "");
String jarCleanPath = Paths.get(new URI(jarStringPath)).toString();
if (jarCleanPath.toLowerCase().contains(".jar")) {
return jarCleanPath.substring(0, jarCleanPath.lastIndexOf(".jar") + 4);
} else {
return null;
}
} catch (Exception e) {
log.error("Error getting JAR path.", e);
return null;
}
}
CommandLineRunner
구현을 사용하여 Spring Boot 응용 프로그램으로 작업하는 완전한 코드 는 응용 프로그램이 항상 콘솔보기 (JAR 파일 이름에서 실수로 두 번 클릭) 내에서 실행되도록하기 위해 다음 코드를 사용하고 있습니다.
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) throws IOException {
Console console = System.console();
if (console == null && !GraphicsEnvironment.isHeadless() && isRunningOverJar()) {
Runtime.getRuntime().exec(new String[]{"cmd", "/c", "start", "cmd", "/k",
"java -jar \"" + getPathJar() + "\""});
} else {
SpringApplication.run(Application.class, args);
}
}
@Override
public void run(String... args) {
/*
Additional code here...
*/
}
private static boolean isRunningOverJar() {
try {
String pathJar = Application.class.getResource(Application.class.getSimpleName() + ".class").getFile();
if (pathJar.toLowerCase().contains(".jar")) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
private static String getPathJar() {
try {
final URI jarUriPath =
Application.class.getResource(Application.class.getSimpleName() + ".class").toURI();
String jarStringPath = jarUriPath.toString().replace("jar:", "");
String jarCleanPath = Paths.get(new URI(jarStringPath)).toString();
if (jarCleanPath.toLowerCase().contains(".jar")) {
return jarCleanPath.substring(0, jarCleanPath.lastIndexOf(".jar") + 4);
} else {
return null;
}
} catch (Exception e) {
return null;
}
}
}
Java 7로 작성하고 Oracle 런타임으로 Windows 7을 테스트하고 오픈 소스 런타임으로 Ubuntu를 테스트하십시오. 이것은 해당 시스템에 완벽하게 작동합니다.
실행중인 jar 파일의 부모 디렉토리 경로 (이 코드를 호출하는 클래스가 jar 아카이브 자체의 직접적인 자식이라고 가정) :
try {
fooDir = new File(this.getClass().getClassLoader().getResource("").toURI());
} catch (URISyntaxException e) {
//may be sloppy, but don't really need anything here
}
fooDirPath = fooDir.toString(); // converts abstract (absolute) path to a String
따라서 foo.jar의 경로는 다음과 같습니다.
fooPath = fooDirPath + File.separator + "foo.jar";
다시 말하지만 이것은 Mac 또는 이전 Windows에서 테스트되지 않았습니다.
이 getProtectionDomain
접근 방식은 때때로 일부 핵심 Java 클래스 (예 : StringBuilder
IBM JDK 내의 클래스)에 대한 jar을 찾아야 할 때 작동하지 않을 수 있지만 다음과 같이 원활하게 작동합니다.
public static void main(String[] args) {
System.out.println(findSource(MyClass.class));
// OR
System.out.println(findSource(String.class));
}
public static String findSource(Class<?> clazz) {
String resourceToSearch = '/' + clazz.getName().replace(".", "/") + ".class";
java.net.URL location = clazz.getResource(resourceToSearch);
String sourcePath = location.getPath();
// Optional, Remove junk
return sourcePath.replace("file:", "").replace("!" + resourceToSearch, "");
}