Pegar o path da classe ou do JAR

Eu gostaria de pegar o caminho da minha classe principal ou do JAR.
Eu ja procurei no google e aqui no fórum, mas as soluções que encontrei não me serviram.

Tentei usar:
File path = new File(".");
System.out.println(path.getAbsolutePath());

O problema de usar “.” é que ele vai me trazer o caminho em relação ao diretório que estou no momento de chamar o programa e não o diretório da classe ou do JAR.

Por exemplo:
Se minha classe estiver em “c:\temp\Teste.class” e eu estiver no diretório “c:\fontes\netbeans” e chamar minha classe com o comando “java -cp c:\temp Teste” ele vai me retornar “c:\fontes\netbeans.” e não “c:\temp.” que é o que eu quero.

Alguém tem alguma idéia?
É pra uma aplicação em Swing, não Web.
Obrigado desde já.

Você pode brincar com Class.getResource, que lhe retorna uma URL. Digamos que o nome de sua classe seja “br.com.teste.Teste”, procure pelo resource “/br/com/teste/Teste.class”

[quote=thingol]Você pode brincar com Class.getResource, que lhe retorna uma URL. Digamos que o nome de sua classe seja “br.com.teste.Teste”, procure pelo resource “/br/com/teste/Teste.class”
[/quote]

Dessa maneira não me serve.
Eu queria o caminho real e completo, por exemplo: “C:\Arquivos de programas\minha aplicação”.

Mas mesmo assim obrigado.

Isso me traz o diretório corrente, e não o local onde está classe.

Como será que o eclipse encontra todos os plugins dele, mesmo depois que você move ele para outro lugar?

[quote=klez][quote=thingol]Você pode brincar com Class.getResource, que lhe retorna uma URL. Digamos que o nome de sua classe seja “br.com.teste.Teste”, procure pelo resource “/br/com/teste/Teste.class”
[/quote]

Dessa maneira não me serve.
Eu queria o caminho real e completo, por exemplo: “C:\Arquivos de programas\minha aplicação”.

Mas mesmo assim obrigado.[/quote]

É que a URL fornece o tal path do arquivo, se você for dar uma olhada. Mesmo se a classe estiver dentro de um .jar, ela vai lhe fornecer o nome do .jar com seu path. É questão de você fazer uns testes.

DISCLAIMER - não sei se isso funciona sempre, nem sei se funciona no Linux. Use com critério.

EDIT - Agora pus um “if” que talvez faça este programa funcionar com o Linux/Unix. Alguém se habilita a testá-lo?

import java.net.*;
import java.io.*;

class TestePathDaClasse {
    
    public TestePathDaClasse() {
    }
    /** Retorna uma string indicando em que .jar a classe pôde ser encontrada,
     * ou então o diretório a partir do qual a classe foi encontrada.
     * Por exemplo, para java.lang.String, deve retornar algo como 
     * "C:/Program Files/Java/jre1.5.0_08/lib/rt.jar"
     * e para esta classe, o diretório onde está a classe.
     */
    public String pathDaClasse (Class klass) throws Exception {
        String className = "/" + klass.getName().replace ('.', '/') + ".class";
        URL u = klass.getResource (className);
        String s = u.toString();
        if (s.startsWith ("jar:file:/")) {
            // Deve ser algo como "jar:file:/C:/Program%20Files/Java/jre1.5.0_08/jre/lib/rt.jar!/java/lang/String.class"
            int pos = s.indexOf (".jar!/");
            if (pos != -1) {
                if (File.separator.equals ("\"))
                    s = s.substring ("jar:file:/".length(), pos + ".jar".length());
                else 
                    s = s.substring ("jar:file:".length(), pos + ".jar".length());
                s = s.replaceAll ("%20", " ");
            } else {
                s = "?";
            }
        } else if (s.startsWith ("file:/")) {
            // Algo como "file:/C:/temp2/java/TestePathDaClasse.class"
            if (File.separator.equals ("\"))
                s = s.substring ("file:/".length());
            else
                s = s.substring ("file:".length());
            s = s.substring (0, s.lastIndexOf (className)).replaceAll ("%20", " ");
        } else {
            s = "?";
        }
        return s;
    }

    public static void main(String[] args) throws Exception {
        TestePathDaClasse t = new TestePathDaClasse();
        // Deve mostrar algo como "C:/Program Files/Java/jre1.5.0_08/lib/rt.jar"
        System.out.println (t.pathDaClasse (Class.forName ("java.lang.String")));
        // Deve mostrar algo como "C:/diretoriodaclasse"
        System.out.println (t.pathDaClasse (t.getClass()));
    }
}
    

funciona no linux sim, só fica faltando a barra inicial (root)… sai algo tipo:

opt/jdk1.5.0_06/jre/lib/rt.jar

Que legal! Então dá para fazer uns truques com File.separator, mais ou menos como:

if (File.separator igual a '/') 
  s = s.substring ("jar:file:".length(), pos + ".jar".length());
else
    s = s.substring ("jar:file:/".length(), pos + ".jar".length());

Bah o Class.getResource funciona mesmo, me traz o que eu realmente queria.
Obrigado thingol, não tinha testado pq no primeiro post seu vc me mostrou um exemplo e pensei que ele trouxesse apenas o path do pacote mas não o real.

Obrigado a todos pela ajuda.

Se eu tivesse tido essa idéia antes, não teria feito uma coisa muito feia que fiz em um sistema - eu passo -Ddiretorio.instalacao=<diretorio de instalacao do meu software> como parâmetro para o java.exe, e checo essa variável com System.getProperty. Muito feio…

String local = this.getClass().getResource("src/com/java/.../.../bean/").toString(); System.out.println(local);

retorna NULL
pq?

eu quero que ele gere o arquivo nesse local assim

arquivo = new FileWriter(new File(this.getClass().getResource("com/java/.../.../bean/")+"Teste.txt");

System.getProperty(“user.dir”) ?