Как прочитать manifest.mf из класса POJO (не сервлета), созданного Spring?

У меня есть простая служба под названием BuildNumberService, которая будет создана весной.

Я пытаюсь найти самый чистый код для класса, чтобы узнать файл MANIFEST.MF из файла jar, в который он был упакован.

Код должен выполняться внутри контейнера сервлета.

@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;
    }
}

Как бы Вы это сделали ?

Редактировать: На самом деле, я пытаюсь найти ресурс по имени, который находится в том же пакете, что и фактический класс.


person David    schedule 11.10.2010    source источник
comment
Я думаю, вы можете увидеть ответ на этот вопрос .   -  person Riduidel    schedule 11.10.2010
comment
взгляните на jcabi-manifests с служебным классом, который выполняет всю эту работу для тебя   -  person yegor256    schedule 30.12.2012


Ответы (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);
}
person Sean Patrick Floyd    schedule 11.10.2010

Я нашел другое решение для загрузки MANIFEST.MF без ссылки на контекст сервлета, просто используя Spring Framework.

Я использовал эту конфигурацию с Spring 3.1.2.RELEASE, но я считаю, что она должна нормально работать в более поздних версиях.

Сначала напишите следующий bean-компонент в файле applicationContext.xml.

<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 ищет этот файл в объекте контекста сервлета, тогда как, начиная с префикса classpath:, Spring просматривает путь к классам, чтобы найти запрошенный ресурс.

Во-вторых, объявите вышеупомянутый компонент в своем классе:

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

Мой MANIFEST.MF находится в папке $WEBAPP_ROOT/META-INF/, и я успешно протестировал это решение на Apache Tomcat 7 и WildFly 8.

person s_bighead    schedule 06.09.2014