Here is my problem.
My package setup is:
-src
---- foo
-------- code.java
---- foo.data
-------- files I need to access
Currently I have a jar that contains all of the above files I need to access. I will be running this code on my machine and send File objects initialized on my machine to another machine with the same jar running.
My question is how can I obtain a relative path to the data file so when I send the File objects to the other machine they know to look in the jar?
I need to access the data file so I can perform methods on it. Therefore I need to create a new File(relative/path/to/jar/data/files) with it and then I will be passing the File objects to another computer to compute.
Currently I have been able to use getClass().getResource("data/" + "filename").getPath() this gives me a path like file:/pathtojar!/pathtofileinjar/ which I think will be able to find the jar in the other machine but I am getting null pointer when trying to use the item in the jar. Are files in jar able to be used or is there a workaround for it?
Why not send the relative path of the file in the jar, instead of the File?
The other program can then use that path and read the data from the jar.
Could you try with the absolute path, like so:
package resourcetest;
import java.net.URL;
public class ResourceTest {
public static void main(String[] args) {
new ResourceTest().test();
}
private void test() {
URL res = this.getClass().getResource("/data/data.txt");
System.out.println(res);
}
}
Here my data file that i want to access is data/data.txt
src\resourcetest\ResourceTest.class (this class runs and tries to access data/Data.txt
src\data\Data.txt
Related
I have written a project where some images are used for the application's appearance and some text files will get created and deleted along the process. I only used the absolute path of all used files in order to see how the project would work, and now that it is finished I want to send it to someone else. so what I'm asking for is that how I can link those files to the project so that the other person doesn't have to set those absolute paths relative to their computer. something like, turning the final jar file with necessary files into a zip file and then that the person extracts the zip file and imports jar file, when runs it, the program work without any problems.
by the way, I add the images using ImageIcon class.
I'm using eclipse.
For files that you just want to read, such as images used in your app's icons:
Ship them the same way you ship your class files: In your jar or jmod file.
Use YourClassName.class.getResource or .getResourceAsStream to read these. They are not files, any APIs that need a File object can't work. Don't use those APIs (they are bad) - good APIs take a URI, URL, or InputStream, which works fine with this.
Example:
package com.foo;
public class MyMainApp {
public void example() {
Image image = new Image(MyMainApp.class.getResource("img/send.png");
}
public void example2() throws IOException {
try (var raw = MyMainApp.class.getResourceAsStream("/data/countries.txt")) {
BufferedReader in = new BufferedReader(
new InputStreamReader(raw, StandardCharsets.UTF_8));
for (String line = in.readLine(); line != null; line = in.readLine()) {
// do something with each country
}
}
}
}
This class file will end up in your jar as /com/foo/MyMainApp.class. That same jar file should also contain /com/foo/img/send.png and /data/countries.txt. (Note how starting the string argument you pass to getResource(AsStream) can start with a slash or not, which controls whether it's relative to the location of the class or to the root of the jar. Your choice as to what you find nicer).
For files that your app will create / update:
This shouldn't be anywhere near where your jar file is. That's late 80s/silly windows thinking. Applications are (or should be!) in places that you that that app cannot write to. In general the installation directory of an application is a read-only affair, and most certainly should not be containing a user's documents. These should be in the 'user home' or possibly in e.g. `My Documents'.
Example:
public void save() throws IOException {
Path p = Paths.get(System.getProperty("user.home"), "navids-app.save");
// save to that file.
}
This is what I've tried:
String myPath = myStaticClass.class.getResource("en-us").getPath();
// returns C:/Users/Charles/Workspace/ProjectName/target/classes/
My resources are in C:/Users/Charles/Workspace/ProjectName/src/main/resources
Does anyone know why this is happening?
Edit:
I suppose I should have mentioned that the path is being used in a library to load resources, but is failing.
That is where your compiled code is put when you use maven to build your project. Your resources are being copied to the target/classes folder as part of the build process.
If you then deploy your application to another location, you will find that your code will return the new path to the resource.
Edit
As per your comment, try using the following to load your resource:
InputStream resourceStream = myStaticClass.class.getClassLoader().getResourceAsStream("en-us");
This uses the current class's class loader to locate and provide an InputStream to your resource.
When you run mvn compile, one of the steps along the way is to copy your resources directory to the target/classes directory. Now usually if you call myStaticClass.class.getResource, the path you pass in will have target/classes as the root. So lets say you have a file at src/main/resources/my.file.txt You will be able to get it by calling myStaticClass.class.getResource("/my.file.txt");
The thing you're probably forgetting is the "/" there. Without that "/", it will look relative to your class' directory.
Alternatively, you could do this: ClassLoader.getSystemClassLoader().getResource("my.file.txt").getPath(). Notice the lack of a slash.
You are asking why this is happening and you are saying you want to load the resources.
The "why": see the other posts. No reason to duplicate them here.
The "how": the following code shows how to load the resources. Assuming they are in a file called "your.resources" and that this file is in the classpath; which, according to your post, it is.
import java.io.IOException;
import java.util.Properties;
public class Test {
public Test() throws IOException
{
final Properties properties = new Properties();
properties.load(this.getClass().getResourceAsStream("your.resources"));
System.out.println(properties);
}
public static void main(String[] args) throws IOException {
new Test();
}
}
Note that you don't need to provide the full path of the resources. As long as they are in the classpath, this will find them.
Play 2.2.3. Windows 7.
public static Result menu() throws IOException {
String path = Play.application().resource("resources/menu.json").toString();
String content = Files.toString(new File(path), Charsets.UTF_8);
return ok(content).as("JSON");
}
Got an error:
... scala-2.10\classes\resources\menu.json The filename, directory
name, or volume label syntax is incorrect
Checking that path in file-system, I'm able to find my file there:
..\target\scala-2.10\classes\resources\menu.json
I'm able to find it there. Why play can't?
--
UPDATE:
I've just figured out I can not create files on C:\ root folder on my machine. That maybe the issue. But on other hand I'm not accessing root folder, and ad trying to get read only access. And I do have write access to that file on that path anyway.
As actually you want to use your menu.json file as a static asset you can put it i.e. into public/resources/menu.json file and then read it with simple:
<script>
$.get('#routes.Assets.at("resources/menu.json")');
</script>
or just directly by request:
http://localhost:9000/assets/resources/menu.json
To do what you want via controller you need to read the InputStream by classpath (remember that finally it will be archived into jar file!) but it need to be placed in conf folder i.e.: conf/resources/menu.json then from controller:
public static Result menuViaControllerJson() {
InputStream is = Play.application().classloader().getResourceAsStream("resources/menu.json");
return (is != null)
? ok(is)
: notFound();
}
Anyway you will get exactly the same result as for common Assets.at, so consider if it's worth of effort.
Edit: If you want to use this file as custom config just use HOCON syntax file i.e.: conf/ses.conf:
foo = "bar"
and in controller:
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
....
Config cfg = ConfigFactory.parseResources(Play.application().classloader(), "ses.conf");
debug("My 'foo' is configured as: " + cfg.getString("foo"));
I am trying to explore Apache commons configuration to dynamically load the property file and do modification in the file and save it.
I wrote a demo code for the same.
Code Snippet
package ABC;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
public class Prop {
public static void main(String[] args)
{
try {
URL propertiesURL = Prop.class.getResource("/d1.properties");
if (propertiesURL == null) {
System.out.println("null");
}
String absolutePath=propertiesURL.getPath();
PropertiesConfiguration pc = new PropertiesConfiguration(absolutePath);
pc.setReloadingStrategy(new FileChangedReloadingStrategy());
String s=(String)pc.getProperty("key_account_sales");
System.out.println("s is " + s);
pc.setAutoSave(true);
pc.setProperty("key_account_sales", "Dummy");
pc.save();
System.out.println("Modified as well");
String sa=(String)pc.getProperty("key_account_sales");
System.out.println("s is " + sa);
}catch(ConfigurationException ce)
{
ce.printStackTrace();
}
}
}
Although when I run the code multiple times, the updated value for the property is being properly shown but the changes are not seen in the Property file.
I tried refreshing the entire workspace and the project but still the property file shows the previous entry whereas this code displays the updated entry in console.
Why my property file is not getting updated?
Well I noticed that a new file with same name was formed inside bin
directory of my IDE workspace. This new file contains the required
changes.
However I still want that the old file should be updated with the new
value and instead of creating a new file, it should update in the old
file itself.
My property file is located inside a Web Application package say
Dem1
by the name of
Prop1.prop
I want to read this property file from in another class say
Reading.java
located inside another package
Dem2
, do changes in this same property file and show it to another user. It is a web application being deployed on an application server.
Even after using the absolute path in a simple file (main function) it is not reflecting the changes in the same file but updating it in new file.
I am doing a very slight mistake but can someone please help.
Using absolute path I am not able to make changes in the same property file in normal main method also. Please suggest.
New file in bin directory is created instead of updating the same file
in src folder.
You should be able to solve this using absolute paths. The PropertiesConfiguration class is finding your properties file somewhere on the classpath and only knows to write back to "d1.properties"; hence you have a file appearing in your bin directory.
The absolute path can be obtained by querying resources on the classpath. Something like the following:
URL propertiesURL = Prop.class.getResource("/d1.properties");
if (propertiesURL == null) {
// uh-oh...
}
String absolutePath = propertiesURL.getPath();
// Now use absolutePath
I have searched for hours and I am not finding a solution, this is my last resort
I have a program that creates a data file via serialization, and the file is created successfully, and I can read the data (Deserialization) using the same program/ package.
The problem I have is that the data file must be read from another program and I have created the same class but I cannot read from the file (Class not found error) from a different program
//Class
public static class
{
File inst_path = ....
}
So I created an external class so that I can create the data file from the same class and read using the same class. The class is saved as a jar file
How can I link both programs to the same class (External File)
Edit
Currently I am accessing my local these way
records.classes myclass = new records.classes()
myclass.inst_path = new File...
So I am looking for something that will look something like ...
externaljar.jar.classes myclass = new ...
I know this won't work but I need something like it.
You just need the jar to be in the classpath of the two programs. Then you use the class as any other class: by importing it and using its name:
java -cp jarWithCommonSerializedClass.jar;jarWithTheProgramClasses.jar the.program.MainClass
Note: this is for Windows. Under *nix, : must be used instead of ;.
See http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html.
Also, respect the Java naming conventions. Java classes start with an upper-case letter. Variables never contain underscores and are camelCased.