How to get File from spring Resource - java

I have a Resource object (org.springframework.core.io.ClassPathResource). I need to get File object, but resource.getFile() throws an exeption File not Found. but after invoking resource.getURI() I have a result
jar:file:/D: .... file.jar!/com//test/0be14958-3778-40bf-bd3e-ee605fcdd3f0/verify
Directory is located in jar file. Is it possible to workaround limitation for ClassPathResource and create a File object?
I've tried a new File(resource.getURI()) but it fails with java.lang.IllegalArgumentException: URI is not hierarchical
what is my fault?

I don't think it's possible to get a java.io.File out of something that's in a JAR (because it's not actually a file). From the ClassPathResource JavaDoc:
Supports resolution as java.io.File if the class path resource resides in the file system, but not for resources in a JAR.
You don't mention why you need it as a java.io.File, but maybe you can refactor your code to use the ClassPathResource.getInputStream method (which enables you to read the resource)?
Either that or you could also use ClassPathResource.getInputStream to copy the file you want to a temporary file on the file system that you could then use as a straight up java.io.File.
File temp = File.createTempFile("temp", ".tmp");
org.apache.commons.io.IOUtils.copy(resource.getInputStream(), new FileOutputStream(temp));

Related

How can you pack ObjectDB in a runnable JAR file?

I wanted to know if it is possible to include an ObjectDB database file .odb in a runnable JAR.
The method:
EntityManagerFactory emf = Persistence.createEntityManagerFactory(path);
takes a String path as an argument and not a URL. This means that getResource() does not work. Neither do getResource.getPath() and getResource.toString() work, since they somehow show a distorted path name and during runtime the database file is created outside the jar file.
So I was wondering if it is possible for the .odb file to be created inside the JAR and be manipulated within the JAR.
Why can't you copy your resource to temporary folder using for instance:
FileUtils.copyURLToFile()
(http://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/FileUtils.html#copyURLToFile%28java.net.URL,%20java.io.File%29)? And then you can use file path to copy.
Temporary system folder for current user you can find by:
File tempDir = new File(System.getProperty("java.io.tmpdir"));
An ObjectDB database must be a file and cannot be a resource within a file.
Following the solution of rsutormin seems as the right way to go.

Instancing a java.io.File to read a resource from classpath

Supposing that I've a project structure as follows:
+ src
---+ main
------+ java
------+ resources
How can I define a java.io.File instance that is able to read an xml from resources folder?
It depends on what your program's working directory is.
You can get your working directory at runtime via System.getProperty("user.dir");
Here's a link with more info
Once you've got that, create a relative filepath pointing to your resource folder.
For example, if your working directory is src, create a relative filepath like so:
new File(Paths.get("main","resources").toString());
There are weaknesses with this approach as the actual filepath you use may change when you deploy your application, but it should get you through some simple development.
No, use an InputStream, with the path starting under resources.
InputStream in = getClass().getResourceAsStrem("/.../...");
Or an URL
URL url = getClass().getResource("/.../...");
This way, if the application is packed in a jar (case sensitive names!) it works too. The URL in that case is:
"jar:file://... .jar!/.../..."
If you need the resource as file, for instance to write to, you will need to copy the resource as initial template to some directory outside the application, like System.getProperty("user.home").
Path temp = Files.createTempFile("pref", "suffix.dat");
Files.copy(getClass().getResourceAsStream(...), temp, StandardCopyOption.REPLACE_EXISTING);
File file = temp.toFile();
As #mjaggard commented, createTempFile creates an empty file,
so Files.copy will normally fail unless with option REPLACE_EXISTING.

URI scheme is not "file". Unable to read file from classpath

I have Java webapp and I am trying to read a file from classpth.
if (fileName == null){
fileName = Thread.currentThread().getContextClassLoader().getResource("config.properties");
}
objFile = new File(fileName.toURI());
I have config.properties in my classpath. WEB-INF/classes. When I inspect locally it gives: fileName.toURI(), it gives me file:/D:/dev/Tomcat_6_0/webapps/testApp/WEB-INF/classes/config.properties. And works fine.
Issue is on production linux server I am getting this path there vfsfile:/export/home/u/bin/jboss-5.1.0.BE/server/default/deploy/testApp.war/WEB-INF/classes/config.properties.
And I am getting following exception.
Caused by: java.lang.IllegalArgumentException: URI scheme is not "file"
at java.io.File.<init>(File.java:366)
at com.utils.ConfigLoader.loadConfigFilePath(ConfigLoader.java:87)
What is the workaround for handeling vfs?
You must not try to convert a resource from the classpath to a File. It may not even be a File if it's inside a WAR/JAR. The File class only represents filesystem objects.
Since you're loading resources (and they may be or may not be files, just imagine this properties file packed into jar/war), why don't you use openStream() on URL object? Then just read contents out of BufferedStream returned and that is it!

proper file path of a text file to read

I want to manipulate a file in my java program.The file to read must be paralled to my src folder.
What should I give as file path?
An elaborated example might help. From your question, what I get is,
Source Path : /home/user/project1/src/
File Path : /home/user/project1/src/
If this is the case, then once you build the project, the file path is not going to remain the same. So if you say that relative path for the file to open remains the same in built code, then you can use Class.getResourceAsStream(String path) which returns you the InputStream for given file. You can then construct the File object using it.
Refer this for details.
You should have a File object representing your src folder, and then create a new File object using that:
File textFile = new File(srcFolder, relativePath);
How you determine srcFolder really depends on the context.
EDIT: If you're just trying to read a file which is present at build time, you should include it in your built jar file and use either ClassLoader.getResourceAsStream or Class.getResourceAsStream to load it at execution time.
For example, if you have this structure:
src\
com\
xyz\
Foo.class
data\
input.txt
Then you could use Foo.class.getResourceAsStream("/data/input.txt") or Foo.class.getClassLoader.getResourceAsStream("data/input.txt"). Both will give you an InputStream you can use to load the data.

how to call jasper report on jsp page

When I call the jrxml file through .load(), its throw a exception FileNotfoundException.
I have tried with absolute path, but it does not work. Please help.
FileNotFoundException generally means the file is not there. Get the path from your code and paste it in you filesystem explorer and see if it exists.
If it does, it means it is for some reason inaccessible:
This exception will be thrown by the FileInputStream, FileOutputStream, and RandomAccessFile constructors when a file with the specified pathname does not exist. It will also be thrown by these constructors if the file does exist but for some reason is inaccessible, for example when an attempt is made to open a read-only file for writing.
You should always use absolute paths in Java IO stuff. Apparently the one you tried was plain wrong. Maybe you just guessed it based on the deploy location of the webapp. You shouldn't do that. If the jrxml file is actually located in the webcontent, then you can use ServletContext#getRealPath() to convert a relative web path to an absolute disk file system path which you in turn can use further in the usual Java IO stuff.
Assuming that file.jrxml is located in webcontent root (e.g. accessible by http://example.com/contextname/file.jrxml), here's an example:
String absolutePath = getServletContext().getRealPath("file.jrxml");
File file = new File(absolutePath);
It depends on how you give it the reference to the file. Looking at the documentation for the JRXmlLoader http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/xml/JRXmlLoader.html
you can see that you can pass it in a reference to a File object. You are probably just passing in a string and that might be wrong.
Try something like
String path = "/tmp/test.jrmxl";
File jrxmlFile = new File(path);
JasperDesign jasperDesign = JRXmlLoader.load(jrxmlFile);
with the appropriate try/catch and more and then debug on the file first before you worry about the loader.
You should probably get some of the jasperreports documentation. The books are quite good for that basic stuff.

Categories

Resources