JimFS: how to get File from Path - java

I started using google jimfs and I can't understand how I can get file from path. In source code I see that Path.toFile throws UnsupportedOperationException. But how then can I use it without files? For example if my application need to know if some path is folder or file.

The JSR 203 API has all the tools you need for that; and in this case, the Files class.
In spite of its name, it handles everything Path. For instance, you can use:
Files.isDirectory(thePath)
to test whether a file is a directory. But there are also other ways to test for the same thing.

Related

Can't get resources from jar

In my project i need to take jsons from folder located in resources. For it I implemented this method:
protected def getListOfJsonFromResources(path: String): List[String] = {
val source = Source.fromInputStream(Thread.currentThread().getContextClassLoader.getResourceAsStream(path))
println(source)
val list = source.getLines().map{file =>
Source.fromInputStream(Thread.currentThread().getContextClassLoader.getResourceAsStream(path + file))
.mkString
}.toList
source.close()
list
}
It's work fine in IDE but return nothing when I run my jar.
I know that problem is in val source as in jar it return empty iterator.
I tried already use this.getClass().getResourceAsStream(), this.getClass().getClassLoader().getResourceAsStream() and rewrite this method as java method.
I generate JAR in Idea (Build>Build Artifacts>Build). This files is inside JAR with correct path.
I use Apache Maven 3.6.3
My res folder: resources/folder/json/jsonFolder path:folder/json/jsonFolder/
How should I change this method to get list of jsons from given folder?
Thank, in advance.
The proper usage is actually MyClass.class.getResourceAsStream. After all, getClass().getRAS() would fail if your code is subclassed. However, I assume it isn't - so that change will improve the style of this code and future proof it, but it probably won't directly fix the issue.
What MyClass.class.getRAS does, is look in the exact same place that the MyClass.class file is at. For example, if you have a jar with:
META-INF/MANIFEST.MF
com/foo/app/MyClass.class
app-icon.png
com/foo/app/save.png
And you run MyClass, then MyClass.class.gRAS("save.png") will work out. As weill MyClass.class.gRAS("/app-icon.png") - note the leading slash.
Thus, if gRAS isn't working for you here, the conclusion is that you're either specifying the wrong path, or the file you need to be included with your app is not being included by your build tooling.
You haven't shown anything relevant from your build scripts, so there's not much to say about how to fix this. But I can give you the tools you need to debug the problem so you can fix it yourself, with this useful trick:
MyClass.class.getResource("MyClass.class")
works for any class. Print it (System.out.println the URL that falls out of the above call), and you will see the URL, which tells you exactly which of the no doubt many variants of MyClass is actually being used (by your IDE's build-on-save, by sbt's build tooling, in the jar file produced by sbt during the dist phase, and who knows how many more exist somewhere on disk!).
Now use standard computer tools (Mac: Finder, windows: Explorer, or just use the command line) to navigate to the actual location and check for the existence of this resource file. Note that jar files are just zip files; unzip -l somejar.jar is useful here.
If you see the file, well, now you know where that file is relative to MyClass.class, and now you know what to feed to the gRAS call. Note that .. is not a good idea; if it's not in the same dir as your class and not in any subdir, then use the leading slash to go off of the 'root' of the jar file or classpath root directory.
If you don't see the file, well, now you know that your build is broken. Search the web (or ask in a separate question here on SO) on how to fix that, and now you don't need to repeatedly build and run the entire app to figure it out; you can simply keep scanning the jar file produced by the build tool until the resource file shows up in the right spot.
NB: ClassLoader.getSystemCLassLoader.getResource, getThreadContext().getResource, getClass().getResource - these are all wrong. Don't do that. It'll probably also work, but it's more code and will break in various circumstances. MyClass.class.getResource does exactly what you want, is idiomatic, and is one of the shortest forms.

class.getClassLoader.getResource() returns null

Previously I built single jars with ant, for each application i wanted from my project and calling the application with java -jar application-name.
I have now moved to using gradle and having a single jar and call the applications with
java -cp fullpath-to-class.
Everything works as expected for all but one application where i now get a
null pointer exception trying to load the resources required.
If I move the files into the directory of the class which is looking for the files everything is good once again , but having them in a different directory seems to be problematical.
Have you any suggestions on the best approach to
A. debugging this effectivey
B. Having the file in a separate directory
Have you any suggestions on the best approach to A. debugging this effectively
Use jar -tvf ... to check that the missing resource is actually in the JAR file, and that it has the correct pathname in the JAR.file
Use a debugger, and set a breakpoint on the code that is trying to load the resource. Single step until you get to the point where you have the absolute resource path. Check it.
B. Having the file in a separate directory
Umm. I'm not sure what your actual problem is, but my guess is that it is to do with resolving relative resource pathnames. I suggest using absolute resource pathnames instead.
I guess the problem could be in the way you are building the JAR file, but you've not provided any concrete details of how you are doing that.

