如何从spring实例化的POJO类(不是servlet)读取manifest.mf?

发布于 2024-09-26 20:03:24 字数 738 浏览 3 评论 0原文

我有一个名为 BuildNumberService 的简单服务,它将由 spring 实例化。

我正在尝试为该类找到最干净的代码,以便从它打包到的 jar 文件中找出 MANIFEST.MF 文件。

该代码必须在 servlet 容器内运行。

@Service
public class BuildNumberService {

    private static final String IMPLEMENTATION_BUILD = "Implementation-Build";

    private String version = null;

    public BuildNumberService() {

      // find correct manifest.mf
      // ?????


      // then read IMPLEMENTATION_BUILD attributes and caches it.
       Attributes mainAttributes = mf.getMainAttributes();
       version = mainAttributes.getValue(IMPLEMENTATION_BUILD);
    }

    public String getVersion() {
        return this.version;
    }
}

你会怎么做?

编辑:实际上,我想做的是,按名称查找与实际类位于同一包中的资源。

I have a simple service called BuildNumberService which would be instantiated by spring.

I'm trying to find the cleanest code for the class to find out the MANIFEST.MF file from the jar file it has been packaged into.

The code has to run inside a servlet container.

@Service
public class BuildNumberService {

    private static final String IMPLEMENTATION_BUILD = "Implementation-Build";

    private String version = null;

    public BuildNumberService() {

      // find correct manifest.mf
      // ?????


      // then read IMPLEMENTATION_BUILD attributes and caches it.
       Attributes mainAttributes = mf.getMainAttributes();
       version = mainAttributes.getValue(IMPLEMENTATION_BUILD);
    }

    public String getVersion() {
        return this.version;
    }
}

How would you do that ?

Edit: Actually, what I'm trying to do, is, find a resource by name which sits in the same package as the actual class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

酸甜透明夹心 2024-10-03 20:03:24

我找到了另一种解决方案,只需使用 Spring Framework 即可加载 MANIFEST.MF,而无需引用 servlet 上下文。

我在 Spring 3.1.2.RELEASE 中使用了此配置,但我相信它在以后的版本中应该可以正常工作。

首先,在 applicationContext.xml 中编写以下 bean

<bean class="java.util.jar.Manifest" id="manifest">
    <constructor-arg>
        <value>/META-INF/MANIFEST.MF</value>
    </constructor-arg>  
</bean>

您应该注意到 Manifest 类中的构造函数参数接受 InputStream 作为参数,但是,您无需担心这一点,因为 Spring 会将提供的值转换为匹配构造函数参数。
此外,通过以斜杠 / (/META-INF/...) 开始路径,Spring 在 servlet 上下文对象上查找此文件,同时以 classpath: 开始前缀它引导 Spring 查看类路径以查找所请求的资源。

其次,在您的类中声明上述 bean:

@Autowired
@Qualifier("manifest")
private Manifest manifest;

我的 MANIFEST.MF 位于文件夹 $WEBAPP_ROOT/META-INF/ 下,我已在 Apache Tomcat 7 和 WildFly 8 上成功测试了此解决方案。

I've found another solution to load MANIFEST.MF without referencing servlet context, by just using Spring Framework.

I used this configuration with Spring 3.1.2.RELEASE, but I believe it should work fine on later releases.

First, write the following bean in your applicationContext.xml

<bean class="java.util.jar.Manifest" id="manifest">
    <constructor-arg>
        <value>/META-INF/MANIFEST.MF</value>
    </constructor-arg>  
</bean>

You should notice that the constructor argument from Manifest class accepts an InputStream as a parameter, however, you don't need to worry about that 'cause Spring converts the provided value to match constructor arguments.
Moreover, by starting the path with a slash / (/META-INF/...), Spring looks for this file on a servlet context object whereas starting with classpath: prefix it steers Spring to look over the classpath to find the requested resource.

Second, declare the aforementioned bean in your class:

@Autowired
@Qualifier("manifest")
private Manifest manifest;

My MANIFEST.MF is under the folder $WEBAPP_ROOT/META-INF/ and I've successfully tested this solution on Apache Tomcat 7 and WildFly 8.

洒一地阳光 2024-10-03 20:03:24

好吧,如果您知道 jar 位于文件系统上(例如不在战争中)并且您还知道安全管理器授予您访问类保护域的权限,您可以这样做:

public static InputStream findManifest(final Class<?> clazz) throws IOException,
    URISyntaxException{
    final URL jarUrl =
        clazz.getProtectionDomain().getCodeSource().getLocation();
    final JarFile jf = new JarFile(new File(jarUrl.toURI()));
    final ZipEntry entry = jf.getEntry("META-INF/MANIFEST.MF");
    return entry == null ? null : jf.getInputStream(entry);
}

Well if you know the jar is on the file system (e.g. not inside a war) and you also know that the security manager gives you the permission to access a class' protection domain, you can do it like this:

public static InputStream findManifest(final Class<?> clazz) throws IOException,
    URISyntaxException{
    final URL jarUrl =
        clazz.getProtectionDomain().getCodeSource().getLocation();
    final JarFile jf = new JarFile(new File(jarUrl.toURI()));
    final ZipEntry entry = jf.getEntry("META-INF/MANIFEST.MF");
    return entry == null ? null : jf.getInputStream(entry);
}
聆听风音 2024-10-03 20:03:24
Manifest mf = new Manifest();
Resource resource = new ClassPathResource("META-INF/MANIFEST.MF");
                    InputStream is= resource.getInputStream();
                        mf.read(is);
                        if (mf != null) {
                            Attributes atts = mf.getMainAttributes();
                            implementationTitle = atts.getValue("Implementation-Title");
                        }
Manifest mf = new Manifest();
Resource resource = new ClassPathResource("META-INF/MANIFEST.MF");
                    InputStream is= resource.getInputStream();
                        mf.read(is);
                        if (mf != null) {
                            Attributes atts = mf.getMainAttributes();
                            implementationTitle = atts.getValue("Implementation-Title");
                        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文