again I face a strange issue and hope someone here can help.
I have a spring boot backend module, what works in eclipse well and application is executeable when sta
I encountered this limitation too and created this library to overcome the issue: spring-boot-jar-resources
It basically allows you to register a custom ResourceLoader with Spring Boot that extracts the classpath resources from the JAR as needed, transparently:
new SpringApplicationBuilder()
.sources(Application.class)
.resourceLoader(new JarResourceLoader())
.run(args);
With that ResourceLoader you can do resource.getFile()
on any classpath resource.
Now I needed to find xmlFiles into a resource folder from a JAR and facing similar problems described here already. I would like to share my findings and how I got it work, maybe it is helpful.
In a jar I have "db-input" folder under src/main/resources with any number for xml-Files for DB-Input. My application is Spring-Based:
@Component
public class DatabaseInitializer implements InitializingBean {
@Autowired DomainConfigurationRepository repository;
@Autowired MarshallerService marshallerService;
@Autowired ApplicationContext context;
@Override
public void afterPropertiesSet() throws Exception {
final Resource[] resources = context.getResources("classpath*:db-input/*");
final Set<String> filePaths = findInputFileNames(resources);
final Set<DomainConfiguration> configurations = createConfigurations(filePaths);
repository.save(configurations);
}
private Set<DomainConfiguration> createConfigurations(final Set<String> filePaths) throws Exception {
final Set<DomainConfiguration> configurations = new HashSet<>();
for(final String path : filePaths){
final Resource resource = context.getResource(path);
final DomainConfigurationXO xoConfiguration = marshallerService.unmarshal(resource.getInputStream());
final DomainConfiguration configuration = PopulationUtils.getPopulatedConfiguration(xoConfiguration);
configurations.add(configuration);
}
return configurations;
}
public Set<String> findInputFileNames(final Resource[] inputDirectoryResources) throws IOException {
return Arrays.stream(inputDirectoryResources)
.map(resource -> extractURI(resource))
.collect(Collectors.toSet());
}
private String extractURI(Resource resource){
try {
return resource.getURI().toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Okay, already I found the real problem and the solution.
First, the application use the correct path to the csv files, but there is another issue when using an executable jar what I found under following link. Stackoverflow-Link
Before I come to issue with executable jar I used following solution for getting CSV-File (Issue is getFile()):
final List<String> resourceLines = FileReadUtils.readLines(specialisationResource.getFile());
for (final String line : resourceLines) {
data.add(getNewTransientSpecialisation(line));
}
But in executeable jar I cant use my resource as file, I need to use it as stream, see provided link above. So I needed to change my code. If you prefer using native java, you can do follows:
final InputStream inputStream = specialisationResource.getInputStream();
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
data.add(getNewTransientSpecialisation(line));
}
I prefer using frameworks and use apache commons like follows:
final List<String> resourceLines = IOUtils.readLines(specialisationResource.getInputStream());
for (final String line : resourceLines) {
data.add(getNewTransientSpecialisation(line));
}
So just remember, don't use File() for getting resource, always use stream do avoid that issue from beginning :-)
Hope that helps someone.