I am trying to read a .json file I am packaging with my .jar.
The problem - finding the file so that I can parse it in.
The strange bit is that this code works in NetBeans, likely due to the way these methods work and the way NetBeans handles the dev workspace. When I build the jar and run it, however, it throws an ugly error: Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical.
My code for getting the file is as such:
//get json file
File jsonFile = new File(AndensMountain.class.getResource("/Anden.json").toURI());
FileReader jsonFileReader;
jsonFileReader = new FileReader(jsonFile);
//load json file
String json = "";
BufferedReader br = new BufferedReader(jsonFileReader);
while (br.ready()) {
json += br.readLine() + "\n";
}
I have gotten it to work if I allow it to read from the same directory as the jar, but this is not what I want - the .json is in the jar and I want to read it from in the jar.
I've looked around and as far as I can see this should work but it isn't.
If you are interested, this is the code before trying to get it to read out of the jar (which works as long as Anden.json is in the same directory as AndensMountain.jar):
//get json file
String path = AndensMountain.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
File jsonFileBuilt = new File(new File(path).getParentFile(), "Anden.json");
File jsonFileDev = new File(new File(path), "Anden.json");
FileReader jsonFileReader;
try {
jsonFileReader = new FileReader(jsonFileBuilt);
} catch (FileNotFoundException e) {
jsonFileReader = new FileReader(jsonFileDev);
}
Try
Reader reader = new InputStreamReader(AndensMountain.class.getResourceAsStream("/Anden.json"), "UTF-8");
AndensMountain.class.getResource("/Anden.json") URL when ran outside a jar (for example, when the classes are compiled to a "classes/" directory) is a "file://" URL.
That is not the case when ran from inside a jar: it then becomes a "jar://" URL.
The java.io.File doesn't know how to handle this type of URL. It handles only "file://".
Anyway you don't really need to treat it as a File. You can manipulate the URL itself (either to navigate to a parent directory, for example) or to get its contents (via openStream(), or if you need to add headers, via openConnection()).
java.lang.Class#getResourceAsStream() as I suggested is just shorthand to Class#getResource() followed by openStream() on its result.
Related
Here is my project structure
DejaVuu
-- src/main/java
---- views
------ basetheme.css
-- src/test/java
-- src
-- basetheme.css
-- tempfile.css
Currently I am trying to read in my css file with
view.getStylesheets().add("basetheme.css");
But this does not work. However, it works when I use
view.getStylesheets().add("views/basetheme.css");
I need basetheme.css at the root because that is where
I rewrite the file to after some updates. In other words,
the read and write location should be the same.
Here is the code I call to write to the file:
public String writeToCSS(String css) throws IOException {
String path_name = "basetheme.css"; // I need this to match read in for getStyleSheet().add
File temp = new File(path_name);
temp.delete();
temp.createNewFile();
BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
bw.write("some css");
bw.close();
String temp_url = temp.toURI().toString();
return temp_url;
}
Now when looking in writeToCSS and the following is set
String path_name = "basetheme.css";
the above writing works. This is to root of project.
The issue is that now I cannot read the stylesheet into
JavaFX from this location.
With that said, I have tried to write the file to
String path_name = "/home/ming/eclipse-workspace/DejaVuu/views/basetheme.css";
However, I receive an error when doing this
java.io.IOException: No such file or directory
java.io.UnixFileSystem.createFileExclusively(Native Method)
java.io.File.createNewFile(File.java:1012)
Can File not be used to write to packages in MavenProjects?
I am using eclipse for reading a jsonfile. I put the jsonfile in my src->main->java->testjson->jsonfile.json . Now I am trying to read the jsonfile. But my progam cannot find the file. I get the output "nothing". Here is the code I already implement:
JsonParser parser = new JSONParser();
try{
Object obj = parser.parse(new FileReader("jsonfile.json"));
JSONObject jsonObject = (JSONObject) obj;
String name = (String) jsonObject.get("name");
}
catch(Exception e){
System.out.println("nothing");
}
Your file within the project is called a "resource", which will be bundled in the resulting jar-file.
In maven projects such files resides in a special folder resources (like src/main/resources/testjson/jsonfile.json), in many other project types, these files are located directly beneath the java files.
Therefore you cannot read it with FileReader, because it will not be a regular file, but zipped inside the jar file.
All you have to do is to read the file with this.getClass().getResourceAsStream("/testjson/jsonfile.json").
Your parser should be capable to read from an InputStream instead of a Reader.
If not, utilize an InputStreamReader with the correct encoding (JSON files should be UTF-8, but that depends...)
Code:
try (InputStream is = this.getClass().getResourceAsStream("/testjson/jsonfile.json"); ) {
Object obj = parser.parse(is);
} catch (Exception ex) {
System.out.println("failed to read: "+ex.getMessage());
}
Code if parser does not support InputStream:
try (InputStream is = this.getClass().getResourceAsStream("/testjson/jsonfile.json");
Reader rd = new InputStreamReader(is, "UTF-8"); ) {
Object obj = parser.parse(rd);
} catch (Exception ex) {
System.out.println("failed to read: "+ex.getMessage());
}
As you're saying that you use Eclipse, i assume you also run your code via Eclipse.
As a default, the working directory when executing a Java program in Eclipse is the root folder of the project.
Therefore, I suggest to put your jsonfile.json in the root folder of your project instead of src/main/....
Furthermore, you should not catch Exception. Catch more specific like IOExceptionor JSONException and then print the exception message (e.getMessage()), then it is much easier to solve the problem.
The file "countries.geo.json" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable.
You have to use the data folder as a source.
if Images not appear. Click on this links to see the images
Right-Click on the data folder
You then see Buid path option
Click on "Use as a source folder"
Give the full path to the JSON file instead of the file name.
If the file path is home/src/main/java/testjson/jsonfile.json
String path = "home/src/main/java/testjson/jsonfile.json";
Object obj = parser.parse(new FileReader(path));
I am trying to update a JSON file on my server resources folder in response to a form submission to my api endpoint.
I want to update my QueryMap.json from the controller QueryMapController.java
#CrossOrigin
#RequestMapping("/newQuery")
public String newQuery(#RequestParam("qid") String qid, #RequestParam("query") String query) throws Exception{
String fileName="QueryMap.json";
File file = new ClassPathResource(fileName).getFile();
JSONParser parser = new JSONParser();
FileReader fr = new FileReader(file);
Object ob = parser.parse(fr);
fr.close();
JSONArray arr = (JSONArray)ob;
JSONObject newob = new JSONObject();
newob.put("Query_id",qid);
newob.put("Query",query);
arr.add(newob);
FileWriter fw = new FileWriter(file.getAbsoluteFile(),false);
BufferedWriter out = new BufferedWriter(fw);
out.write(arr.toJSONString());
out.flush();
out.close();
fw.close();
return arr.toJSONString();
}
The above code is the Controller Method I want to use to update my .json file.
Apparently Everything seems to work. It works without errors and the program executes as if the file is updated but the actual file is not changed. As I restart the server the changes are gone. It seems the file is cached somewhere internally during runtime. How should I handle this.
Pardon my Custom Data Connection and writing code like this which doesn't strictly follow MVC guidelines. It has reasons behind to code this way.
tl;dr Place files you want to modify outside of your classpath because they are overwritten with the ones in your <projectDir>/src/main/resources directory when you build/package your project. If you want to see code for this check the end of the answer.
The reason this happens is most likely because when you restart your server, your project is re-build. During this process every class is re-compiled and the compiled classes are placed in a separate directory, along with all the resources (<projectDir>/target/classes/ when using maven). This replaces your changed version of the json file with the original one from your <projectDir>/src/main/resources directory.
You can verify this by debugging your newQuery Method and following these steps:
Check the location of your json file with File.getAbsolutePath(). For me it is <projectDir>/target/classes/QueryMap.json.
Check the content of the file, it should be in its original state.
Let your code do the changes, then re-check the file content. The changes should be there.
Stop the server and re-build your project (With maven mvn clean package).
The file content should be in its original state again, because the build process replaced <projectDir>/target/classes/QueryMap.json with <projectDir>/src/main/resources/QueryMap.json.
One solution to this would be to use the json file on your class path as a default and copy it to the current working directory where you can change it any way you want:
File editableQueryMap = new File("./QueryMap.json");
if (!editableQueryMap.exists()) {
File defaultQueryMap = new ClassPathResource("QueryMap.json").getFile();
try (OutputStream os = Files.newOutputStream(editableQueryMap.toPath())) {
Files.copy(defaultQueryMap.toPath(), os);
}
}
//do your changes with editableQueryMap here
For me, this puts the editable QueryMap.json file in the root of my project directory. If you use a jar file, it should place the file in the same directory as the jar (unless the working directory is changed).
im Working on a project that can compile/run existing java files in PC.
most of code works pretty well, but im having a problem at getting the path of java files.
here are the problematic codes
void uploadJ() {
System.out.print("Insert File name : "); //ex)HelloWorld.java
FileName = sc.next();
}
void Compile(){
String s = null;
File file = new File(FileName);
String path = file.getAbsolutePath();
try {
Process oProcess = new ProcessBuilder("javac", path).start();
BufferedReader stdError = new BufferedReader(
new InputStreamReader(oProcess.getErrorStream()));
while ((s = stdError.readLine()) != null) {
FileWriter fw = new FileWriter(E_file, true);
fw.write(s);
fw.flush();
fw.close();
}
} catch...
}
For instance, when i put HelloWorld.java as a file name,
the absolute path of the HelloWorld.java should be C:\Users\user\eclipse-
workspace\TermProject\src\HelloWorld.java,
but instead, the result is C:\Users\user\eclipse-
workspace\TermProject\HelloWorld.java.
it misses /src/ so it always ends up with javac: file not found error.
When your application has been compiled, there will be no src directory. This working directory could also be set to anything.
You also can't guarantee that the file you are looking for is an actual file, in the context of a jar file, it isn't.
However, you can load files from the classpath. You can make use of Class#getResourceAsStream(String):
Finds a resource with a given name. The rules for searching resources associated with a given class are implemented by the defining class loader of the class.`.
Finding the file can be accomplished by calling this.getClass().getResourceAsStream("/" + FileName), with the / causing the search to occur from the resource root.
To use this with javac, you'll have to create a temporary file and populate it with the data stream you get from getResourceAsStream.
This may be a stupid question, but I have to ask because I couldn't find any proper solution.
I am new to Eclipse. I created a Dynamic Web project in Eclipse, In this, I write a simple code to create a text file, Only file name is specified Not the path that where to create, After successful execution, i could not find my text file in my project folder.
If path is specified in the code, I can find the text file in specified directory, My Question is where i can find my text file if i am not specify a path ?
And my code is
try {
FileWriter outFile = new FileWriter("user_details.txt", true);
PrintWriter out1 = new PrintWriter(outFile);
out1.append(request.getParameter("un"));
out1.println();
out1.append(request.getParameter("pw"));
out1.close();
outFile.close();
System.out.println("file created");
} catch(Exception e) {
System.out.println("error in writing a file"+e);
}
I edited my code with following lines,
String path = new File("user_details.txt").getAbsolutePath();
System.out.println(path);
The path that i got is below
D:\Android\eclipse_JE\eclipse\user_details.txt
Why i got it in the eclipse folder ?
Then,
How can i create a text file in my web app, if this is not the right way to create a textfile ?
The file is located in the actual working directory of your application server. Do a
System.out.println(new File("").getAbsolutPath());
and you'll find the location.
However this is not a good idea to write files in web application like this, because first you never know where it is and second you never know whether you write privilege on it.
You need to specify some filesystem root for your application by passing it as init-parameter and use it as parent for everything you need to do on the filesystem. Check this answer to a similar Question.
You could then create your file like this:
String fsroot = getServletContext().getInitParameter("fsroot")
File ud = new File(fsroot, "user_details.txt");
FileWriter outFile = new FileWriter(ud, true);
You may try the getAbsolutePath() method.
String newFile = new File("Demo.txt").getAbsolutePath();
It will show the location where the files will be created.