Hou*_*man 124 java osgi manifest.mf apache-felix
我需要读取Manifest
传递我的课程的文件,但是当我使用时:
getClass().getClassLoader().getResources(...)
Run Code Online (Sandbox Code Playgroud)
我MANIFEST
从第一次.jar
加载到Java Runtime.
我的应用程序将从小程序或webstart运行,
因此.jar
我猜我无法访问自己的文件.
我实际上想要读取启动Felix OSGi 的Export-package
属性.jar
,所以我可以将这些包暴露给Felix.有任何想法吗?
ZZ *_*der 117
您可以先找到您班级的URL.如果它是JAR,那么从那里加载清单.例如,
Class clazz = MyClass.class;
String className = clazz.getSimpleName() + ".class";
String classPath = clazz.getResource(className).toString();
if (!classPath.startsWith("jar")) {
// Class not from JAR
return;
}
String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
"/META-INF/MANIFEST.MF";
Manifest manifest = new Manifest(new URL(manifestPath).openStream());
Attributes attr = manifest.getMainAttributes();
String value = attr.getValue("Manifest-Version");
Run Code Online (Sandbox Code Playgroud)
Chs*_*y76 110
你可以做以下两件事之一:
调用getResources()
并遍历返回的URL集合,将其作为清单读取,直到找到您的URL:
Enumeration<URL> resources = getClass().getClassLoader()
.getResources("META-INF/MANIFEST.MF");
while (resources.hasMoreElements()) {
try {
Manifest manifest = new Manifest(resources.nextElement().openStream());
// check that this is your manifest and do what you need or get the next one
...
} catch (IOException E) {
// handle
}
}
Run Code Online (Sandbox Code Playgroud)您可以尝试检查是否getClass().getClassLoader()
是实例java.net.URLClassLoader
.大多数Sun类加载器都包括在内AppletClassLoader
.然后,您可以将其转换并调用findResource()
已知的 - 至少对于applet - 直接返回所需的清单:
URLClassLoader cl = (URLClassLoader) getClass().getClassLoader();
try {
URL url = cl.findResource("META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(url.openStream());
// do stuff with it
...
} catch (IOException E) {
// handle
}
Run Code Online (Sandbox Code Playgroud)yeg*_*256 21
您可以使用Manifests
从jcabi-清单和读取任何可用的MANIFEST.MF文件的任何属性只用一行:
String value = Manifests.read("My-Attribute");
Run Code Online (Sandbox Code Playgroud)
您需要的唯一依赖是:
<dependency>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-manifests</artifactId>
<version>0.7.5</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
此外,请参阅此博客文章了解更多详情:http://www.yegor256.com/2014/07/03/how-to-read-manifest-mf.html
Ant*_*kel 11
我认为获取任何bundle的清单(包括加载给定类的bundle)的最合适的方法是使用Bundle或BundleContext对象.
// If you have a BundleContext
Dictionary headers = bundleContext.getBundle().getHeaders();
// If you don't have a context, and are running in 4.2
Bundle bundle = FrameworkUtil.getBundle(this.getClass());
bundle.getHeaders();
Run Code Online (Sandbox Code Playgroud)
请注意,Bundle对象还提供getEntry(String path)
查找特定包中包含的资源,而不是搜索该包的整个类路径.
通常,如果您需要特定于包的信息,请不要依赖关于类加载器的假设,只需直接使用OSGi API.
小智 9
以下代码适用于多种类型的存档(jar,war)和多种类型的类加载器(jar,url,vfs,...)
public static Manifest getManifest(Class<?> clz) {
String resource = "/" + clz.getName().replace(".", "/") + ".class";
String fullPath = clz.getResource(resource).toString();
String archivePath = fullPath.substring(0, fullPath.length() - resource.length());
if (archivePath.endsWith("\\WEB-INF\\classes") || archivePath.endsWith("/WEB-INF/classes")) {
archivePath = archivePath.substring(0, archivePath.length() - "/WEB-INF/classes".length()); // Required for wars
}
try (InputStream input = new URL(archivePath + "/META-INF/MANIFEST.MF").openStream()) {
return new Manifest(input);
} catch (Exception e) {
throw new RuntimeException("Loading MANIFEST for class " + clz + " failed!", e);
}
}
Run Code Online (Sandbox Code Playgroud)
我将首先承认这个答案不能回答最初的问题,即通常能够访问清单的问题。但是,如果真正需要读取多个“标准”清单属性之一,则以下解决方案比上面发布的解决方案简单得多。因此,我希望主持人允许。请注意,此解决方案是在Kotlin中而不是Java中进行的,但是我希望通向Java的端口很简单。(尽管我承认我不知道Java的“ .`package`”。
在我的情况下,我想读取属性“ Implementation-Version”,因此我从上面给出的解决方案开始获取流,然后对其进行读取以获取值。在此解决方案有效的同时,一位同事检查了我的代码,向我展示了一种更轻松的方法来完成我想要的事情。请注意,此解决方案位于Kotlin中,而不是Java中。
val myPackage = MyApplication::class.java.`package`
val implementationVersion = myPackage.implementationVersion
Run Code Online (Sandbox Code Playgroud)
再次注意,这并不能回答原始问题,特别是“ Export-package”似乎不是受支持的属性之一。也就是说,有一个myPackage.name返回一个值。也许有人比我理解得更多,但我无法评论它是否返回原始海报所要求的值。
最简单的方法是使用JarURLConnection类:
String className = getClass().getSimpleName() + ".class";
String classPath = getClass().getResource(className).toString();
if (!classPath.startsWith("jar")) {
return DEFAULT_PROPERTY_VALUE;
}
URL url = new URL(classPath);
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
Manifest manifest = jarConnection.getManifest();
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue(PROPERTY_NAME);
Run Code Online (Sandbox Code Playgroud)
因为在某些情况下...class.getProtectionDomain().getCodeSource().getLocation();
会给出路径vfs:/
,所以这应该另外处理.
更简单的方法是使用 getPackage()。例如,要获取实现版本:
Application.class.getPackage().getImplementationVersion()
Run Code Online (Sandbox Code Playgroud)
小智 6
您可以像这样使用getProtectionDomain().getCodeSource():
URL url = Menu.class.getProtectionDomain().getCodeSource().getLocation();
File file = DataUtilities.urlToFile(url);
JarFile jar = null;
try {
jar = new JarFile(file);
Manifest manifest = jar.getManifest();
Attributes attributes = manifest.getMainAttributes();
return attributes.getValue("Built-By");
} finally {
jar.close();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
113501 次 |
最近记录: |