Eu preciso ler o Manifest
arquivo, que entregou minha classe, mas quando eu uso:
getClass().getClassLoader().getResources(...)
Eu recebo o MANIFEST
primeiro .jar
carregado no Java Runtime.
Meu aplicativo será executado a partir de um miniaplicativo ou de um webstart,
portanto , acho que não terei acesso ao meu próprio .jar
arquivo.
Na verdade, eu quero ler o Export-package
atributo a partir do .jar
qual o Felix OSGi iniciou, para que eu possa expor esses pacotes ao Felix. Alguma ideia?
java
osgi
manifest.mf
apache-felix
Houtman
fonte
fonte
Respostas:
Você pode fazer uma das duas coisas:
Ligue
getResources()
e repita a coleção retornada de URLs, lendo-os como manifestos até encontrar o seu:Você pode tentar verificar se
getClass().getClassLoader()
é uma instância dejava.net.URLClassLoader
. A maioria dos carregadores de classes da Sun são, inclusiveAppletClassLoader
. Em seguida, você pode convertê-lo e chamar ofindResource()
que é conhecido - pelo menos para applets - para retornar diretamente o manifesto necessário:fonte
Você pode encontrar o URL da sua turma primeiro. Se for um JAR, você carregará o manifesto a partir daí. Por exemplo,
fonte
classPath.replace("org/example/MyClass.class", "META-INF/MANIFEST.MF"
getSimpleName
remove o nome da classe externa. Isto irá funcionar para classes internas:clazz.getName().replace (".", "/") + ".class"
.Você pode usar
Manifests
de jcabi-manifestests e ler qualquer atributo de qualquer um dos arquivos MANIFEST.MF disponíveis com apenas uma linha:A única dependência que você precisa é:
Além disso, consulte esta publicação no blog para obter mais detalhes: http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
fonte
<logger name="com.jcabi.manifests" level="OFF"/>
Admito desde já que esta resposta não responde à pergunta original, a de geralmente poder acessar o Manifesto. No entanto, se o que é realmente necessário é ler um dos vários atributos "padrão" do Manifest, a solução a seguir é muito mais simples do que as postadas acima. Então, espero que o moderador permita. Observe que esta solução está no Kotlin, não no Java, mas eu esperaria que uma porta para Java fosse trivial. (Embora eu admita que não conheço o equivalente em Java de ".`package`".
No meu caso, eu queria ler o atributo "Implementation-Version", então comecei com as soluções fornecidas acima para obter o fluxo e, em seguida, li-o para obter o valor. Enquanto essa solução funcionava, um colega de trabalho revisando meu código me mostrou uma maneira mais fácil de fazer o que eu queria. Observe que esta solução está no Kotlin, não no Java.
Mais uma vez, observe que isso não responde à pergunta original, em particular "Export-package" não parece ser um dos atributos suportados. Dito isto, existe um myPackage.name que retorna um valor. Talvez alguém que entenda isso mais do que eu possa comentar se isso retorna o valor que o pôster original está solicitando.
fonte
String implementationVersion = MyApplication.class.getPackage().getImplementationVersion();
Acredito que a maneira mais apropriada de obter o manifesto para qualquer pacote (incluindo o pacote que carregou uma determinada classe) é usar o objeto Bundle ou BundleContext.
Observe que o objeto Bundle também fornece
getEntry(String path)
a consulta de recursos contidos em um pacote específico, em vez de procurar o caminho de classe inteiro desse pacote.Em geral, se você quiser informações específicas de pacote configurável, não confie em suposições sobre os carregadores de classes, basta usar as APIs OSGi diretamente.
fonte
O código a seguir funciona com vários tipos de arquivos (jar, war) e vários tipos de classloaders (jar, url, vfs, ...)
fonte
clz.getResource(resource).toString()
barras invertidas?A maneira mais fácil é usar a classe JarURLConnection:
Como, em alguns casos,
...class.getProtectionDomain().getCodeSource().getLocation();
fornece caminho paravfs:/
, isso deve ser tratado adicionalmente.fonte
Você pode usar getProtectionDomain (). GetCodeSource () assim:
fonte
getCodeSource
pode retornarnull
. Quais são os critérios para que isso funcione? A documentação não explica isso.DataUtilities
importado? Não parece estar no JDK.Por que você está incluindo a etapa getClassLoader? Se você disser "this.getClass (). GetResource ()", você deverá obter recursos relativos à classe de chamada. Eu nunca usei ClassLoader.getResource (), embora, a partir de uma rápida olhada no Java Docs, pareça que você obterá o primeiro recurso desse nome encontrado em qualquer caminho de classe atual.
fonte
class.getResource("myresource.txt")
tentará carregar esse recursocom/mypackage/myresource.txt
. Como exatamente você vai usar essa abordagem para obter o manifesto?fonte
cl.getResourceAsStream("META-INF/MANIFEST.MF")
.classLoader.getResource(..)
eurl.openStream()
é totalmente irrelevante e propenso a erros, pois ele tenta fazer o mesmo queclassLoader.getResourceAsStream(..)
faz.ClassLoader classLoader = cl.getClassLoader(); return new Manifest(classLoader.getResourceAsStream("/META-INF/MANIFEST.MF"));
Eu usei a solução de Anthony Juckel, mas no MANIFEST.MF a chave deve começar com maiúsculas.
Portanto, meu arquivo MANIFEST.MF contém uma chave como:
Mykey: value
Em seguida, no ativador ou em outra classe, você pode usar o código de Anthony para ler o arquivo MANIFEST.MF e o valor necessário.
fonte
Eu tenho essa solução estranha que executa aplicativos de guerra em um servidor Jetty incorporado, mas esses aplicativos também precisam ser executados em servidores Tomcat padrão, e temos algumas propriedades especiais no manifesto.
O problema era que, no Tomcat, o manifesto podia ser lido, mas, no cais, um manifesto aleatório era capturado (perdendo as propriedades especiais)
Com base na resposta de Alex Konshin, eu vim com a seguinte solução (o fluxo de entrada é então usado em uma classe Manifest):
fonte