Kodum foo.jar diyelim bir JAR dosyası içinde çalışır ve kodda, hangi foo.jar çalışan klasöründe bilmeliyim .
Yani, foo.jar içeriyorsa , C:\FOO\
şu anki çalışma dizinim ne olursa olsun bu yolu almak istiyorum.
Kodum foo.jar diyelim bir JAR dosyası içinde çalışır ve kodda, hangi foo.jar çalışan klasöründe bilmeliyim .
Yani, foo.jar içeriyorsa , C:\FOO\
şu anki çalışma dizinim ne olursa olsun bu yolu almak istiyorum.
Yanıtlar:
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getPath();
"Sınıfım" yerine sınıfınızın adını yazın.
Açıkçası, sınıfınız dosya olmayan bir konumdan yüklendiyse bu garip şeyler yapacaktır.
toURI()
Adım boşluklar ve artılar dahil özel karakterler içeren önlemek sorunlarına hayati önem taşımaktadır. Doğru tek astar: return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
Kullanmak URLDecoder
birçok özel karakter için çalışmaz. Daha fazla ayrıntı için aşağıdaki cevabıma bakın.
getProtectionDomain
bir stracktrace dan sınıf alıyorsanız null:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
Benim için en iyi çözüm:
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
Bu, boşluk ve özel karakterlerle sorunu çözmelidir.
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
, Linux'ta @Iviggiani's (( ) ile birlikte mükemmel bir çözüm gibi görünüyor . Ancak, Windows üzerinde denemedim.
URLDecoder
özel karakterlerin kodunu çözmek için kullanılması önerilmez . Özellikle, gibi karakterlerin +
boşluklara yanlışlıkla kodu çözülecektir. Ayrıntılar için cevabıma bakın.
Belirli bir için elde etmek File
için Class
iki adım vardır:
Class
a kadarURL
URL
a kadarFile
Her iki adımı da anlamak ve onları karıştırmamak önemlidir.
Bir kez sahip olduktan sonra File
, getParentFile
ihtiyacınız olan şey varsa, içeren klasörü almak için arayabilirsiniz .
Class
-URL
Diğer cevaplarda tartışıldığı gibi, a ile URL
ilgili bulmanın iki ana yolu vardır Class
.
URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
Her ikisinin de artıları ve eksileri var.
getProtectionDomain
Yaklaşım sınıfı (örneğin, içeren JAR dosyası) taban bölgesi elde edilir. Bununla birlikte, Java çalışma zamanının güvenlik ilkesinin SecurityException
arama sırasında ortaya çıkması mümkündür getProtectionDomain()
, bu nedenle uygulamanızın çeşitli ortamlarda çalışması gerekiyorsa, hepsini test etmek en iyisidir.
getResource
Yaklaşım ek dize kullanımı uygulamanız gerekir hangi sınıfa ait tam URL kaynak yolunu verir. Bir file:
yol olabilir , ancak bir OSGi çerçevesi içinde yürütülürken olduğu jar:file:
gibi hatta daha nahoş bir şey de olabilir bundleresource://346.fwk2106232034:4/foo/Bar.class
. Tersine, getProtectionDomain
yaklaşım file:
OSGi içinden bile doğru bir URL verir .
Hem o Not getResource("")
ve getResource(".")
sınıf bir JAR dosyası içinde ikamet, benim testlerde başarısız; her iki çağrı da boş döndü. Bu yüzden yukarıda gösterilen # 2 çağrısını daha güvenli göründüğünden tavsiye ederim.
URL
-File
Her iki durumda da, a'ya sahip olduğunuzda, bir URL
sonraki adım a'ya dönüştürülür File
. Bu kendi zorluğudur; bkz konuda Kohsuke Kawaguchi adlı blog yazısı tüm detaylar için, ama kısacası kullanabilirsiniz new File(url.toURI())
sürece URL tamamen iyi biçimli olarak.
Son olarak, kullanmayı şiddetle tavsiye ederim URLDecoder
. URL Bazı karakterler :
ve /
özellikle de geçerli URL olarak kodlanmış karakterleri kullanılamaz. Gönderen URLDecoder Javadoc:
Kodlanan dizedeki tüm karakterlerin aşağıdakilerden biri olduğu varsayılır: "a" - "z", "A" - "Z", "0" - "9" ve "-", "_", " .", ve "*". "%" Karakterine izin verilir, ancak özel bir çıkış dizisinin başlangıcı olarak yorumlanır.
...
Bu kod çözücünün yasadışı dizelerle başa çıkmasının iki olası yolu vardır. Yasadışı karakterleri yalnız bırakabilir veya bir IllegalArgumentException kurabilir. Kod çözücünün hangi yaklaşımı uyguladığı uygulamaya bırakılır.
Uygulamada, URLDecoder
genellikle IllegalArgumentException
yukarıda tehdit edildiği gibi atmaz . Dosya yolunuz olarak kodlanmış boşluklar varsa %20
, bu yaklaşım işe yarayabilir. Ancak, dosya yolunuzda başka alfa olmayan karakterler varsa, dosya yolunuzu yönetmeyle +
ilgili sorunlarınız olacaktır URLDecoder
.
Bu adımları gerçekleştirmek için aşağıdakine benzer yöntemleriniz olabilir:
/**
* 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);
}
Aşağıdaki yöntemleri SciJava Common kütüphanesinde bulabilirsiniz:
Ayrıca kullanabilirsiniz:
CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
Geçerli sınıfınızın URL'sini bulmak için ClassLoader.getResource () öğesini kullanın.
Örneğin:
package foo;
public class Test
{
public static void main(String[] args)
{
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("foo/Test.class"));
}
}
(Bu örnek benzer bir sorudan alınmıştır .)
Dizini bulmak için URL'yi manuel olarak ayırmanız gerekir. Bir kavanoz URL'sinin biçimi için JarClassLoader öğreticisine bakın .
NPE
çünkü sorulan soruya cevap vermediniz (JAR dir yolu yolu soruldu ve kesinlikle farklı bir soruya cevap verdiniz: sınıf yolu). 2. Başkaları tarafından işaret edildiği gibi, ben de aynı sorunu var, appletler için işe yaramaz. 3. İade yolu hiç kanonik yol temsilinin değil: jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class
.
Son zamanlarda hiçbirinin kullanılmasını önermediğini görünce şaşırdım Path
. ": Burada atıf aşağıdaki bir yolunun diğer formları, ya da özü kısımlarına yolu dönüştürmek sınıfı çeşitli yolu hakkında bilgi elde etmek için kullanılabilecek yöntem, yolun erişim elemanları içerir "Path
Bu nedenle, iyi bir alternatif, Path
nesneyi şu şekilde elde etmektir :
Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
Linux, Mac ve Windows'ta benim için çalışan tek çözüm:
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();
}
Aynı sorunu yaşadım ve bu şekilde çözdüm:
File currentJavaJarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String currentJavaJarFilePath = currentJavaJarFile.getAbsolutePath();
String currentRootDirectoryPath = currentJavaJarFilePath.replace(currentJavaJarFile.getName(), "");
Umarım size yardımcı olmuştum.
İşte bana bazı ayrıntılar için yükseltme gibi görünüyor,
.jar dosyasının dışında göreli bir "klasör" kullanma (kavanozun aynı konumunda):
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
özel karakterlerin kodunu çözmek için kullanılması önerilmez . Özellikle, gibi karakterlerin +
boşluklara yanlışlıkla kodu çözülecektir. Ayrıntılar için cevabıma bakın.
URLDecoder
, ismine rağmen, URL kodunu çözmek ve URL'leri değil, parametre adlarını ve değerlerini oluşturmak içindir.
Jar dosyasını çalıştırma yolunu elde etmek için yukarıdaki çözümleri inceledim ve birbirinden biraz farklı olan tüm yöntemleri denedim. Bu kod Eclipse IDE'de çalışıyorsa, belirtilen sınıf da dahil olmak üzere dosyanın yolunu bulabilmeli ve bulunan yolla belirtilen bir dosyayı açmalı veya oluşturabilmelidir.
Ancak zor, runnable jar dosyasını doğrudan veya komut satırı üzerinden çalıştırdığınızda, yukarıdaki yöntemlerden alınan jar dosyasının yolu jar dosyasında dahili bir yol vereceği için başarısız olacaktır, yani her zaman bir yol verir gibi
rsrc: project-name (belki de ana sınıf dosyasının paket adı olduğunu söylemeliyim - belirtilen sınıf)
Harici bir yola rsrc: ... yolunu dönüştüremiyorum, yani Eclipse IDE dışında jar dosyasını çalıştırdığınızda jar dosyasının yolunu alamıyorum.
Eclipse IDE dışında jar dosyasını çalıştırma yolunu almanın tek yolu
System.getProperty("java.class.path")
bu kod satırı, java belgesi olarak ve bazı insanlar tüm sınıf dosyalarının yollarını döndüreceğini söylediğinde, çalışan jar dosyasının yaşam yolunu (dosya adı dahil) (dönüş yolunun çalışma dizini olmadığını unutmayın) döndürebilir. aynı dizinde, ancak aynı dizinde birçok jar dosyası içeriyorsa testlerim olarak, sadece jar çalıştıran yolu döndürür (aslında Eclipse'de gerçekleşen birden fazla yol sorunu hakkında).
java.class.path
çok değerli olabilir. Bu değerlerden biri kesinlikle geçerli sınıfın bulunduğu dizini veya JAR dosyasını sağlayacaktır, ancak hangisi?
Diğer yanıtlar, dizin olmayan Jar dosyası konumu olan kod kaynağına işaret ediyor gibi görünüyor.
kullanım
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
kavanozunuzu Gnome masaüstü ortamından (herhangi bir komut dosyasından veya terminalden değil) tıklatarak çalıştırırsanız yukarıdaki seçilen cevap çalışmaz.
Bunun yerine, aşağıdaki çözümün her yerde çalıştığını sevdim:
try {
return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
URLDecoder
özel karakterlerin kodunu çözmek için kullanılması önerilmez . Özellikle, gibi karakterlerin +
boşluklara yanlışlıkla kodu çözülecektir. Ayrıntılar için cevabıma bakın.
NullPointerException
NPE
JAR'da kaynak yoksa sahip olacaksınız .
Aslında burada daha iyi bir sürüm var - eski bir klasör adında boşluk varsa başarısız oldu.
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);
}
Küçük uygulamalarda başarısızlığa gelince, genellikle yerel dosyalara erişemezsiniz. JWS hakkında çok şey bilmiyorum ama yerel dosyaları işlemek için uygulamayı indirmek mümkün olmayabilir.
Kavanozu kullanarak koşu yolunu almaya çalıştım
String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();
c: \ app> java -jar application.jar
"Application.jar" adlı jar uygulamasını çalıştırarak, Windows'ta " c: \ app " klasöründeki "String" klasörü değişkeninin değeri " \ c: \ app \ application.jar " idi ve sınamada sorunlar yaşadım yolun doğruluğu
File test = new File(folder);
if(file.isDirectory() && file.canRead()) { //always false }
Bu yüzden "test" i şöyle tanımlamaya çalıştım:
String fold= new File(folder).getParentFile().getPath()
File test = new File(fold);
yolu " \ c: \ app \ application.jar " yerine " c: \ app " gibi doğru bir biçimde almak ve ben bunun işe yaradığını fark ettim.
En basit çözüm, kavanozu çalıştırırken yolu bir argüman olarak geçirmektir.
Bunu bir kabuk komut dosyasıyla otomatikleştirebilirsiniz (Windows'ta .bat, başka bir yerde .sh):
java -jar my-jar.jar .
.
Geçerli çalışma dizinini geçirdim .
GÜNCELLEME
Jar dosyasını bir alt dizine yapıştırmak isteyebilirsiniz, böylece kullanıcılar yanlışlıkla tıklamaz. Kodunuz ayrıca komut satırı bağımsız değişkenlerinin sağlandığından emin olmalı ve bağımsız değişkenler eksikse iyi bir hata iletisi vermelidir.
Sonunda çalışan (ve kısa) bir çözüm bulamadan önce çok uğraşmak zorunda kaldım. Kullanarak çıkarılabilen veya gibi bir önekle
gelmesi mümkündür .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();
Yol her zaman jar dosyası içindeki kaynağa başvurur.
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
ve getResource(".")
benim testlerde başarısız, sınıf bir JAR dosyası içinde ikamet zaman; her iki çağrı da boş döndü.
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'da iyi çalışır
Sinir bozucu bir şey, Eclipse geliştirdiğinizde harika MyClass.class.getProtectionDomain().getCodeSource().getLocation()
olan /bin
dizini döndürür , ancak bir kavanoza derlediğinizde, yolun /myjarname.jar
size yasadışı dosya adları veren bölümü içermesidir.
Kodun hem ide'de çalışması için hem de bir kavanoza derlendiğinde, aşağıdaki kod parçasını kullanıyorum:
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");
}
Gerçekten diğerleri hakkında emin değilim ama benim durumumda bir "Runnable kavanoz" ile işe yaramadı ve ben phchen2 cevap ve bu bağlantıdan başka bir kod birlikte sabitleyerek çalışma var: Nasıl çalışan bir JAR dosyasının yolunu almak için? Kod:
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");
Orada birkaç çözüm denedim ama hiçbiri çalıştırılabilir kavanoz Eclipse "Ambalaj dış kütüphaneler" ile ihraç (muhtemelen özel) durumda doğru sonuçlar vermedi. Bazı nedenlerden dolayı, ProtectionDomain tabanlı tüm çözümler bu durumda null sonucunu verir.
Yukarıdaki bazı çözümleri birleştirerek aşağıdaki çalışma kodunu elde etmeyi başardım:
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);
Arşivdeki koddan çağrılan bu yöntem, .jar dosyasının bulunduğu klasörü döndürür. Windows veya Unix'te çalışmalıdır.
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);
}
Şu koddan türetildi: JAR'dan çalıştırılıp çalıştırılmadığını belirleyin
Sadece kontrol edilir Windows
ama diğer İşletim Sistemleri [ Linux,MacOs,Solaris
] :) mükemmel çalıştığını düşünüyorum .
Aynı dizinde 2 .jar
dosyam vardı . Bir .jar
dosyadan .jar
aynı dizindeki diğer dosyayı başlatmak istedim .
Sorun, cmd
geçerli dizinden başlattığınızda olmasıdır system32
.
Uyarılar!
;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
veya ()%&$%^@#
iyi çalışıyor.ProcessBuilder
Aşağıdaki gibi aşağıdaki ile kullanıyorum :🍂 ..
//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;
}
Bu kod benim için çalıştı:
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;
}
Bu kod, programın bir JAR dosyası veya IDE içinde yürütülüp yürütülmediğini tanımlamak için benim için çalıştı:
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 dosyasının Windows tam yolunu almam gerekirse, bu yöntemi kullanıyorum:
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
Uygulamanın her zaman bir konsol görünümü (JAR dosya adında yanlışlıkla çift tıklama) içinde yürütülmesini sağlamak için uygulama kullanarak bir Spring Boot uygulaması ile çalışan benim tam kod, bir sonraki kodu kullanıyorum:
@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'de yazıyorum ve Oracle'ın çalışma zamanı ile Windows 7'de ve açık kaynak çalışma zamanı ile Ubuntu'da test yapıyorum. Bu, bu sistemler için mükemmel çalışır:
Herhangi bir çalışan jar dosyasının üst dizininin yolu (bu kodu çağıran sınıfın jar arşivinin kendisinin doğrudan bir alt öğesi olduğu varsayılarak):
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
Yani, foo.jar yolu şöyle olur:
fooPath = fooDirPath + File.separator + "foo.jar";
Yine, bu herhangi bir Mac veya daha eski Windows'da test edilmedi
getProtectionDomain
Eğer çekirdek java sınıfları bazıları için kavanozu bulmak zorunda olduğunda yaklaşım bazen örneğin çalışmayabilir (örn benim durumda StringBuilder
, IBM JDK içinde sınıfından) Ancak aşağıdaki işleri sorunsuz:
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, "");
}
Bir sınıfın String konumunu almak için başka bir yol var.
URL path = Thread.currentThread().getContextClassLoader().getResource("");
Path p = Paths.get(path.toURI());
String location = p.toString();
Çıktı Dizesi şu şekilde olacaktır:
C:\Users\Administrator\new Workspace\...
Boşluklar ve diğer karakterler işlenmez ve biçimsizdir file:/
. Yani kullanımı daha kolay olacak.