How do I access Java resources in a Grails project?

Grails newbie here. My application is in Grails, my IDE is IntelliJ IDEA. I configured my project (in IntelliJ) to say that my resources folder is under root\src\resources. I have an image file in there that I need to load into an InputStream / BufferedImage. However I can't seem to get to those resources from my Grails controller. This is what I was trying:
def image = this.getClass().getClassLoader().getResourceAsStream("image.png")
But that just returns null. I use this exact same convention in Java projects (well, except I have to declare image being of type InputStream), and it does work there. I was under the impression that I could essentially drop Java code in a Grails project and it should just work. What do I need to do differently to get this to work in my Grails controller? I need to access that static resource file.
If you mark a directory as a source directory in IntelliJ IDEA, Grails won't know about it. You have to configure Grails properly by either adding your new directory as a source directory or move the resource to one of the standard source directories.
I've never actually added a new source directory myself, but the answer to this stackoverflow question looks promising.
Other than that, you can just add resources to any source directory and it will be included, for example: grails-app/conf, src/java, src/groovy and more. In addition, any file in web-app/META-INF/classes will also be in the classpath of the application. The last one is great to know about if you need to copy a java or groovy source file (i.e. just copy, no compilation).
Try this
servletContext.getResourceAsStream("/WEB-INF/resources/yourfile")

find file location in java.io.FileNotFoundException

I have this Java application and I'm using an external Jar and one of the functions is throwing a java.io.FileNotFoundException. I have the file that it's looking for but I have no idea where I'm supposed to put it. Is there any program I can use that can give me the location of the path that it's trying to look at? Thanks.
if you run the application in a debugger, most debuggers allow you to break when an exception is thrown. you could then inspect the local state of the application to determine the relevant path.
you should also probably report this as an enhncement request to the original library author (to include the file name in the thrown exception).
Don't you have to the .class file of the Java class containing that method.If yes, decompile it to view the source code. This is one such decompiler
Also, try to look for any config file like a property file that may have the path information.
You can find the current working directory from System.getProperty("user.dir") and do some hit-trial by placing the file there.
If the exception stack does not give you a hint on where it is looking for the file, and placing it in common places e.g.
in user directory
home directory
current directory etc
does not work, I guess you can decompile the jar and see where it is looking for the file
Well, I doubt it is hardcoded so this will probably not show you exactly where it is looking...but you may want to decompile the class using JAD. This may clue you in on where it is looking.

Problem with resources location difference in eclipse and JARs

I wrote a program that is based completely on a single text file: I read the file, store the information, then search the information, etc. So, for the program to work, the file just has to be present and detectable by the program.
I use eclipse, so I put the file is in the default resources map (src/main/resources). At the start of my program I create the file:
private static File textFile = new File("src/main/resources/TEXT.TXT")
However, when I try to package my program using Maven, I get a JAR in which all class and resources files are present in the same folder; my program stops working since it cannot find the file anymore.
Any help on how to deal with this problem? I`d prefer a situation in which my program works in eclipse and as a JAR, but as a JAR only would be alright as well.
You can use ClassLoader.getResourceAsStream to load it from the classpath (or getResource to get the URL of the file).
Thread.currentThread().getContextClassLoader().getResource("TEXT.TXT")
This works as long as src/main/resources is on the classpath in eclipse. (The maven eclipse plugin includes it by default.) The file has to be in the jar file to work outside of eclipse.
Nice suggestions, this works perfect in eclipse itself: the correct location of the file is returned and I can use the file to do whatever I like.
When opening the program as a jar, there is still a problem. The getResource method returns a location that looks like the right one:
/something/something/something/something/workspace/program/target/program-0.0.1.jar!/TEXT.TXT.
However, when I convert this url to a string, use that string to create a file object and use this file object in my program, I get the following error:
java.io.FileNotFoundException: file:/something/something/something/something/workspace/program/target/program-0.0.1.jar!/TEXT.TXT (No such file or directory)
So, the getResource method does find the file, but the program somehow can't use it..

Categories