私のコードは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の()と組み合わせると、UTF変換は完璧なソリューションのようです。しかし、私はWindowsで試しませんでした。
URLDecoder
特殊文字のデコードに使用することはお勧めしません。特に、などの文字+
は誤ってスペースにデコードされます。詳細については、私の回答を参照してください。
File
特定ののを取得するには、Class
2つのステップがあります。
Class
をaに変換しますURL
URL
をaに変換しますFile
両方のステップを理解し、それらを混同しないことが重要です。
あなたがしたらFile
、あなたは呼び出すことができますgetParentFile
それはあなたが必要なものであれば、入っているフォルダを取得します。
Class
にURL
他の回答で説明されているように、にURL
関連するものを見つけるには2つの主要な方法がありますClass
。
URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
どちらにも長所と短所があります。
このgetProtectionDomain
アプローチにより、クラス(たとえば、含まれるJARファイル)の基本的な場所がわかります。ただし、JavaランタイムのセキュリティポリシーがをSecurityException
呼び出すとスローされる可能性があるgetProtectionDomain()
ため、アプリケーションをさまざまな環境で実行する必要がある場合は、すべての環境でテストすることをお勧めします。
このgetResource
アプローチにより、クラスの完全なURLリソースパスが生成されます。そこから追加の文字列操作を実行する必要があります。それはfile:
パスかもしれませんが、OSGiフレームワーク内で実行するときのjar:file:
ようにbundleresource://346.fwk2106232034:4/foo/Bar.class
、あるいはもっとひどいものになるかもしれません。逆に、このgetProtectionDomain
アプローチはfile:
OSGi内からでもURLを正しく生成します。
クラスがJARファイル内にある場合、テストで失敗したことgetResource("")
とgetResource(".")
失敗したことに注意してください。どちらの呼び出しもnullを返しました。したがって、安全だと思われるため、代わりに上記の#2呼び出しをお勧めします。
URL
にFile
どちらの方法でも、を取得したらURL
、次のステップはへの変換File
です。これはそれ自体が課題です。詳細については、河口浩介氏のブログ投稿を参照してください。つまり、new File(url.toURI())
URLが完全に整形式である限り使用できます。
最後に、を使用しないことを強くお勧めしURLDecoder
ます。いくつかのURLの文字、:
そして/
特に、有効なURLエンコードされた文字ではありません。URLDecoder Javadoc から:
エンコードされた文字列のすべての文字は、「a」から「z」、「A」から「Z」、「0」から「9」、および「-」、「_」、「 。 "、および" * "。文字「%」は使用できますが、特別なエスケープシーケンスの開始として解釈されます。
...
このデコーダが不正な文字列を処理する方法は2つあります。不正な文字をそのままにしておくか、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共通ライブラリにあります。
次のものも使用できます。
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 dirへのパスが尋ねられ、まったく異なる質問に答えました:クラスへのパス)。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")
このコード行は、実行中のjarファイルの生きているパス(ファイル名を含む)を返す可能性があります(戻りパスは作業ディレクトリではないことに注意してください)。Javaドキュメントと一部の人々は、すべてのクラスファイルのパスを返すと述べています同じディレクトリにありますが、同じディレクトリに多くのjarファイルが含まれている場合のテストでは、実行中のjarのパスのみが返されます(実際にEclipseで発生した複数パスの問題について)。
java.class.path
複数の値を持つことができます。これらの値の1つは、確かに現在のクラスが配置されているディレクトリまたはJARファイルを提供しますが、どれを指定しますか?
上記の選択した回答は、Gnomeデスクトップ環境(スクリプトや端末からではなく)からクリックしてjarを実行する場合は機能しません。
代わりに、私は次の解決策がどこでも機能しているのが好きです:
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についてはよく知りませんが、ローカルファイルを処理するためにアプリをダウンロードできない場合があります。
を使用してjar実行パスを取得しようとしました
String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();
c:\ app> java -jar application.jar
「application.jar」という名前のjarアプリケーションをWindowsの「c:\ app」フォルダーで実行すると、文字列変数「folder」の値は「\ c:\ app \ application.jar」で、テストに問題がありました。パスの正確さ
File test = new File(folder);
if(file.isDirectory() && file.canRead()) { //always false }
だから私は「テスト」を次のように定義しようとしました:
String fold= new File(folder).getParentFile().getPath()
File test = new File(fold);
「のような正しい形式でパスを取得するには「\ c:\ app \ application.jar」ではなく c:\ app」の。
私は最終的に実用的な(そして短い)解決策を見つける前に、多くのことをいじらなければなりませんでした。
またはのjarLocation
ような接頭辞がに付属し
ている可能性があります。これはを使用して削除できます。file:\
jar:file\
String#substring()
URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
String path = getClass().getResource("").getPath();
パスは常にjarファイル内のリソースを参照します。
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
と両方でgetResource(".")
失敗しました。どちらの呼び出しも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とjarにコンパイルした後の両方で機能させるには、次のコードを使用します。
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");
}
他の人についてはよくわかりませんが、私の場合、「実行可能な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
、同じディレクトリ内のファイルを。1つの.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;
}
}
WindowsのJARファイルの完全パスを取得する必要がある場合、次の方法を使用しています。
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, "");
}
クラスの文字列の場所を取得する別の方法があります。
URL path = Thread.currentThread().getContextClassLoader().getResource("");
Path p = Paths.get(path.toURI());
String location = p.toString();
出力文字列は次の形式になります
C:\Users\Administrator\new Workspace\...
スペースやその他の文字は、なしの形式で処理されfile:/
ます。だから使いやすくなります。