web-dev-qa-db-fra.com

Comment référencer correctement un fichier de ressources pour JAR et le débogage?

J'ai un vilain problème de référencement des ressources lors de l'utilisation d'un projet Maven et de fichiers Jar ...

J'ai toutes mes ressources dans un dossier dédié/src/main/resources qui fait partie du chemin de construction dans Eclipse. Les fichiers sont référencés en utilisant 

getClass().getResource("/filename.txt")

Cela fonctionne bien dans Eclipse mais échoue dans le fichier Jar - les ressources se trouvent dans un dossier situé directement sous la racine du jar ...

Est-ce que quelqu'un connaît une «meilleure pratique» pour référencer un fichier à la fois dans le fichier JAR et (!) Dans Eclipse?

Modifier:Le problème est que, bien que les ressources se trouvent réellement dans le fichier JAR dans un dossier "ressources" au niveau supérieur, la méthode ci-dessus ne parvient pas à trouver le fichier ...

37
Patrick

Le contenu des dossiers de ressources Maven est copié dans target/classes et de là dans la racine du fichier Jar résultant. C'est le comportement attendu.

Ce que je ne comprends pas, c'est quel est le problème dans votre scénario. Le référencement d'une ressource via getClass().getResource("/filename.txt") commence à la racine du chemin de classe, qu'il s'agisse de (ou de l'un de ses éléments) target/classes ou de la racine du JAR. La seule erreur possible que je vois est que vous utilisez la mauvaise ClassLoader.

Assurez-vous que la classe qui utilise la ressource se trouve dans le même artefact (JAR) que la ressource et exécutez ThatClass.class.getResource("/path/with/slash") ou ThatClass.class.getClassLoader().getResource("path/without/slash").

Mais à part cela: si cela ne fonctionne pas, vous faites probablement quelque chose de mal quelque part dans le processus de construction. Pouvez-vous vérifier que la ressource est dans le fichier JAR?

16

J'ai eu un problème similaire… .. Après une journée complète d'essais de toutes les combinaisons et de débogage, j'ai essayé getClass ().

18
andjelko

Une fois que vous compressez le fichier JAR, vos fichiers de ressources ne sont plus des fichiers, mais des flux, donc getResource ne fonctionnera pas!

Utilisez getResourceAsStream.

Pour obtenir le contenu du fichier, utilisez https://commons.Apache.org/proper/commons-io/javadocs/api-release/org/Apache/commons/io/IOUtils.html :

static public String getFile(String fileName)
{
        //Get file from resources folder
        ClassLoader classLoader = (new A_CLASS()).getClass().getClassLoader();

        InputStream stream = classLoader.getResourceAsStream(fileName);

        try
        {
            if (stream == null)
            {
                throw new Exception("Cannot find file " + fileName);
            }

            return IOUtils.toString(stream);
        }
        catch (Exception e) {
            e.printStackTrace();

            System.exit(1);
        }

        return null;
}
16
Thomas Decaux

Peut-être que cette méthode peut aider dans certaines situations.

public static File getResourceFile(String relativePath)
{
    File file = null;
    URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
    String codeLoaction = location.toString();
    try{
        if (codeLocation.endsWith(".jar"){
            //Call from jar
            Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
            file = path.toFile();
        }else{
            //Call from IDE
            file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
        }
    }catch(URISyntaxException ex){
        ex.printStackTrace();
    }
    return file;
}
0
gbii