Loading Xml files from class path in Spring Boot - java

I am trying to load and validate xml files from a directory in the class path at startup of a Spring Boot application. I am seeing the following error which indicates that I am trying to load files using absolute path and not class path:
java.io.FileNotFoundException: class path resource [converters/mapper.xml] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/opt/core/home/libexec/boss/core-service-2.0.0.jar!/BOOT-INF/lib/core-api-2.0.0.jar!/converters/mapper.xml
Below is a code snippet that loads the files:
..
#Autowired
public FieldsMapTypeConvertersRegistry(#Value("${core.files-location:converters}")
String mapperFilesLocation) {
this.mapperFilesLocation = mapperFilesLocation;
}
..
try {
// ToDo we need to replace this when we enable multi-tenancy
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(classLoader);
Resource[] xmlResources = resolver.getResources(mapperFilesLocation + "/*.xml");
for (Resource xmlResource : xmlResources) {
File file = ResourceUtils.getFile(xmlResource.getURL());
registerTypeConverter(file);
}
} catch (IOException e) {
// do stuff
} catch (JAXBException e) {
//do stuff
}
I think the issue is in this statement in the code above:
File file = ResourceUtils.getFile(xmlResource.getURL());
but I am not sure what other ways I can do that. Any help is really appreciated.

I'm just wondering why you are using ResourceUtils.getFile(xmlResource.getURL()) when xmlResource.getFile() is already available to get the File Handle. Ideally speaking, you should be catching the FileNotFoundException inside the catch block and checking the detailed message wrapped inside the exception.
Edit:
The exception is being thrown because the xml is not found in classpath at runtime. Most probably, the file target/converters/mapper.xml is not available.

Try something like this MyService.class.getClassLoader().getResourceAsStream("/file.xml"); and then create File from stream.

Try using commons-io:commons-io:2.7 (Maven artifact) and use the following code:
InputStream inputStream = obj.getClass()
.getClassLoader()
.getResourceAsStream("converters/mapper.xml");
String data = IOUtils.toString(inputStream, "UTF-8");

Related

FileNotFoundException while getting file from resources folder using getResource()

I need to get this file from the resources folder in the File object, not in InputSream.
I am using below code, working file on eclipse but FoleNotFoundException on the server. )Using AWS EC2)
Code:
URL res = ResidentHelperService.class.getClassLoader().getResource("key.pem");
System.out.println("resource path2 :" + res);
File privateKeyFile = Paths.get(res.toURI()).toFile();
After printing path looks like:
:jar:file:/home/centos/myproject/microservices/user-service/target/user-service-0.0.1-SNAPSHOT.jar!/BOOT-INF/lib/project-common-utility-0.0.1-SNAPSHOT.jar!/key.pem
I have added dependency on the common jar to user service pom.
Please help me to get the file from resources of a common project.
If you have your file in resources folder, the easiest way to access it from the code is probably to use org.springframework.util.ResourceUtils class that Spring provides:
try {
final File file = ResourceUtils.getFile("classpath:key.pem");
....
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Perhaps this way can help you with your issue.

Jar classpath resources read failing which is triggerred from other executable jar

With reference to the link: How do I read a resource file from a Java jar file?
I am trying using your code base and trying to read content of sample.csv which is residing in my project directory src/main/resources. I am unable to read the content, it says can not read file. Output:
[Can not read file: sample.csv]
//This is added within your while loop after this check /* If it is a directory, then skip it. */
I mean when file is detected then next is my below code snippet added to read the file content
if(entry.getName().contains("sample.csv")) {
File f1 = new File("sample.csv");
if(f1.canRead()) {
List<String> lines = Files.readAllLines(f1.toPath());
System.out.println("Lines in file: "+lines.size());
} else {
System.out.println("Can not read file: "+entry.getName());
}
}
Can anyone educate me what I am doing wrong here, how can I make it working?
My requirement is this:
(My micro-service) Service.jar imports Parser.jar library in its pom.xml
(My library) - Parser.jar has FnmaUtils-3.2-fieldMapping.csv file in src/main/resources directory
There is a FnmaUtils class that loads the FnmaUtils-3.2-fieldMapping.csv within its constructor, this class is part of Parser.jar - Here I am trying to read the content FnmaUtils-3.2-fieldMapping.csv, this step is keep failing with below error, tried all possible options shown in [How do I read a resource file from a Java jar file?
public FnmaUtils() {
String mappingFileUrl = null;
try {
Resource resource = new ClassPathResource("FnmaUtils-3.2-fieldMapping.csv");
mappingFileUrl = resource.getFile().getPath();
loadFnmaTemplate(mappingFileUrl);
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("Error loading fnma template file ", e);
}
}
Getting error:
java.io.FileNotFoundException: class path resource [`FnmaUtils-3.2-fieldMapping.csv`] cannot be resolved to absolute file path because it does not reside in the file system: `jar:file:/home/ravibeli/.m2/repository/com/xxx/mismo/util/fnma-parser32/2018.1.0.0-SNAPSHOT/fnma-parser32-2018.1.0.0-SNAPSHOT.jar!/FnmaUtils-3.2-fieldMapping.csv`
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:218)
at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:52)
at com.xxx.fnma.util.FannieMaeUtils.<init>(FannieMaeUtils.java:41)
at com.xxx.fnma.processor.FNMA32Processor.<init>(FNMA32Processor.java:54)
at com.xxx.fnma.processor.FNMA32Processor.<clinit>(FNMA32Processor.java:43)
What is going wrong here?
Try
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt");
Be sure the resource is in your classpath.

