Is it possible to get the file name which is being executed. Like e.g. If i am running a Jar file, and inside i want to add code functionality that can detect the file name so that if this jar is renamed, code should be able to detect that.
Is there any possibility of doing this without scanning the files in current directory?
Try this:
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
http://www.rgagnon.com/javadetails/java-0300.html
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getProtectionDomain()
http://docs.oracle.com/javase/7/docs/api/java/security/ProtectionDomain.html
you could check if System.getEnv() has some value indicating which file was invoked
Related
So I have a project, and this is one of the demands:
You should have a class named Project3, containing a main method.
This program reads the levels information from a file whose name is
specified as a command-line parameter (The file should also be
relative to the class-path as described here:)
All the file names specified in the levels and block definition files
should be relative to the class path. The reason we want them to be
relative to the class path is that later we will be able to read the
files from inside a jar, something we can not do with regular File
references.
To get an input stream relative to the class path (even if it's inside
a jar), use the following:
InputStream is =
ClassLoader.getSystemClassLoader().getResourceAsStream("image.png");
The idea is to keep a folder with files(definitions and images) and
then add that folder to the class path when running the JVM:
java -cp bin:resources ... If you don't add the resources folder to
you class path you wont be able to load them with the command from
above.
When run without parameters, your program should read a default level
file, and run the game accordingly. The location of the default level
file should be hard-coded in your code, and be relative to the
classpath_.
When run without parameters, your program should read a default level file, and run the game accordingly. The location of the default level file should be hard-coded in your code, and be relative to the classpath_.
The part of the code that handles the input is:
public Void run() throws IOException {
LevelReader level = new LevelReader();
List<level> chosenLevels = new ArrayList<>();
if (args.length >= 1) {
File f = new File(args[0]);
if (f.exists()) {
chosenLevels = level.makeLevel(args[0]);
}
}
if (chosenLevels.size() == 0) {
game.runLevels(defaultLevels);
} else {
game.runLevels(chosenLevels);
}
return null;
}
So my question is:
An argument should be the full path of a file which means:
D:\desktop\level3.txt
Is it possible to read a file from every location on my computer?
Because right now I can do it only if my text file is in the
project's directory (not even in the src folder).
I can't understand the rest of their demands. What does is mean "should be hard-coded in your code, and be relative to the
classpath_." and why is it related to InputStream method(?)
I'm confused all over this.
Thanks.
A classpath resource is not the same as a file.
As you have correctly stated, the full path of a file is something like D:\desktop\level3.txt.
But if ever want to distribute your application so it can run on other computers, which probably won’t have that file in that location, you have two choices:
Ask the user to tell the program where to find the file on their computer.
Bundle the file with the compiled program.
If you place a non-.class file in the same place as .class files, it’s considered a resource. Since you don’t know at runtime where your program’s class files are located,¹ you use the getResource or getResourceAsStream method, which is specifically designed to look in the classpath.
The getResource* methods have the additional benefit that they will work both when you are developing, and when the program is packaged as a .jar file. Individual entries in a .jar file are not separate files and cannot be read using the File or FileInputStream classes.
If I understand your assignment correctly, the default level file should be an application resource, and the name of that resource is what should be hard-coded in your program. Something like:
InputStream is;
if (args.length > 0) {
is = new BufferedInputStream(
new FileInputStream(args[0]));
} else {
// No argument provided, so use program's default level data.
is = ClassLoader.getSystemClassLoader().getResourceAsStream("defaultlevel.txt");
}
chosenLevels = level.makeLevel(is);
¹ You may find some pages that claim you can determine the location of a running program’s code using getProtectionDomain().getCodeSource(), but getCodeSource() may return null, depending on the JVM and ClassLoader implementation, so this is not reliable.
To answer your first question, it doesn't seem like they're asking you to read from anywhere on disk, just from within your class path. So that seems fine.
The second question, "What does is mean 'should be hard-coded in your code, and be relative to the classpath'?". You are always going to have a default level file in your project directory. Define the path to this file as a String in your program and that requirement will be satisfied. It's related to the InputStream because the stream requires a location to read in from.
I've been trying to set up a Scanner to use a File as an input, but it doesn't seem to recognize the filepath. The file exists in the same folder as my .java files.
File errorList = new File("Errors.txt");
Scanner errorIn = new Scanner(errorList);
This results in a FileNotFoundException.
What am I doing wrong, and how can I fix this?
One other approach you could try is, execute the below code in your eclipse (from any of your class), and see where the hello.txt is created, so you get an idea of where Java is looking for the file.
new File("hello.txt").createNewFile();
Then you could either put your Errors.txt in that location or provide the corresponding relative location.
I have a class XYZ in application that is executed as jar in any directory. I want to find the current directory path in which jar is executing for this I have used following code.
String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()
I write this code in public constructor of XYZ class but it is not working though I am using it since long time it works fine, but now it is not returning the current directory path.
please mark and suggest what is going wrong in this.
When you execute your statement within "this" - it means that you are trying to locate current instance of the class but you need to find the class itself.
In your case you can use this:
String path = XYZ.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
It will give you the path you are looking for and will solve issues with whitespaces and special characters inside this path.
In case you are doing this for Linux it might be useful to use:
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
...but now it is not returning the current directory path.
It shouldn't return the current directory path. It should return the path of the jar file the class is coming from, or the root folder where the class files are loaded from (if not packed in a jar). It might and it might not be the current folder.
Calling
this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath()
will try to locate the path the class of the current instance (this) is coming from.
Make sure that the Class you start from is part of the jar file. E.g. do not use this but use an explicit class which you're sure is from the jar file, e.g.
SomeClass.class.getProtectionDomain().getCodeSource().getLocation().getPath()
Also note that this won't work if you start the application from your IDE in which case the result would be the bin folder (the root folder of compiled class files).
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
OR
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath().toURI());
What I need to do is get the name of the running jar/exe file (it would be an EXE on windows, jar on mac/linux). I have been searching around and I can't seem to find out how.
How to get name of running Jar or Exe?
Hope this can help you, I test the code and this return you the full path and the name.
Maybe you want to play a little more with the code and give me some feed back.
File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
This was found on a similar but not == question on stackoverflow
How to get the path of a running JAR file?
File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
returns simple path in the compiled application and an error in jar:
URI is not hierarchical
My solution is:
private File getJarFile() throws FileNotFoundException {
String path = Main.class.getResource(Main.class.getSimpleName() + ".class").getFile();
if(path.startsWith("/")) {
throw new FileNotFoundException("This is not a jar file: \n" + path);
}
path = ClassLoader.getSystemClassLoader().getResource(path).getFile();
return new File(path.substring(0, path.lastIndexOf('!')));
}
File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
Should give you the jar.
as for the exe, as I'm assuming you're using some sort of wrapper, you'll need to know the name of the exe before it's run. Then you could use something like :
Process p = Runtime.getRuntime().exec
(System.getenv("windir") +"\\system32\\"+"tasklist.exe");
Try the following
System.getProperty("java.class.path")
Using Lunch4j you can add an image name for exe file by editing generated xml, you have to change tag value true from false to true
I have some text configuration file that need to be read by my program. My current code is:
protected File getConfigFile() {
URL url = getClass().getResource("wof.txt");
return new File(url.getFile().replaceAll("%20", " "));
}
This works when I run it locally in eclipse, though I did have to do that hack to deal with the space in the path name. The config file is in the same package as the method above. However, when I export the application as a jar I am having problems with it. The jar exists on a shared, mapped network drive Z:. When I run the application from command line I get this error:
java.io.FileNotFoundException: file:\Z:\apps\jar\apps.jar!\vp\fsm\configs\wof.txt
How can I get this working? I just want to tell java to read a file in the same directory as the current class.
Thanks,
Jonah
When the file is inside a jar, you can't use the File class to represent it, since it is a jar: URI. Instead, the URL class itself already gives you with openStream() the possibility to read the contents.
Or you can shortcut this by using getResourceAsStream() instead of getResource().
To get a BufferedReader (which is easier to use, as it has a readLine() method), use the usual stream-wrapping:
InputStream configStream = getClass().getResourceAsStream("wof.txt");
BufferedReader configReader = new BufferedReader(new InputStreamReader(configStream, "UTF-8"));
Instead of "UTF-8" use the encoding actually used by the file (i.e. which you used in the editor).
Another point: Even if you only have file: URIs, you should not do the URL to File-conversion yourself, instead use new File(url.toURI()). This works for other problematic characters as well.