Scenario is the following:
Developing a jsp application with jdeveloper
Deploying to Oracle Weblogic
All files are in the same project
Source files are inside packages that are inside the src folder
Inside the Resources folder are two files: menu.json and TestWS.properties
So, I made a java class that should read menu.json and return a menu (in html) based on its structure.
When, inside the class, I do this
InputStream i =
Thread.currentThread().getContextClassLoader().
getResourceAsStream("Resources/menu.json");
BufferedReader r = new BufferedReader(new InputStreamReader(i));
The InputStreamReader constructor throws a NullPointerException, I suppose because it can't find the file.
Funny thing is, if I try to load TestWS.properties instead, it loads it just well.
I tried checking the project's properties, manually added both files under Project Source Path -> Resources, adding the .json extension to Compiler -> Copy file types to output directory, renamed, deleted, recreated, changed extension to the json file, deployed to WAR and loaded the project on another machine running weblogic, but to no avail.
Is there anything else I'm missing?
This is explained in this article.
In short, you have to change the compiler setting "Copy File Types to Output Directory" to include the extension of the resources you want to have available at runtime.
Related
I'm trying to read a txt file that is in a folder called "levels". The class where I'm using the Scanner is in src/anotherPackageName, if that's relevant. When I execute:
Scanner s = new Scanner(new File("levels/level0")); //adding .txt doesn't fix
it throws an exception. I don't want to use an absolute path, but rather relative to the project if possible. This is my folder structure:
D:\OneDrive\Folder\AnotherFolder\ProjectName
ProjectName
src
packageOne
ClassWhereImUsingScanner
OtherClasses
(...)
levels
level0
level1
(...)
So in order to access a file you could do something like this:
FileReader sourceFile = new FileReader("levels/level0.txt");
BufferedReader inStream = new BufferedReader(sourceFile);
String Line = inStream.readLine();
Then, you can use a tokenizer depending on your data and how you want to store it.
You could see this example: http://www.mkyong.com/java/how-to-read-file-from-java-bufferedreader-example/
Bear in mind that in most Java code, the end state of the project is not run from the IDE, but rather from some production system (e.g. an app or a server). In that case, your development source code structure won't be available.
There are two main ways to read text files or other resources in Java: either you can find the path to the actual file, in which case you need to deal with possibly not running out of your development source tree, or else you need to find a way to bundle the text file into your project.
Most Java projects end up getting compiled into some kind of archive, either a JAR file or a WAR file (for web applications) or something like an Android APK. In most cases you can add your own text files into the project archive. (For example, in a Maven project, if you just put your text file in the src/main/resources folder it should be included in the compiled JAR.)
However, in this case, the text file is no longer a separate file on disk, but rather a blob of data inside an archive. You could unzip the archive to get an actual File object, but that's wasteful if all you actually need is to read the bytes.
Thus, the most common way that text files like this are read is by using the existing ClassLoader mechanism, which is what is reading the .class files from disk (or from an archive, or over the network, or whatever). The ClassLoader already knows how to load bytes that are "alongside" your compiled code, so you can just make use of that.
In your case, you should be able to do something like this:
Scanner scanner = new Scanner(
getClass().getResourceAsStream("/path/to/file.txt"));
In this case, the /path/to/file.txt path is relative to the path your class was loaded from. E.g. if your class is named my.package.Foo then the actual class bytes will be in a folder (either a filesystem folder or in a JAR file or something) named my/package/Foo.class -- in this case, the path/to/file.txt and my/package/Foo.class will be relative to the same root.
See the documentation on resources for more information.
Usually the path is relative to your execution, but it also depends on your project setup on eclipse, could you send more information about you directory structure?
Based on you structure try something like this:
Scanner s = new Scanner(new File("../levels/level0"));
I have completed a program in eclipse and now I would like to export it as a single runnable jar file. The program contains a resource folder with images and text files in it. This is located beneath the source folder.
The res file is not added to the build path however when I run the program in Eclipse it still works.
The thing that is confusing me is that the res file is being saved into the runnable jar file when I export it as I can open the Jar file with WinRar and I see the folder is there with all the objects in it. But when I run the problem it stops at the point that the resource folder is referenced. To add to my confusion when I manually copy and paste the res folder next to where the runnable jar file is saved and run the program it works exactly as it should do.
Now I know this is something to do with how I reference the files in my code. At the moment I have it like this
reader = new LineNumberReader(new FileReader("res/usernames.txt"));
This works exactly how I want and accesses the res folder without any exceptions - in Eclipse and when I move the resource folder next to the Jar file.
I would like it to work normally but without having a folder outside of the Jar file I would like it all encapsulated in one Jar file.
I did a lot of research and what seems to be a common fix - may I add I don't really know how it works but everyone seems to mention it - is to somewhere use:
myClass().getResource()
When I create a new FileReader it needs a String input however when I use myClass().getResource() it returns a resource and not a string. I also don't have a clue how it is meant to reference the resource folder. Should I move the resource folder into the source folder?
Does anyone know how I can reference the resource folder from within the runnable jar file?
Sorry for rambling question I know what I want for my final product but I'm getting confused by the build paths and referencing from within classes and I have searched online for a long time trying to figure it out.
Resources, when you deploy your software, are not deployed as files in a folder. They are packaged as part of the jar of your application. And you access them by retrieving them from inside the jar. The class loader knows how to retrieve stuff from the jar, and therefore you use your class's class loader to get the information.
This means you cannot use things like FileReader on them, or anything else that expects a file. The resources are not files anymore. They are bundles of bytes sitting inside the jar which only the class loader knows how to retrieve.
If the resources are things like images etc., that can be used by java classes that know how to access resource URLs (that is, get the data from the jar when they are given its location in the jar), you can use the ClassLoader.getResource(String) method to get the URL and pass it to the class that handles them.
If you have anything you want to do directly with the data in the resource, which you would usually do by reading it from a file, you can instead use the method ClassLoader.getResourceAsStream(String).
This method returns an InputStream, which you can use like any other InputStream - apply a Reader to it or something like that.
So you can change your code to something like:
InputStream is = myClass().getResourceAsStream("res/usernames.txt");
reader = new LineNumberReader( new InputStreamReader(is) );
Note that I used the getResourceAsStream() method from Class rather than ClassLoader. There is a little difference in the way the two versions look for the resource inside the jar. Please read the relevant documentation for Class and ClassLoader.
I have a problem, I want to list the files in "default" folder, this folder is in the resources folder :
-resources/languages/default/manyfiles
The second line throws a nullPointerException
InputStream in = getClass().getClassLoader().getResourceAsStream("languages/default/");
BufferedReader br = new BufferedReader(new InputStreamReader(in));
It seems I can't do this with a folder but only with a file. The problem is I can't use File because this is inside a jar.
EDIT : here the content of the jar :
http://www.mediafire.com/view/05u5w20xupt1mo1/javapbfolder.bmp
There is no standard way to list the contents of a folder. The reason is that there concept of a file system behind the class resource loading, just names/location of a resource.
It depends what you want to do, how to work around this. Possible solutions come to my mind:
Retrieve the URL from one resource in the directory. Extract the JAR file from the URL and open the JAR via the ZipFile class. This is "hacky" and may or may not work, depending on the platform you run and security settings.
Generate an index file when you pack the JAR that contains the list of the resources.
Put in a JAR into the resource, that you then open via ZipFile.
I am using Eclipse to create a Dynamic Web Project. My eclipse is in
/home/pc/eclipse
and My project is in /home/pc/workspace/MyWebProj
Now I placed the files in the above Project Directory. When I want to read any File from my code, It always searches the files in /home/pc/eclipse folder instead of /home/pc/workspace/MyWebProj, thus I am hardcoding the file path for time being.
Is there any configuration setting in Eclipse I am missing?
Please Suggest.
Thank You,
Tara Singh
I think what you need to do is read the file from the location of the javax.servlet.ServletContext of the Web Application. If you use getContextPath() you should get the working directory of the Web Application rather than the Java VM.
You could also try loading any files using the getResource and getResourceAsStream methods from the same class.
I was a little rushed when I wrote this so I will provide a little more info.
The best approach is to use the getResourceAsStream method. this allows you to access files within your webapp.
To get a file foo.txt from the root directory of the web application and print it to the response, you could do the following.
public class TestServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException
{
PrintWriter writer = response.getWriter();
// foo.txt is at the root directory of the web app
InputStream in = getServletContext().getResourceAsStream("/foo.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String text;
while ((text = reader.readLine()) != null) {
writer.println(text);
}
}
}
I'm not sure what these files are, or more specifically, what the most appropriate storage location would be, but traditionally the best method of IO in this case is via ClassLoading. You could create a source folder located at src/main/resources that would be included in the archive (jar, war, ear, etc.) assembly (i.e. these files would be included in the jar). You would then load these resources.
If a file is located directly in the package, it will also be included in the artifact assembly, and can be accessed by any class in the package's class loader, or by the default class loader with the package path (packages correspond to folders when an archive is built).
If you are using a maven assembly plugin, these resources files would be included automatically. If you're using something like Ant, you would probably need to include these files in a script step. Otherwise I think if you're simply building in Eclipse there's a wizard for including files.
Also, the likely reason for attempting to read files from the /home/pc/eclipse folder is because a system property like user.dir or user.home is being utitlized:
String filename = System.getProperty("user.dir") + System.getProperty("file.separator") + "file.txt";
don't know if it's what you are looking for, but you can set/change the "Working Directory" of each "Running configuration" pretty easily in Eclipse.
Go to the "Run Configurations" Dialog
Select your Project (or the specific running config)
Select the "Arguments" tab
In the lower part of the Window, you can now change the "Working Directory" of the running configuration.
Change it to /home/pc/workspace/MyWebProj and your App should work.
Although this might work, i suggest you should go through a SystemProperty variable. Just get the parent path of your file like this:
File myFile = new File(System.getProperty("com.myapp.myfile.property"));
Now you can reset / move the working dir and filename via the System Properties just by setting this keyword.
Hope it helps a bit ;)
I need to read a file in my code. It physically resides here:
C:\eclipseWorkspace\ProjectA\src\com\company\somePackage\MyFile.txt
I've put it in a source package so that when I create a runnable jar file (Export->Runnable JAR file) it gets included in the jar. Originally I had it in the project root (and also tried a normal sub folder), but the export wasn't including it in the jar.
If in my code I do:
File myFile = new File("com\\company\\somePackage\\MyFile.txt");
the jar file correctly locates the file, but running locally (Run As->Java Main application) throws a file not found exception because it expects it to be:
File myFile = new File("src\\com\\company\\somePackage\\MyFile.txt");
But this fails in my jar file. So my question is, how do I make this concept work for both running locally and in my jar file?
Use ClassLoader.getResourceAsStream or Class.getResourceAsStream. The main difference between the two is that the ClassLoader version always uses an "absolute" path (within the jar file or whatever) whereas the Class version is relative to the class itself, unless you prefix the path with /.
So if you have a class com.company.somePackage.SomeClass and com.company.other.AnyClass (within the same classloader as the resource) you could use:
SomeClass.class.getResourceAsStream("MyFile.txt")
or
AnyClass.class.getClassLoader()
.getResourceAsStream("com/company/somePackage/MyFile.txt");
or
AnyClass.class.getResourceAsStream("/com/company/somePackage/MyFile.txt");
If I have placed i file in a jar file, it only worked if and only if I used
...getResourceAsStream("com/company/somePackage/MyFile.txt")
If I used a File object it never worked. I got also the FileNotFound exception. Now, I stay with the InputStream object.