2010-10-11 3 views
3

У меня есть простой сервис под названием BuildNumberService, который будет создан экземпляром весной.Как читать manifest.mf из класса POJO (а не сервлета), созданного весной?

Я пытаюсь найти самый чистый код для класса, чтобы узнать файл 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; 
    } 
} 

Как вы это сделаете?

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

+0

посмотрите на [jcabi-manifestests] (http://www.jcabi.com/jcabi-manifests/index.html) с полезным классом, который делает все это для вас – yegor256

+0

I догадаться, вы можете увидеть ответ на [этот вопрос] (http://stackoverflow.com/questions/3777055/readin г-манифест-MF-файлы из-Jar-файл-используя-Java). – Riduidel

ответ

2

Ну, если вы знаете, что банка находится в файловой системе (например, не внутри войны), и вы также знаете, что менеджер безопасности дает вам разрешение на доступ к домену защиты класса, вы можете сделать это следующим образом:

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); 
} 
+4

Psshh .. ['JarFile # getManifest()'] (http://download.oracle.com/javase/6/docs/api/java/util/jar/JarFile.html#getManifest%28%29). – BalusC

+0

@BalusC, что было бы слишком легко. Позвольте мне самому заниматься ногами :-) (Честно говоря, не знал об этом) –

+0

Это единственный способ для класса найти банку, в которой она упакована? Кажется, что jdk затрудняет чтение этих метаданных во время выполнения. Как будто этого не должно было быть сделано. – David

2

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

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

Во-первых, написать следующий компонент в вашем 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.

 Смежные вопросы

  • Нет связанных вопросов^_^