3

我有一个名为 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;
    }
}

你会怎么做?

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

4

3 回答 3

2

好吧,如果您知道 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);
}
于 2010-10-11T15:58:37.933 回答
2

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

我将此配置与 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 上成功测试了这个解决方案。

于 2014-09-06T13:47:26.217 回答
0
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");
                        }
于 2019-05-01T18:48:24.623 回答