Jar-File soll eignen *.jar Namen ausgeben

  • Themenstarter Themenstarter GuestOnly
  • Beginndatum Beginndatum
G

GuestOnly

Gast
Hallo

Ich habe eine *.jar Datei welche ihren eigenen Namen kennen soll.
Also wenn die Datei zB "Projekt.jar" heisst soll das Programm in der Lage sein diesen auszugeben auch wenn man die Datei umbenent.
Der Pfad wo sich die *.jar Datei befindet ist dabei egal es geht ausschliesslich um den Namen.
Der Name sollte als String o.ae. im Programm zur Verfuegung stehen (und dann ggf. ausgegebn werde). Wie lautet diese Befehlszeile?
Suchen im Forum oder ueber andere Seiten ergaben nicht die Egebnisse nach denen ich gesucht habe....

Gruss
 
Ist ein bischen von hinten durch die Brust ins Auge. Aber wenn du in dem fraglichen Jar-File eine Dir bekannte Resource hast, kannst Du dir mit getResource("/package/Resource") die URL zu dieser Resource holen. Diese enthält u.a. auch den Namen des jar-Files. Hier mal ein Codeschnipsel, der rausprintet, in welchem jar sich java.io.File befindet:
Java:
public final class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Throwable {

		// Aufruf muss passen, sonst NullpointerException!
		final String jarUrlString = Main.class.getResource(
				"/java/io/File.class").toString();

		System.out.println(jarUrlString);

		// hier noch ein bischen Fummelkram, um den Teil mit dem ".jar"
		// aus dem String rauszupulen.
	}
}
 
Zuletzt bearbeitet von einem Moderator:
Vielen Dank fuer die schnelle Antwort!

Allerdings gibt mir das Programm mit dem Namen "Test.jar" (mit der zu testenden Methode)
folgendes aus:

jar:file:/C:/Program%20Files%20(x86)/Java/jre6/lib/rt.jar!/java/io/File.class

--> keinen Hinweis auf den .jar Namen.

Ich hatte es bereits ueber main.class.getResource("main.class") versucht.
Dort musste ich auch umstaendlich den .jar Namen auslesen was allerdings ausschlieslich auf meinem Computer funktionierte (bei einem weiteren win7 und einem xp probiert).
Gib es da keine anderen Moeglichkeiten??

Gruss
 
Hatte einen Parameter vergessen...
Nun tut er es genau wie meine vorher benutzte Methode. Wird sie auf anderen Computern (anderes OS) aber auch zuverlaessig funktionieren? Werde es zeitnah ausprobieren....
Gibt es keine eleganteren Moeglichkeiten?
 
GuestOnly hat gesagt.:
Allerdings gibt mir das Programm mit dem Namen "Test.jar" (mit der zu testenden Methode)
folgendes aus:

jar:file:/C:/Program%20Files%20(x86)/Java/jre6/lib/rt.jar!/java/io/File.class

--> keinen Hinweis auf den .jar Namen.
Schau mal genau hin. Habe es fett gemacht:
jar:file:/C:/Program%20Files%20(x86)/Java/jre6/lib/rt.jar!/java/io/File.class
Das Ausrufezeichen ist ein guter Ankerpunkt für's Rauspulen.

Und Du musst auch meine Tipps genauer lesen. Du musst natürlich eine Resource aus dem jar nehmen, dessen Namen du wissen willst. Das mit File.class war ein Beispiel.
 
Ja ich hatte nicht genau gelesen...

mit folgender Methode hab ich es nun realisiert:

Java:
static void name()
    {   
      
        
  final String n=CClient.class.getResource("CClient.class").toString();
          int i=n.length()-19;
            for(;;)
            { 
              
              if(n.substring(i-1,i).equals("/")){break;}
                i--;
                if((i-1)<0){break;}
            }
           System.out.println(n.substring(i,n.length()-19)+".jar");

          
    }

Scheint bisher zu klappen (noch nicht getestet auf anderen PCs) aber ist eig. 1zu1 die Methode die ich vorher nutzte und die bei anderen Computern nicht funktionierte. Ich werde es ausprobieren und berichten.

Danke vorab!

Gruss
 
