tutorial mvc example application spring-boot

spring-boot - mvc - spring boot web application example



Recurso Classpath no encontrado cuando se ejecuta como jar (8)

Creé una clase ClassPathResourceReader en formato java 8 para facilitar la lectura de archivos desde classpath

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.stream.Collectors; import org.springframework.core.io.ClassPathResource; public final class ClassPathResourceReader { private final String path; private String content; public ClassPathResourceReader(String path) { this.path = path; } public String getContent() { if (content == null) { try { ClassPathResource resource = new ClassPathResource(path); BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream())); content = reader.lines().collect(Collectors.joining("/n")); reader.close(); } catch (IOException ex) { throw new RuntimeException(ex); } } return content; } }

Utilización:

String content = new ClassPathResourceReader("data.sql").getContent();

Al tener este problema tanto en Spring Boot 1.1.5 como en 1.1.6, estoy cargando un recurso classpath usando una anotación @Value, que funciona bien cuando ejecuto la aplicación desde STS (3.6.0, Windows). Sin embargo, cuando ejecuto un paquete mvn y luego trato de ejecutar el jar, obtengo las excepciones FileNotFound.

El recurso, message.txt, está en src / main / resources. He inspeccionado el jar y he verificado que contiene el archivo "message.txt" en el nivel superior (el mismo nivel que application.properties).

Aquí está la aplicación:

@Configuration @ComponentScan @EnableAutoConfiguration public class Application implements CommandLineRunner { private static final Logger logger = Logger.getLogger(Application.class); @Value("${message.file}") private Resource messageResource; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... arg0) throws Exception { // both of these work when running as Spring boot app from STS, but // fail after mvn package, and then running as java -jar testResource(new ClassPathResource("message.txt")); testResource(this.messageResource); } private void testResource(Resource resource) { try { resource.getFile(); logger.debug("Found the resource " + resource.getFilename()); } catch (IOException ex) { logger.error(ex.toString()); } } }

La excepción:

c:/Users/glyoder/Documents/workspace-sts-3.5.1.RELEASE/classpath-resource-proble m/target>java -jar demo-0.0.1-SNAPSHOT.jar . ____ _ __ _ _ /// / ___''_ __ _ _(_)_ __ __ _ / / / / ( ( )/___ | ''_ | ''_| | ''_ // _` | / / / / /// ___)| |_)| | | | | || (_| | ) ) ) ) '' |____| .__|_| |_|_| |_/__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.1.5.RELEASE) 2014-09-16 08:46:34.635 INFO 5976 --- [ main] demo.Application : Starting Application on 8W59XV1 with PID 5976 (C:/Users/glyo der/Documents/workspace-sts-3.5.1.RELEASE/classpath-resource-problem/target/demo -0.0.1-SNAPSHOT.jar started by glyoder in c:/Users/glyoder/Documents/workspace-s ts-3.5.1.RELEASE/classpath-resource-problem/target) 2014-09-16 08:46:34.640 DEBUG 5976 --- [ main] demo.Application : Running with Spring Boot v1.1.5.RELEASE, Spring v4.0.6.RELEA SE 2014-09-16 08:46:34.681 INFO 5976 --- [ main] s.c.a.AnnotationConfigA pplicationContext : Refreshing org.springframework.context.annotation.Annotation ConfigApplicationContext@1c77b086: startup date [Tue Sep 16 08:46:34 EDT 2014]; root of context hierarchy 2014-09-16 08:46:35.196 INFO 5976 --- [ main] o.s.j.e.a.AnnotationMBe anExporter : Registering beans for JMX exposure on startup 2014-09-16 08:46:35.210 ERROR 5976 --- [ main] demo.Application : java.io.FileNotFoundException: class path resource [message. txt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/C:/Users/glyoder/Documents/workspace-sts-3.5.1.RELEASE/cl asspath-resource-problem/target/demo-0.0.1-SNAPSHOT.jar!/message.txt 2014-09-16 08:46:35.211 ERROR 5976 --- [ main] demo.Application : java.io.FileNotFoundException: class path resource [message. txt] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/C:/Users/glyoder/Documents/workspace-sts-3.5.1.RELEASE/cl asspath-resource-problem/target/demo-0.0.1-SNAPSHOT.jar!/message.txt 2014-09-16 08:46:35.215 INFO 5976 --- [ main] demo.Application : Started Application in 0.965 seconds (JVM running for 1.435) 2014-09-16 08:46:35.217 INFO 5976 --- [ Thread-2] s.c.a.AnnotationConfigA pplicationContext : Closing org.springframework.context.annotation.AnnotationCon figApplicationContext@1c77b086: startup date [Tue Sep 16 08:46:34 EDT 2014]; roo t of context hierarchy 2014-09-16 08:46:35.218 INFO 5976 --- [ Thread-2] o.s.j.e.a.AnnotationMBe anExporter : Unregistering JMX-exposed beans on shutdown


Jersey necesita ser jarras desempaquetados.

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <requiresUnpack> <dependency> <groupId>com.myapp</groupId> <artifactId>rest-api</artifactId> </dependency> </requiresUnpack> </configuration> </plugin> </plugins> </build>


Si está utilizando Spring Framework, entonces, la lectura de ClassPathResource en una String es bastante simple al usar FileCopyUtils Spring Framework :

String data = ""; ClassPathResource cpr = new ClassPathResource("static/file.txt"); try { byte[] bdata = FileCopyUtils.copyToByteArray(cpr.getInputStream()); data = new String(bdata, StandardCharsets.UTF_8); } catch (IOException e) { LOG.warn("IOException", e); }


Si quieres usar un archivo:

ClassPathResource classPathResource = new ClassPathResource("static/something.txt"); InputStream inputStream = classPathResource.getInputStream(); File somethingFile = File.createTempFile("test", ".txt"); try { FileUtils.copyInputStreamToFile(inputStream, somethingFile); } finally { IOUtils.closeQuietly(inputStream); }


También me encontré con esta limitación y creé esta biblioteca para solucionar el problema: spring-boot-jar-resources Básicamente, le permite registrar un ResourceLoader personalizado con Spring Boot que extrae los recursos classpath del JAR según sea necesario, de forma transparente.


cuando el proyecto de arranque de primavera se ejecuta como un contenedor y necesito leer algún archivo en classpath, lo implemento por debajo del código

Resource resource = new ClassPathResource("data.sql"); BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream())); reader.lines().forEach(System.out::println);


resource.getFile() espera que el recurso esté disponible en el sistema de archivos, es decir, no puede anidarse dentro de un archivo jar. Es por eso que funciona cuando ejecuta su aplicación en STS pero no funciona una vez que ha creado su aplicación y la ejecuta desde el contenedor ejecutable. En lugar de utilizar getFile() para acceder al contenido del recurso, recomendaría usar getInputStream() lugar. Eso te permitirá leer el contenido del recurso, independientemente de dónde esté ubicado.


to get list of data from src/main/resources/data folder -- first of all mention your folder location in properties file as - resourceLoader.file.location=data inside class declare your location. @Value("${resourceLoader.file.location}") @Setter private String location; private final ResourceLoader resourceLoader; public void readallfilesfromresources() { Resource[] resources; try { resources = ResourcePatternUtils.getResourcePatternResolver(resourceLoader).getResources("classpath:" + location + "/*.json"); for (int i = 0; i < resources.length; i++) { try { InputStream is = resources[i].getInputStream(); byte[] encoded = IOUtils.toByteArray(is); String content = new String(encoded, Charset.forName("UTF-8")); } } } catch (IOException e) { throw new UncheckedIOException(e); } }