2010-09-02 21 views
12

Sorun, her şeyi açıklıyor.Yürütme jar dosyasına göre bir dosya yükleniyor

Benim durumumdaki özellik, şu anki çalışma dizininin jar dosyasının yeri değil, c:\Windows\system32 (Sağ taraf menüsünü kullanarak jar dosyası başlatılıyor, bir klasörün yolunu geçmek istiyorum) jar parametresi).

Şimdi, jar ile aynı klasörde bulunan config.xml adlı bir yapılandırma dosyasını yüklemek istiyorum. Dosyanın amacı, elbette, kavanoz için ayarları sağlamaktır. Xml dosyasının kolay düzenleme için jar dosyasının dışında olması benim için önemlidir.

Bu dosyayı yüklerken zor bir zaman geçiriyorum. , Windows cmd /k ile her şeyi arayan hattın

cmd /k java -jar D:\pathToJarfile\unpacker-0.0.1-SNAPSHOT-jar-with-dependencies.jar 

yürütür Ben küpünün çıkışını görebileceği şekilde pencereler açık komut istemi bırakır. bu işlevler (pencereler afaik yürütür her şey için çalışma klasörü olan) sırasıyla C:\Windows\system32\. ve C:\Windows\system32, dönüş olarak

göreli yolu için new File(".") veya System.getProperty("user.dir") kullanamaz.

Launcher.class.getResourceAsStream("/../config.xml") ile hiç bir başarı elde edemedim. Bu yol / ile başladığından, arama, kavanozun kök düğümünde başlar. ../config.xml için tam olarak bu dosyaya gelin, ancak çağrı null döndürür.

Birisi bana doğru yönde işaret edebilir mi? Gerçekten burada sıkıştım. Bu dosya yükleme şeyler gerçekten hata her me ... başıma

Gereksinimler:

  • java kaynak kodunda yolunu hardcode istemiyorum
  • ben geçmek istemiyorum java -jar çağrısına parametre olarak dosyanın yolu (ne bir main(String[] args) için param ne de bir sistem özelliği ayarlamak için -Dpath=d:\... kullanma gibi)

Orijinal soruna ek olarak, jar-with-dependencies kullanırken Class-Path: .MANIFEST.MF (BalusC'nin gönderdiği çözüm) maven2 yerine sahip olmak zor bir zaman geçirdim. Sorun, hattın normal jar'ın MANIFEST dosyasında göründüğü, ancak jar-with-dependencies.jar'ın MANIFEST dosyasında (2 jar dosyası üretildi) olmamasıydı. herkes için kim bunu nasıl yaptığını umurunda:

final Class<?> referenceClass = YourMainClass.class; 
final URL url = 
    referenceClass.getProtectionDomain().getCodeSource().getLocation(); 

try{ 
    final File jarPath = new File(url.toURI()).getParentFile(); 
    System.out.println(jarPath); // this is the path you want 
} catch(final URISyntaxException e){ 
    // etc. 
} 

YourMainClass senin kavanoza herhangi bir sınıf ile değiştirilebilir:

<plugin> 
    <artifactId>maven-assembly-plugin</artifactId> 
    <version>2.2-beta-5</version> 
    <configuration> 
     <archive> 
     <manifest> 
      <mainClass>${mainClass}</mainClass> 
      <addClasspath>true</addClasspath> 
      <!--at first, i tried to place the Class-Path entry 
       right here using <manifestEntries>. see below --> 
     </manifest> 
     </archive> 
     <descriptorRefs> 
     <descriptorRef>jar-with-dependencies</descriptorRef> 
     </descriptorRefs> 
    </configuration> 
    <executions> 
     <execution> 
     <goals> 
      <goal>attached</goal> 
     </goals> 
     <phase>package</phase> 
     <configuration> 
      <descriptorRefs> 
      <descriptorRef>jar-with-dependencies</descriptorRef> 
      </descriptorRefs> 
      <archive> 
      <manifest> 
       <mainClass>${mainClass}</mainClass> 
      </manifest> 
      <!--this is the correct placement --> 
      <manifestEntries> 
       <Class-Path>.</Class-Path> 
      </manifestEntries> 
      </archive> 
     </configuration> 
     </execution> 
    </executions> 
    </plugin> 

cevap

6

işe Launcher.class.getResourceAsStream("/../config.xml") almak için, JAR en MANIFEST.MF dosyanın Class-Path girişi giden yolunu eklemeniz gerekir. Bu normal bir uygulamadır.

+1

sesler prettier :-) –

+0

Mutlak yolu 'MANIFEST.MF' içine koymam mı yoksa yeterli mi? İkincisi arzu edilir. Denemek yerine üzgünüm, bu makinede IDE'im yok. – f1sh

+1

Hayır, JAR dosyasının kendisine göre olan yol. 'Config.xml' 'in JAR dosyasının kendisiyle aynı klasörde olmasını istiyorsanız,' Class-Path:. 'Yeterli olacaktır ("MANIFEST.MF" nin sonuna boş bir satır eklemeyi unutmayın!) . Sonra 'config.xml'' getResourceAsStream ("config.xml") 'ile elde edebilirsiniz. Basit olsun :) – BalusC

11

İşte Class.getProtectionDomain() kullanılarak olası bir çözümdür.Class.getProtectionDomain() Dokümanlar


:

Returns the ProtectionDomain of this class. 
If there is a security manager installed, this method first calls 
the security manager's checkPermission method with a 
RuntimePermission("getProtectionDomain") permission to ensure it's 
ok to get the ProtectionDomain. 

Returns: 
    the ProtectionDomain of this class 
Throws: 
    SecurityException - if a security manager exists and its 
    checkPermission method doesn't allow getting the ProtectionDomain. 
+1

Koddaki yola ihtiyacım olması durumunda bunu bilmek çok güzel. Şu anda yapmıyorum, bu yüzden BalusC'nin cevabını kullanmaya çalışacağım. – f1sh

İlgili konular