Klappt das wirklich? Finde die for-Schleife mit leeren Anweisungen etwas merkwürdig und die fixe Länge 19 ist auch eine Fehlerquelle, wenn die Klasse mal umbenannt wird (obwohl die URL dan eh null wäre). Habe mal eine Methode geschrieben, die etwas flexibler ist und vor allem auch vernünftig eventuelle Fehlerzustände mittels geeigneter Exceptions reportet. Die Methode und die Kosntante kannste in eine Klasse Deiner Wahl kopieren.
Java:
private static final String JAR = "jar";
	/**
	 * Finds the file name of a jar a given resource is packaged in.
	 * 
	 * @param resourceUrl
	 *            the jar-URL pointing to the resource in question, must not be
	 *            null and must be a jar-URL (jar:...)
	 * @return the jar file name
	 * @throws NullPointerException
	 *             if resourceUrl is null
	 * @throws IllegalArgumentException
	 *             if resourceUrl is not a jar-URL
	 * @throws IllegalStateException
	 *             if resourceUrl does not contain a jar file name
	 */
	public static String findJarName(final URL resourceUrl) {

		if (!JAR.equals(resourceUrl.getProtocol())) {

			throw new IllegalArgumentException(
					"resourceUrl must be a jar-URL but is: " + resourceUrl);
		}

		final String[] pathParts = resourceUrl.getPath().split("[/!]");

		for (final String pathPart : pathParts) {

			if (pathPart.contains(JAR)) {
				return pathPart;
			}
		}

		throw new IllegalStateException(
				"Resource Url does not contain a jar file name: " + resourceUrl);
	}
}
 
@ nillehammer Sieht eleganter aus und laeuft gut!

@ irgendjemand Dieser Thread ist auch erst von gestern^^

Gibt es Unterschiede zwischen den beiden Wegen? Ist einer vielleicht vielseitiger oder verlaesslicher jenachdem unter welchem OS er ausgefuehrt wird o.ae.

Java:
...
File me = new File(<CLASSNAME>.class.getProtectionDomain().getCodeSource().getLocation().toURI());
...

Gibt es da (Problembezogen) generell einen Unterschied von wo aus die .jar gestartet wird?
Also ueber ein direktes ausfuehren, ueber eine .bat oder .vbs ??
 
ja ... es gibt einen sehr wichtigen unterschied ... du musst dich nicht um decoding der URL kümmern ...

ich versuchs mal so zu erklären

bei der variante über getResource() erhält man eine URL welche auch durch "!" getrennt den "pfad" innerhalb des jar zur resource enthält ...
man kann zwar jetzt aus dieser URL auch eine URI machen ... jedoch über diese URI kein File objekt erzeugen ...
also müsste man aus der URL erst einen String machen ... dann den jar-internen teil abtrennen ... dann wieder aus dem string eine URL parsen ... diese umwandeln zu einer URI und könnte DANN erst ein File objekt erzeugen ...

und das ist einfach viel umständlicher und birgt auch einige enconding-risiken ... als gleich dierekt eine URL auf das JAR zu erhalten ... diese dierekt in eine URI umzuwandeln ... und dann daraus dierekt das File objekt erstellen ...

oder kurz : die andere variante ist kürzer und zuverlässiger

einen unterschied WIE das jar gecallt wird gibt es bei keiner variante ...
jedoch gibt es einen unterschied zwischen "im jar" und "ohne jar" ...
bei der variante über getResource() nämlich sein das es probleme gibt die eigentlich "bekannte" resource zu finden ... weil sie plötzlich doch an einem anderen ort liegt ...
auch muss man grundsätzlich immer auf "!/" prüfen was signalisiert ob es ein JAR ist oder nicht ... alles in allem ein haufen "fummelei" ...
bei dem einzeiler reicht ein folgendes [c]if(me.isFile()) { me=me.getParentFile(); }[/c] um dann auf den ordner zu kommen in dem das jar liegt *falls notwendig*
also alles in allem einen "zwei-zeiler" ...
bei "getResource()" werden es mal locker 4 bis 6 ... und es ist wie gesagt unzuverlässiger als der zwei-zeiler ...


btw : ich habe früher auch mal versucht über [c]this.getClass().getResource(this.getClass().getSimpleName()+".class")[/c] und dann fummelei mit URL , String , URI , File versucht den pfad zum aktuellen JAR zu bekommen ... und was meinst du wie sehr ich dabei gerade unter windows auf die schnauze gefallen bin ...
ich hab dann hier auch mal irgendwann diesen zwei-zeiler gelesen ... und er hat bis her IMMER funktioniert ... ergo : hat sich bewährt und wurde für "perfekt" befunden =D
 

Zurück
Oben