FileInputStream not working in web application

We are trying to read a property file in a servlet using fileInputStream.
However we are constanlty getting a file not found exception.
This is the piece of code we are using
Properties properties = new Properties();
File propertyFile = new File("config" + File.separatorChar + "abc.properties");
try {
FileInputStream propertyFileStream = new FileInputStream(propertyFile);
properties.load(propertyFileStream);
propertyFileStream.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
While using getResourceAsStream it is working fine.
However we need to understand why FileInputStream is not working.
We have placed the config\abc.properties file in the webInf. We have also tried placing it in the src folder(java classpath), the webContent folder, the WebInf\Classes folder but no success.
Resources are not files. They don't live in the file system and they cannot be accessed via File or FileInputStream.
You should be using Class.getResource().
Try by using
ResourceBundle resource = ResourceBundle.getBundle("test");
String VALUE1=resource.getString("KEY1");
String VALUE2=resource.getString("KEY2");
You should use this code to get resources on web application, because the path must be taken from ServletContext, I think that's what you're looking for, if you are inside Servlet:
InputStream is = getContext().getResourceAsStream("/WEB-INF/yourFolder/abc.properties");
to get the full path for your interest:
String fullPath = getContext().getRealPath("/WEB-INF/yourFolder/abc.properties");

Write a file in resources in a java maven project

I have to implement a temporary "persistence" solution for retrieving some definitions ( simple json strings). I have a rest endpoint which creates an instance of my object and then I want to write the json definition inside a file.
I currently have a class loader which loads files from the resources folder inside my module, I use these to grab the query results. Now I want to save a new definition, and write it to a file inside the resources folder.
However, I am unsuccessful in doing so. I grab the path from the existing file with the classloader and when I try to create a new file using FileUtils, it either throws some errors, or creates the file in D:.
Is there a way to use the resources folder to add/edit files at runtime ? Here is some code also with one of the many ways i've tried it.
public String writeDocument(String path, String content) throws IOException {
\\Example call: writeDocument("/definitions/somedefinition.txt",jsonStringHere);
\\where /definitions/somedefinition.txt is placed in /resources
ClassLoader classLoader = getClass().getClassLoader();
final URL url = classLoader.getResource(path);
final File file;
String finalPath = null;
try {
file = Paths.get(url.toURI()).toFile();
FileUtils.writeStringToFile(file, content);
finalPath = file.getAbsolutePath();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return finalPath;
}

File is not opening in java which is inside jar file

I tried to open file form my java application. Using following code from
Open PDF file on fly from Java application
Code:
if (Desktop.isDesktopSupported()) {
try {
File myFile = new File("/path/to/file.pdf");
Desktop.getDesktop().open(myFile);
} catch (IOException ex) {
// no application registered for PDFs
}
}
When I use path like :
"C:\\Users\\kalathoki\\Documents\\NetBeansProjects\\TestJava\\src\\files\\test.pdf"
it opens. But my file is inside my package
files/test.pdf
and I used
files\\test.pdf
it shows following exception:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: The file: \files\test.pdf doesn't exist.
Why? Any Idea... I want to include my file inside my jar file that can open from my application whenever user wants.
Thanks...
getDesktop#open only allows files to be opened from the file system. One solution is to keep the PDF file locally on the file system and read from there. This eliminates extracting the file from the JAR itself so is more efficient.
Unfortunately, you cannot load a file through Desktop that is contained in the jar.
However, you are not out of options. A great workaround is to create a temporary file and then open it as detailed here.
Good luck!
Assuming test.pdf is in the package files, try this:
File myFile = new File(getClass().getResource("/files/test.pdf").toURI());
This code is working properly please use this to open pdf file within jar file
try {
// TODO add your handling code here:
String path = jTextField1.getText();
System.out.println(path);
Path tempOutput = null;
String tempFile = "myFile";
tempOutput = Files.createTempFile(tempFile, ".pdf");
tempOutput.toFile().deleteOnExit();
InputStream is = getClass().getResourceAsStream("/JCADG.pdf");
Files.copy(is,tempOutput,StandardCopyOption.REPLACE_EXISTING);
if(Desktop.isDesktopSupported())
{
Desktop dTop = Desktop.getDesktop();
if(dTop.isSupported(Desktop.Action.OPEN))
{
dTop.open(tempOutput.toFile());
}
}
} catch (IOException ex) {}

Categories

Resources