Para obter mais informações sobre o Stack Overflow no Stack Overflow : : тение файла возле JAR
Meu código é executado dentro de um arquivo JAR, digamos foo.jar , e eu preciso saber, no código, em qual pasta está o foo.jar em execução .
Portanto, se foo.jar estiver dentro C:\FOO\, eu quero pegar esse caminho, independentemente do meu diretório de trabalho atual.
— Thiago Chaves
Veja a resposta de Fab para uma solução que funciona quando os caminhos incluem espaços. Além disso, observe que algumas respostas abaixo abordam a pergunta no título (caminho do jar), algumas abordam a questão em si (caminho da pasta que contém o jar) e algumas fornecem caminhos para as classes dentro do arquivo jar.
Cuidado ao usar no ANT! ============== Eu chamo String path = SomeClass.class.getProtectionDomain (). GetCodeSource (). GetLocation (). GetPath (); e obtenha: /C:/apache-ant-1.7.1/lib/ant.jar Não é muito útil!
— Dino Fancellu
Interessante. O código original em que eu usei isso nunca foi executado no form, por isso não é um problema para mim.
@ Dino Fancellu, experimentei exatamente o que você descreveu. Funciona durante o desenvolvimento, falha quando criado para jar.
Substitua "MyClass" pelo nome da sua turma.
Obviamente, isso fará coisas estranhas se a sua classe foi carregada de um local que não é do arquivo.
A toURI()etapa é vital para evitar problemas com caracteres especiais, incluindo espaços e vantagens. O alinhamento correto é: O return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI()); uso URLDecodernão funciona para muitos caracteres especiais. Veja minha resposta abaixo para mais detalhes.
Nota: isso retorna o caminho, incluindo o nome do arquivo jar
Isso não aponta para o arquivo jar, em vez do diretório em execução? Você precisará fazer um resultado no getParentFile () para este trabalho.
Além disso, getProtectionDomainé nulo se você está recebendo sua classe a partir de um stracktrace:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
Usando este método com até Java 8; Ao colocar esse método em uma classe que está em um Jar externo, carregado pelo caminho da classe, o caminho do jar externo será fornecido em vez do Jar em execução.
— Mr00Anderson
Melhor solução para mim:
Isso deve resolver o problema com espaços e caracteres especiais.
Mais uma observação: Ao chamar esta função do Jar, o nome do jar é anexado no final para mim, portanto, era necessário executar: path.substring (0, path.lastIndexOf ("/") + 1);
/ não é necessariamente o separador de caminho. Você deve fazer (novo arquivo (caminho)). GetParentFile (). GetPath ().
Nenhum problema com o nome do arquivo JAR sendo anexado aqui. A conversão UTF parece ser a solução perfeita em combinação com a @Iviggiani one ( URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");) no Linux. No entanto, eu não tentei no Windows.
Obrigado, isso me permitiu carregar arquivos externos ao meu JAR com o FileInputStream no Linux e no Windows. Apenas teve que adicionar o decodedpath na frente do nome do arquivo ...
Cuidado: não é recomendável usar URLDecoderpara decodificar caracteres especiais. Em particular, caracteres como +serão erroneamente decodificados para espaços. Veja minha resposta para detalhes.
Para obter Fileum dado Class, há duas etapas:
Converta ClassemURL
Converta URLemFile
É importante entender os dois passos, e não confundi-los.
Depois de ter o File, você pode ligar getParentFilepara obter a pasta que contém, se é isso que precisa.
Etapa 1: ClassparaURL
Conforme discutido em outras respostas, há duas maneiras principais de encontrar um URLrelevante para a Class.
A getProtectionDomainabordagem gera a localização base da classe (por exemplo, o arquivo JAR que contém). No entanto, é possível que a política de segurança do tempo de execução Java seja lançada SecurityExceptionao chamar getProtectionDomain(), portanto, se seu aplicativo precisar executar em uma variedade de ambientes, é melhor testar em todos eles.
A getResourceabordagem gera o caminho completo do recurso de URL da classe, a partir do qual você precisará executar uma manipulação adicional de strings. Pode ser um file:caminho, mas também pode ser jar:file:ou até algo mais desagradável bundleresource://346.fwk2106232034:4/foo/Bar.classao executar dentro de uma estrutura OSGi. Por outro lado, a getProtectionDomainabordagem gera corretamente uma file:URL mesmo dentro do OSGi.
Observe que ambos getResource("")e getResource(".")falharam nos meus testes, quando a classe residia em um arquivo JAR; ambas as invocações retornaram nulas. Por isso, recomendo a invocação nº 2 mostrada acima, pois parece mais segura.
Etapa 2: URLparaFile
De qualquer forma, depois de ter um URL, o próximo passo é converter para a File. Este é o seu próprio desafio; consulte a publicação no blog de Kohsuke Kawaguchi para obter detalhes completos, mas, em suma, você pode usar new File(url.toURI())desde que a URL esteja completamente bem formada.
Por fim, eu desencorajaria o uso URLDecoder. Alguns caracteres da URL :e , /em particular, não são caracteres codificados por URL válidos. No URLDecoder Javadoc:
Supõe-se que todos os caracteres na cadeia codificada sejam um dos seguintes: "a" a "z", "A" a "Z", "0" a "9" e "-", "_", " . "e" * ". O caractere "%" é permitido, mas é interpretado como o início de uma sequência de escape especial.
Existem duas maneiras possíveis pelas quais esse decodificador pode lidar com cadeias ilegais. Ele pode deixar caracteres ilegais em paz ou lançar uma IllegalArgumentException. A abordagem adotada pelo decodificador é deixada para a implementação.
Na prática, URLDecodergeralmente não joga IllegalArgumentExceptioncomo ameaçado acima. E se o caminho do arquivo tiver espaços codificados como %20, essa abordagem pode parecer funcionar. No entanto, se o caminho do arquivo tiver outros caracteres não alfanuméricos, como +você terá problemas ao URLDecodermanipular o caminho do arquivo.
Para realizar essas etapas, você pode ter métodos como o seguinte:
Você pode encontrar esses métodos na biblioteca comum do SciJava :
+1; a melhor resposta até o momento: ele retornará o caminho usando a notação correta para o sistema operacional. (por exemplo, \ para janelas).
Em relação à segurança, acredito que descobri que o Java WebStart não permitia isso.
Isso funciona melhor para mim, porque dá o caminho do Jar, não da classe!
Trabalhou para mim também. Combine com a resposta de Fab e ficará melhor!
Use ClassLoader.getResource () para encontrar o URL da sua classe atual.
(Este exemplo foi retirado de uma pergunta semelhante .)
Para encontrar o diretório, você precisará desmontar o URL manualmente. Consulte o tutorial JarClassLoader para obter o formato de uma URL jar.
Meu arquivo JAR está ofuscado, portanto, esta resposta não resolve o meu problema. Mas eu não especifiquei isso na pergunta, então essa ainda é uma resposta válida.
Se estiver ofuscado, use Test.class.getName () e faça a remoção apropriada.
@JonSkeet, há muitos problemas com sua resposta: 1. Não haverá NPEporque você não respondeu à pergunta que foi feita (o caminho para o diretório JAR foi solicitado e você respondeu com uma pergunta absolutamente diferente: caminho para a aula). 2. Como apontado por outros, e eu tenho o mesmo problema, ele não funciona para applets. 3. caminho retornado não é de representação caminho canônico em tudo: jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class.
— WhiteAngel
@WhiteAngel: 1) A última linha da minha postagem indica que você precisa procurar a URL e separá-la para obter o arquivo jar. Concordo que não é a resposta mais completa, mas não acho que seja tão ruim valer a pena discutir (especialmente 10 anos depois ...) 2) Applets não foram mencionados em nenhum comentário aqui - por incrível que pareça, eu não tenho tempo para analisar todos os comentários em todas as respostas sobre perguntas nas quais postou uma resposta. 3) Novamente, vinculo ao formato da URL do jar.
@WhiteAngel: É a melhor resposta que eu já escrevi? Não. É tão ruim quanto você está fazendo parecer? Não, eu não penso assim. (Particularmente em termos das reivindicações que você fez em torno de lançar um NPE, o que não acontece.) Sugiro que você adicione sua própria resposta em vez de se preocupar com essa. Essa seria uma abordagem mais positiva.
Estou surpreso ao ver que nenhum recentemente propôs usar Path. Segue uma citação: " A Pathclasse inclui vários métodos que podem ser usados ​​para obter informações sobre o caminho, acessar elementos do caminho, converter o caminho para outras formas ou extrair partes de um caminho "
Portanto, uma boa alternativa é obter o Pathobjetivo como:
— mat_boy
Como uma nota, Caminho está disponível partida em Java 7.
A única solução que funciona para mim no Linux, Mac e Windows:
Isso não vai funcionar. Se no Linux, o método toUri () lançará uma exceção e você não alcançará a parte else, para linux.
— Wilhelm Sorban
Não faça isso. URL.getPath () não retorna um nome de arquivo e falhará em várias circunstâncias, como caminhos de arquivo com espaços neles.
— VGR 13/06
Aqui está a atualização para outros comentários, que me parecem incompletos para as especificações de
usando uma "pasta" relativa fora do arquivo .jar (no mesmo local do jar):
O uso de caracteres especiais nos nomes dos arquivos não é recomendado.
URLDecoder, apesar do nome, é para decodificar nomes e valores de URLs e de parâmetros de formulário, não URLs.
Para obter o caminho da execução do arquivo jar, estudei as soluções acima e tentei todos os métodos que existem alguma diferença entre si. Se esses códigos estiverem em execução no Eclipse IDE, todos deverão encontrar o caminho do arquivo, incluindo a classe indicada, e abrir ou criar um arquivo indicado com o caminho encontrado.
Mas é complicado, quando executar o arquivo jar executável diretamente ou através da linha de comando, ele falhará, pois o caminho do arquivo jar obtido pelos métodos acima fornecerá um caminho interno no arquivo jar, ou seja, sempre fornece um caminho Como
rsrc: nome do projeto (talvez eu deva dizer que é o nome do pacote do arquivo principal da classe - a classe indicada)
Não consigo converter o caminho rsrc: ... em um caminho externo, ou seja, ao executar o arquivo jar fora do IDE Eclipse, ele não pode obter o caminho do arquivo jar.
A única maneira possível de obter o caminho da execução do arquivo jar fora do IDE Eclipse é
essa linha de código pode retornar o caminho ativo (incluindo o nome do arquivo) do arquivo jar em execução (observe que o caminho de retorno não é o diretório ativo), como o documento java e algumas pessoas disseram que retornará os caminhos de todos os arquivos de classe no mesmo diretório, mas como meus testes se no mesmo diretório incluem muitos arquivos jar, ele retorna apenas o caminho da execução do jar (sobre o problema de vários caminhos, de fato, aconteceu no Eclipse).
— phchen2
java.class.pathpode ter vários valores. Um desses valores certamente fornecerá o diretório ou arquivo JAR em que a classe atual está localizada, mas qual?
Confirmo que tentei outras soluções, mas nunca obtive o nome do arquivo jar. Isso funciona de maneira muito simples! obrigado - +1
— guillaume girod-vitouchkina 16/04/2015
Outras respostas parecem apontar para a fonte de código, que é o local do arquivo Jar, que não é um diretório.
Pode ser um diretório, se você estiver carregando suas classes de um sistema de arquivos em vez de um arquivo JAR, por exemplo, durante a depuração.
a resposta selecionada acima não funcionará se você executar seu jar clicando nele no ambiente de área de trabalho Gnome (não em nenhum script ou terminal).
Em vez disso, gosto que a seguinte solução esteja funcionando em qualquer lugar:
Você tentou isso em um applet ou em um aplicativo. lançado usando o Java Web Start? Meu entendimento é que ele falhará nas duas situações (mesmo que o aplicativo seja confiável).
Esta solução só pode retornar a localização de "." dentro do arquivo JAR, não no local do arquivo JAR.
Na inicialização Spring, ele vai jogarNullPointerException
Você terá NPEse não houver recursos no JAR.
Na verdade, aqui está uma versão melhor - a antiga falhou se o nome de uma pasta tivesse um espaço nela.
Quanto à falha nos applets, você normalmente não teria acesso aos arquivos locais de qualquer maneira. Não sei muito sobre o JWS, mas, para lidar com arquivos locais, talvez não seja possível baixar o aplicativo.
— rapaz bacup
Existem várias maneiras internas de decodificar o caminho. Não há necessidade de escrever seu próprio código.
Eu tentei pegar o caminho do jar usando
Executando o aplicativo jar denominado "application.jar", no Windows na pasta " c: \ app ", o valor da variável String "pasta" era " \ c: \ app \ application.jar " e tive problemas ao testar correção do caminho
Então, eu tentei definir "teste" como:
para obter o caminho no formato correto como " c: \ app " em vez de " \ c: \ app \ application.jar " e notei que funcionava.
— TheGreatPsychoticBunny
A solução mais simples é passar o caminho como argumento ao executar o jar.
Você pode automatizar isso com um script de shell (.bat no Windows, .sh em qualquer outro lugar):
Eu costumava .passar o diretório de trabalho atual.
Você pode colocar o arquivo jar em um subdiretório para que os usuários não cliquem nele acidentalmente. Seu código também deve verificar se os argumentos da linha de comando foram fornecidos e fornecer uma boa mensagem de erro se os argumentos estiverem ausentes.
Eu tive que mexer muito antes de finalmente encontrar uma solução funcional (e curta).
É possível que ele jarLocationvenha com um prefixo como file:\ou jar:file\, que pode ser removido usando String#substring().
O caminho sempre se refere ao recurso dentro do arquivo jar.
Essa cadeia de caminho ainda precisa ser simplificada para sua necessidade. String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
Ambos getResource("")e getResource(".")falharam nos meus testes, quando a classe residia em um arquivo JAR; ambas as invocações retornaram nulas.
Isso joga NullPointerException.
Funciona bem no Windows
Algo frustrante é que, quando você está desenvolvendo no Eclipse, MyClass.class.getProtectionDomain().getCodeSource().getLocation()retorna o /bindiretório que é ótimo, mas quando você o compila em um jar, o caminho inclui a /myjarname.jarparte que fornece nomes de arquivos ilegais.
Para que o código funcione tanto no ide quanto depois de compilado em um jar, use o seguinte trecho de código:
Não tenho muita certeza dos outros, mas, no meu caso, ele não funcionou com um "jar executável" e eu consegui trabalhar corrigindo códigos juntos da resposta phchen2 e outra a partir deste link: Como obter o caminho de um arquivo JAR em execução? O código:
— Fahad Alkamli
Tentei várias soluções lá em cima, mas nenhuma produziu resultados corretos para o caso (provavelmente especial) de que o jar executável foi exportado com "Empacotando bibliotecas externas" no Eclipse. Por algum motivo, todas as soluções baseadas no ProtectionDomain resultam em nulo nesse caso.
Ao combinar algumas soluções acima, consegui obter o seguinte código de trabalho:
— DragonGamer
— Blarzek
Esse método, chamado de código no arquivo morto, retorna a pasta onde está o arquivo .jar. Deve funcionar no Windows ou no Unix.
Derivado do código em: Determine se está sendo executado a partir do JAR
— Bacup Lad
"Ele deve funcionar no Windows ou no Unix." mas falhará em qualquer applet e em todos os aplicativos. lançado usando o JWS.
— 21811 Andrew Thompson
Mencione que ele está marcado apenas para dentro, Windowsmas acho que funciona perfeitamente em outros sistemas operacionais [ Linux,MacOs,Solaris] :).
Eu tinha 2 .jar arquivos no mesmo diretório. Eu queria que um .jararquivo iniciasse o outro .jararquivo que está no mesmo diretório.
O problema é que, quando você o inicia cmdno diretório atual, é system32.
O abaixo parece funcionar muito bem em todos os testes que fiz, mesmo com o nome da pasta ;][[;'57f2g34g87-8+9-09!2#@!$%^^&()ou ()%&$%^@# funciona bem.
Estou usando o ProcessBuildercom o seguinte, como a seguir:
🍂 getBasePathForClass(Class<?> classs):
— GOXR3PLUS
Este código funcionou para mim para identificar se o programa está sendo executado dentro de um arquivo JAR ou IDE:
Se eu precisar obter o caminho completo do arquivo JAR do Windows, estou usando este método:
Meu código completo trabalhando com um aplicativo Spring Boot usando CommandLineRunnerimplementação, para garantir que o aplicativo sempre seja executado dentro de uma visualização do console (cliques duplos por engano no nome do arquivo JAR), estou usando o próximo código:
— Jairo Martínez
Escrevo em Java 7 e testo no Windows 7 com o tempo de execução da Oracle e no Ubuntu com o tempo de execução de código aberto. Isso funciona perfeito para esses sistemas:
O caminho para o diretório pai de qualquer arquivo jar em execução (assumindo que a classe que chama esse código é um filho direto do próprio arquivo jar):
Portanto, o caminho do foo.jar seria:
Novamente, isso não foi testado em nenhum Mac ou Windows mais antigo
A getProtectionDomainabordagem pode não funcionar, por vezes, por exemplo, quando você tem que encontrar o pote para algumas das classes Java núcleo (por exemplo, no meu caso StringBuilderclasse dentro IBM JDK), no entanto seguintes obras perfeitamente:
URL.getPath () não faz o que você pensa que faz. Quaisquer caracteres especiais serão codificados em porcentagem.
Eu tenho outra maneira de obter o local String de uma classe.
A String de saída terá a forma de
Os espaços e outros caracteres são manipulados e na forma sem file:/. Então será mais fácil de usar.