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.
java
path
jar
executable-jar
Thiago Chaves
fonte
fonte
Respostas:
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.
fonte
toURI()
etapa é vital para evitar problemas com caracteres especiais, incluindo espaços e vantagens. O alinhamento correto é: Oreturn new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
usoURLDecoder
não funciona para muitos caracteres especiais. Veja minha resposta abaixo para mais detalhes.getProtectionDomain
é nulo se você está recebendo sua classe a partir de um stracktrace:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
Melhor solução para mim:
Isso deve resolver o problema com espaços e caracteres especiais.
fonte
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
) no Linux. No entanto, eu não tentei no Windows.URLDecoder
para decodificar caracteres especiais. Em particular, caracteres como+
serão erroneamente decodificados para espaços. Veja minha resposta para detalhes.Para obter
File
um dadoClass
, há duas etapas:Class
emURL
URL
emFile
É importante entender os dois passos, e não confundi-los.
Depois de ter o
File
, você pode ligargetParentFile
para obter a pasta que contém, se é isso que precisa.Etapa 1:
Class
paraURL
Conforme discutido em outras respostas, há duas maneiras principais de encontrar um
URL
relevante para aClass
.URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
Ambos têm prós e contras.
A
getProtectionDomain
abordagem 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çadaSecurityException
ao chamargetProtectionDomain()
, portanto, se seu aplicativo precisar executar em uma variedade de ambientes, é melhor testar em todos eles.A
getResource
abordagem 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 umfile:
caminho, mas também pode serjar:file:
ou até algo mais desagradávelbundleresource://346.fwk2106232034:4/foo/Bar.class
ao executar dentro de uma estrutura OSGi. Por outro lado, agetProtectionDomain
abordagem gera corretamente umafile:
URL mesmo dentro do OSGi.Observe que ambos
getResource("")
egetResource(".")
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:
URL
paraFile
De qualquer forma, depois de ter um
URL
, o próximo passo é converter para aFile
. Este é o seu próprio desafio; consulte a publicação no blog de Kohsuke Kawaguchi para obter detalhes completos, mas, em suma, você pode usarnew 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:Na prática,
URLDecoder
geralmente não jogaIllegalArgumentException
como 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 aoURLDecoder
manipular o caminho do arquivo.Código de trabalho
Para realizar essas etapas, você pode ter métodos como o seguinte:
Você pode encontrar esses métodos na biblioteca comum do SciJava :
fonte
Você também pode usar:
fonte
Use ClassLoader.getResource () para encontrar o URL da sua classe atual.
Por exemplo:
(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.
fonte
NPE
porque 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
.Estou surpreso ao ver que nenhum recentemente propôs usar
Path
. Segue uma citação: " APath
classe 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
Path
objetivo como:fonte
A única solução que funciona para mim no Linux, Mac e Windows:
fonte
Eu tive o mesmo problema e resolvi da seguinte maneira:
Espero ter ajudado você.
fonte
Aqui está a atualização para outros comentários, que me parecem incompletos para as especificações de
fonte
URLDecoder
para decodificar caracteres especiais. Em particular, caracteres como+
serão erroneamente decodificados para espaços. Veja minha resposta para detalhes.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).
fonte
java.class.path
pode ter vários valores. Um desses valores certamente fornecerá o diretório ou arquivo JAR em que a classe atual está localizada, mas qual?Outras respostas parecem apontar para a fonte de código, que é o local do arquivo Jar, que não é um diretório.
Usar
fonte
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:
fonte
URLDecoder
para decodificar caracteres especiais. Em particular, caracteres como+
serão erroneamente decodificados para espaços. Veja minha resposta para detalhes.NullPointerException
NPE
se 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.
fonte
Eu tentei pegar o caminho do jar usando
c: \ app> java -jar application.jar
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.
fonte
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.ATUALIZAR
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.
fonte
Eu tive que mexer muito antes de finalmente encontrar uma solução funcional (e curta).
É possível que ele
jarLocation
venha com um prefixo comofile:\
oujar:file\
, que pode ser removido usandoString#substring()
.fonte
O caminho sempre se refere ao recurso dentro do arquivo jar.
fonte
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
egetResource(".")
falharam nos meus testes, quando a classe residia em um arquivo JAR; ambas as invocações retornaram nulas.NullPointerException
.Funciona bem no Windows
fonte
Algo frustrante é que, quando você está desenvolvendo no Eclipse,
MyClass.class.getProtectionDomain().getCodeSource().getLocation()
retorna o/bin
diretório que é ótimo, mas quando você o compila em um jar, o caminho inclui a/myjarname.jar
parte 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:
fonte
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:
fonte
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:
fonte
Tente o seguinte:
fonte
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
fonte
Mencione que ele está marcado apenas para dentro,
Windows
mas acho que funciona perfeitamente em outros sistemas operacionais [Linux,MacOs,Solaris
] :).Eu tinha 2
.jar
arquivos no mesmo diretório. Eu queria que um.jar
arquivo iniciasse o outro.jar
arquivo que está no mesmo diretório.O problema é que, quando você o inicia
cmd
no diretório atual, ésystem32
.;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
ou()%&$%^@#
funciona bem.ProcessBuilder
com o seguinte, como a seguir:🍂 ..
🍂
getBasePathForClass(Class<?> classs)
:fonte
Este código funcionou para mim:
fonte
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
CommandLineRunner
implementaçã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:fonte
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
fonte
A
getProtectionDomain
abordagem 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 casoStringBuilder
classe dentro IBM JDK), no entanto seguintes obras perfeitamente:fonte
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.fonte