166 votes

Le fichier dans le jar n'est pas visible pour spring

Tous

J'ai créé un fichier jar avec le MANIFEST.MF suivant à l'intérieur :

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.3
Created-By: 1.6.0_25-b06 (Sun Microsystems Inc.)
Main-Class: my.Main
Class-Path: . lib/spring-core-3.2.0.M2.jar lib/spring-beans-3.2.0.M2.jar

Dans sa racine, il y a un fichier appelé my.config qui est référencé dans mon spring-context.xml comme ceci :

<bean id="..." class="...">
    <property name="resource" value="classpath:my.config" />
</bean>

Si je lance le jar, tout semble correct, sauf le chargement de ce fichier spécifique :

Caused by: java.io.FileNotFoundException: class path resource [my.config] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/D:/work/my.jar!/my.config
        at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:205)
    at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:52)
    at eu.stepman.server.configuration.BeanConfigurationFactoryBean.getObject(BeanConfigurationFactoryBean.java:32)
    at eu.stepman.server.configuration.BeanConfigurationFactoryBean.getObject(BeanConfigurationFactoryBean.java:1)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:142)
    ... 22 more
  • les classes sont chargées depuis l'intérieur du jar
  • spring et les autres dépendances sont chargées à partir de jars séparés.
  • le contexte de printemps est chargé (new ClassPathXmlApplicationContext("spring-context/applicationContext.xml"))
  • my.properties est chargé dans PropertyPlaceholderConfigurer ("classpath:my.properties")
  • Si je place mon fichier .config en dehors du système de fichiers, et que je change l'url de la ressource en 'file:', tout semble aller bien...

Des conseils ?

2voto

takacsot Points 535

J'ai eu un problème similaire en utilisant Tomcat6.x et aucun des conseils que j'ai trouvé ne m'a aidé. À la fin, j'ai supprimé work (de Tomcat) et le problème a disparu.

Je sais que c'est illogique, mais pour la documentation...

2voto

J'avais un problème plus complexe car j'ai plus d'un fichier avec le même nom, l'un est dans le jar principal de Spring Boot et les autres sont dans des jars à l'intérieur du jar principal. Ma solution était de récupérer toutes les ressources avec le même nom et ensuite de récupérer celle dont j'avais besoin en filtrant par le nom du paquet. Pour obtenir tous les fichiers :

ResourceLoader resourceLoader = new FileSystemResourceLoader();
final Enumeration<URL> systemResources = resourceLoader.getClassLoader().getResources(fileNameWithoutExt + FILE_EXT);

2voto

GabrielBB Points 361

Pour les utilisateurs de kotlin, j'ai résolu le problème comme suit :

val url = ResourceUtils.getURL("classpath:$fileName")
val response = url.openStream().bufferedReader().readText()

2voto

Its-Saab Points 11

Dans le packaging Jar de Spring boot 1.5.22.RELEASE, cela a fonctionné pour moi :

InputStream resource = new ClassPathResource("example.pdf").getInputStream();

"example.pdf" est dans src/main/resources.

Et ensuite pour le lire comme byte[]

FileCopyUtils.copyToByteArray(resource);

1voto

La réponse de @sbk est la façon dont nous devrions le faire dans un environnement spring-boot (à part @Value("${classpath*:})), à mon avis. Mais dans mon scénario, cela ne fonctionnait pas si l'exécution se faisait à partir d'un jar autonome peut-être ai-je fait quelque chose de mal.

Mais cela peut être un autre moyen de le faire,

InputStream is = this.getClass().getClassLoader().getResourceAsStream(<relative path of the resource from resource directory>);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X