Getting the inputstream from a classpath resource (XML file) - java

In Java web application, Suppose if I want to get the InputStream of an XML file, which is placed in the CLASSPATH (i.e. inside the sources folder), how do I do it?

ClassLoader.getResourceAsStream().
As stated in the comment below, if you are in a multi-ClassLoader environment (such as unit testing, webapps, etc.) you may need to use Thread.currentThread().getContextClassLoader(). See http://stackoverflow.com/questions/2308188/getresourceasstream-vs-fileinputstream/2308388#comment21307593_2308388.

ClassLoader.class.getResourceAsStream("/path/file.ext");

That depends on where exactly the XML file is. Is it in the sources folder (in the "default package" or the "root") or in the same folder as the class?
In for former case, you must use "/file.xml" (note the leading slash) to find the file and it doesn't matter which class you use to try to locate it.
If the XML file is next to some class, SomeClass.class.getResourceAsStream() with just the filename is the way to go.

ClassLoader.class.getResourceAsStream("/path/to/your/xml") and make sure that your compile script is copying the xml file to where in your CLASSPATH.

someClassWithinYourSourceDir.getClass().getResourceAsStream();

Some of the "getResourceAsStream()" options in this answer didn't work for me, but this one did:
SomeClassWithinYourSourceDir.class.getClassLoader().getResourceAsStream("yourResource");

I tried proposed solution and forward slash in the file name did not work for me, example: ...().getResourceAsStream("/my.properties"); null was returned
Removing the slash worked: ....getResourceAsStream("my.properties");
Here is from doc API:
Before delegation, an absolute resource name is constructed from the given resource name using this algorithm:
If the name begins with a '/' ('\u002f'), then the absolute name of the resource is the portion of the name following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object with '/' substituted for '.' ('\u002e').

Related

Nested jar: URI

The format of the jar: URI scheme is simply defined to be jar:<url>!/[<entry>].
Is it possible to "nest" two such URIs together and refer to a file inside an archive inside an archive this way? Something like:
jar:jar:http://example.com/!/archive!/file
This should designate /file inside an archive jar:http://example.com/!/archive, that is /archive found in a file provided by http://example.com/. However, URL.openConnection throws an exception:
java.net.MalformedURLException: no !/ in spec
I also cannot replace ! with %21 since that makes the jar: URI invalid, and I am not aware of any escaping that could be performed. Is this somehow possible? Or, as a more generic question, is it possible to store a URI with !/ inside <url> so that it is preserved?
As it is stated in the source code java.net.JarURLConnection does not handle nested Jar URIs.
Your example jar:jar:http://example.com/!/archive!/fileis parsed as entry archive!/file in the archive jar:http://example.com/. The latter is not a valid jar URI. You can not either escape the !/ sequences, because the text after jar: and before !/ must be a valid URI without any translation.
You can of course provide your own URLConnection implementation that supports nested Jar URIs.
While the other answer is indeed correct in the case of JarURLConnection, the use of jar: and similar URIs is not restricted to it. Such is the case of the Apache Commons VFS:
jar:// arch-file-uri[! absolute-path]
Where arch-file-uri refers to a file of any supported type, including other zip files. Note: if you would like to use the ! as normal character it must be escaped using %21.
"Normal character" means usage of the character in path to the file inside the archive, not in the inner URI. This makes jar:jar:http://example.com/!/archive!/file valid, as it is the last occurence of ! that should be used as a delimiter.
Note that the inner URI should probably still remain unescaped, thus it is impossible to use # there.

Enrich body with data from a file

My exchange body contains a class with a string attribute with path to file with which the body need to be enriched. There another attribute to hold file after enriched. I failed to find a solution to build a dynamic route that will load a file and return result I could use in Aggregation Strategy.
When you use the file component, you have to specify a path to a directory which can't be dynamic. You can only specify patterns on files in the directory.
Extract from the camel-file doc:
Camel supports only endpoints configured with a starting directory. So
the directoryName must be a directory. If you want to consume a single
file only, you can use the fileName option, e.g. by setting
fileName=thefilename. Also, the starting directory must not contain
dynamic expressions with ${ } placeholders. Again use the fileName
option to specify the dynamic part of the filename
Could you give us more info on what your are trying to achieve, so that we can give you workarounds ?

Merging two relative file URLs

Let' say I have two paths, first can look like folder/ and second like /anotherFolder/image.png. I would like to merge those two paths in some automated fashion and with option for user to omit the last slash in first string and first slash in second string. So all of these
folder/ + /anotherFolder/image.png
folder + anotherFolder/image.png
folder + /anotherFolder/image.png
should give me folder/anotherFolder/image.png
I need to merge two properties in one of my projects and I want it as dummy as possible:)So is there some trick with URL class or do I have to play around with Strings?
You can do this with java.io.File, by using the constructor which takes a File and a String as arguments, will interpret the String as a relative path to the File.
Or with java.net.URL, you can send an URL and a String to the constructur, which will interpret the URL as a context for the String parameter.
I actually used FileUtils.getFile() from Apache Commons IO but Rolf's solution was working too.

Apache VFS resolveFile with regex

If I have a directory called temp with the following files:
a_file1.jpg
a_file2.jpg
b_file1.jpg
b_file2.jpg
It's possible to get all files like this:
VFS.getManager().resolveFile("temp").getChildren();
But, what I actually want to do is get a_file1.jpg and a_file2.jpg. Maybe like:
VFS.getManager().resolveFile("temp/a*").getChildren();
But this throws an exception:
org.apache.commons.vfs.FileSystemException: Could not list the contents of "temp/a*" because it is not a folder.
So, does anyone know how to resolve a set of files based on a regex with VFS?
You could use the findFiles method, with a FileFilterSelector.
You'll need to create your own FileFilter that accepts the files that match your desired regex.

Problem loading java properties

I am trying to load properties from a file (test.properties)
The code I use is as follows:
URL url = getClass().getResource("../resources/test.properties");
properties.load(url.openStream());
But when executing the second line I get a NPE. (null pointer exception)
I'm not sure what's wrong here... I have checked that the file exists at the location where URL points to...
Any help is appreciated....
The javadoc for Class.getResource(String) says:
Returns: a URL object or null if no resource with this name is found
Most likely, the problem is that getResource is not finding the resource it is looking for. I am very suspicious of the use of ".." in the resource name. The javadoc does not say that getResource treats "." or ".." path components as having special meaning.
It is also possible that properties is null ...
I could be wrong, but I don't believe you can use ".." like that in a call to getResource(). I suggest you try an "absolute" resource:
URL url = getClass().getResource("/path/to/resources/test.properties");
Is it perhaps the properties object that is null?
The answer to whether or not getResource will find your file depends on your system classloader. The classloader is called, but before the classloader is called, the following transformation is made on the string you pass in.
From the Class javadoc:
If the name begins with a '/' ('\u002f'), then the absolute name of
the resource is the portion of the name following the '/'.
Otherwise, the absolute name is of the following form:
modified_package_name/name
Where the modified_package_name is the package name of this object
with '/' substituted for '.' ('\u002e').
So, the question becomes: will the classloader you are using be able to resolve modified_package_name/../resources/test.properties?
getClass().getResource() resolves the resource relative to the given class. Try getClass().getClassLoader().getResource().
You can also use Apache's PropertiesConfiguration

Categories