Modèle de vitesse de chargement dans un fichier jar

J’ai un projet où je veux charger un modèle de vélocité pour le compléter avec des parameters. L’application entière est présentée sous forme de fichier jar. Ce que j’ai d’abord pensé à faire était ceci:

VelocityEngine ve = new VelocityEngine(); URL url = this.getClass().getResource("/templates/"); File file = new File(url.getFile()); ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "file"); ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, file.getAbsolutePath()); ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, "true"); ve.init(); VelocityContext context = new VelocityContext(); if (properties != null) { ssortingngfyNulls(properties); for (Map.Entry property : properties.entrySet()) { context.put(property.getKey(), property.getValue()); } } final Ssortingng templatePath = templateName + ".vm"; Template template = ve.getTemplate(templatePath, "UTF-8"); Ssortingng outFileName = File.createTempFile("report", ".html").getAbsolutePath(); BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outFileName))); template.merge(context, writer); writer.flush(); writer.close(); 

Et cela fonctionne bien quand je l’exécute en éclipse. Cependant, une fois que j’emballe le programme et que je tente de l’exécuter à l’aide de la ligne de commande, j’obtiens une erreur car le fichier est introuvable.

J’imagine que le problème est dans cette ligne:

 ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, file.getAbsolutePath()); 

Parce que dans un fichier jar, le fichier absolu n’existe pas, car il se trouve dans un fichier zip, mais je n’ai pas encore trouvé de meilleur moyen de le faire.

Quelqu’un a des idées?

    Si vous souhaitez utiliser des ressources de classpath, vous devez utiliser le chargeur de ressources pour classpath:

     ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); 

    Code final, développé en utilisant les idées présentées dans les deux réponses ci-dessus:

     VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); ve.init(); final Ssortingng templatePath = "templates/" + templateName + ".vm"; InputStream input = this.getClass().getClassLoader().getResourceAsStream(templatePath); if (input == null) { throw new IOException("Template file doesn't exist"); } InputStreamReader reader = new InputStreamReader(input); VelocityContext context = new VelocityContext(); if (properties != null) { ssortingngfyNulls(properties); for (Map.Entry property : properties.entrySet()) { context.put(property.getKey(), property.getValue()); } } Template template = ve.getTemplate(templatePath, "UTF-8"); Ssortingng outFileName = File.createTempFile("report", ".html").getAbsolutePath(); BufferedWriter writer = new BufferedWriter(new FileWriter(new File(outFileName))); if (!ve.evaluate(context, writer, templatePath, reader)) { throw new Exception("Failed to convert the template into html."); } template.merge(context, writer); writer.flush(); writer.close(); 

    À moins que JAR ne soit explosé, vous ne pouvez pas lire la ressource dans JAR en tant que fichier. Utilisez un stream d’entrée.

    Voir les extraits de code suivants,

      InputStream input = classLoader.getResourceAsStream(fileName); if (input == null) { throw new ConfigurationException("Template file " + fileName + " doesn't exist"); } InputStreamReader reader = new InputStreamReader(input); Writer writer = null; try { writer = new OutputStreamWriter(output); // Merge template if (!engine.evaluate(context, writer, fileName, reader)) ...... 

    Pour que Velocity recherche les templates dans classpath:

     VelocityEngine ve = new VelocityEngine(); ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath"); ve.setProperty("classpath.resource.loader.class",ClasspathResourceLoader.class.getName()); ve.init();