I am aware of getting the path of the jar that contains a specific class
<ClassName>.class.getProtectionDomain().getCodeSource().getLocation()
This is well explored in other SO questions.
My question is :
"How to get the path of the JAR file in the classpath given ONLY the JAR FILE NAME.
If you are looking to find the path to the currently running jar, try this
new File("", jarName);
If you are looking for something else in the classpath, you could use the same strategy, assuming that they are in the same directory as the jar.
However, if you have set the classpath, either by command line or in the manifest, it might be a little bit more complicated.
This is an example that I found on some website:
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
This will get a list of absolute URLs that point to everything that has been loaded. All that you have to do is do url.getFile()
Say I have an exported Jar file on my Desktop, and then a folder I want to access so my jar file can load files from it. How can I access that folder without hard coding the path?
See here: https://stackoverflow.com/a/6849255/514463
Pick one of your classes that you want the directory of, e.g.: Test:
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
If I clearly understand, you may use relative path when you try to access folder. For example, if you run your jar as a standalone application, relative path "." will be a folder that contains your jar. So, when you place names.txt file next to your jar, you can get access to it with:
new File("./names.txt");
Hope I understood you right way and this will help.
The following code should provide the directory containing the JAR file:
URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
File directory = new File(url.toURI()).getParentFile();
Hmmm...
I heard this question so often, and it always boils down to this: How to load resources at runtime?
The main reason for this type of question is, that one is developping an application and now wants to create a distributable package. This normally ends in something like that:
... / my-application-folder
| -- lib / *.jar
| -- main.jar
| -- config.properties
There could be several configuration files. A configuration for the application itself, a configuration for a logging framework that is used, etc. It does not matter. If you want to access such resources, you should do it in two steps:
1) Make sure all folders containing your resources (such configuration files are resources) are part of the classpath. If you run your JAR file (here main.jar) with a java -jar main.jar command, this JAR file should contain a manifest file containing the directory . and all needed library JARs in the class-path entry. [Alternative: Maybe all your config files are located in a config/ subfolder. Then this folder must be part of the class-path.]
2) Inside your application you access such resources with a class loader:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
URL url = loader.getResource(neededResource);
// do something with url, e.g. open stream, read from it, and close stream
If you have a user customizable path, there are several possibilities. You could for example pass a system property to the application, as Reddy suggested in his comment. You could also have a property in a configuration file, which you are loading in the beginning part of your application. However, you have the path to this customizable folder in hand (at runtime). Then you do the following:
String customizablePath = getCustomizablePath();
URL customizablePathURL = new File(customizablePath).toURI().toURL();
ClassLoader loader = new URLClassLoader(new URL[] {customizablePathURL});
Then you can continue like above.
File f = new File("Folder")
This File object points to "Folder" directory in the the working directory of the Jar.
I have an issue with path names in my code. Let's say I have a main class:
com.test.LoadFile.java
Similarly I have a myxml.xml file under com.test. Meaning that the Java file and XML file are under same package.
Can somebody suggest how, when I do (inside LoadFile)
File file = new File("???/myxml.xml")
What should the path be, to support both:
Eclipse IDE code (after including the above code into a single Java project)
and
Run the main LoadFile class outside of the IDE (in a JAR file)
What should I use as the value of the path variable to include in the generated project JAR?
You can read the XML file using getResourceAsStream(), as long as it's in the CLASSPATH:
InputStream is = LoadFile.class.getClassLoader().getResourceAsStream("/myxml.xml");
EDIT: If you are packaging into a .jar, you must specify the complete path of the resource from the jar's root folder using "/" at the beginning of string
I have a Java project in Netbeans. It runs fine with Maven. So I assembled it. It contains the following code to load a file that is in the JAR:
ClassLoader loader = MyClass.class.getClassLoader();
SERVICE_URL = loader.getResource("my.wsdl");
This returns a URL like:
jar:file:/path/to/my/file/MyClass-1.0-SNAPSHOT-jar-with-dependencies.jar!/my.wsdl
but the library that needs this parameter doesn't appear to be able to use it.
Is there any way this file can be in the JAR and be referred to from the code like this?
You may have to use ClassLoader.getResourceAsStream(), copy it to a temporary file, and then create a URL with File.toURI().toURL()
In my Java app I need to get some files and directories.
This is the program structure:
./main.java
./package1/guiclass.java
./package1/resources/resourcesloader.java
./package1/resources/repository/modules/ -> this is the dir I need to get
./package1/resources/repository/SSL-Key/cert.jks -> this is the file I need to get
guiclass loads the resourcesloader class which will load my resources (directory and file).
As to the file, I tried
resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString()
in order to get the real path, but this way does not work.
I have no idea which path to use for the directory.
I had problems with using the getClass().getResource("filename.txt") method.
Upon reading the Java docs instructions, if your resource is not in the same package as the class you are trying to access the resource from, then you have to give it relative path starting with '/'. The recommended strategy is to put your resource files under a "resources" folder in the root directory. So for example if you have the structure:
src/main/com/mycompany/myapp
then you can add a resources folder as recommended by maven in:
src/main/resources
furthermore you can add subfolders in the resources folder
src/main/resources/textfiles
and say that your file is called myfile.txt so you have
src/main/resources/textfiles/myfile.txt
Now here is where the stupid path problem comes in. Say you have a class in your com.mycompany.myapp package, and you want to access the myfile.txt file from your resource folder. Some say you need to give the:
"/main/resources/textfiles/myfile.txt" path
or
"/resources/textfiles/myfile.txt"
both of these are wrong. After I ran mvn clean compile, the files and folders are copied in the:
myapp/target/classes
folder. But the resources folder is not there, just the folders in the resources folder. So you have:
myapp/target/classes/textfiles/myfile.txt
myapp/target/classes/com/mycompany/myapp/*
so the correct path to give to the getClass().getResource("") method is:
"/textfiles/myfile.txt"
here it is:
getClass().getResource("/textfiles/myfile.txt")
This will no longer return null, but will return your class.
It is strange to me, that the "resources" folder is not copied as well, but only the subfolders and files directly in the "resources" folder. It would seem logical to me that the "resources" folder would also be found under `"myapp/target/classes"
Supply the path relative to the classloader, not the class you're getting the loader from. For instance:
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
In the hopes of providing additional information for those who don't pick this up as quickly as others, I'd like to provide my scenario as it has a slightly different setup. My project was setup with the following directory structure (using Eclipse):
Project/
src/ // application source code
org/
myproject/
MyClass.java
test/ // unit tests
res/ // resources
images/ // PNG images for icons
my-image.png
xml/ // XSD files for validating XML files with JAXB
my-schema.xsd
conf/ // default .conf file for Log4j
log4j.conf
lib/ // libraries added to build-path via project settings
I was having issues loading my resources from the res directory. I wanted all my resources separate from my source code (simply for managment/organization purposes). So, what I had to do was add the res directory to the build-path and then access the resource via:
static final ClassLoader loader = MyClass.class.getClassLoader();
// in some function
loader.getResource("images/my-image.png");
loader.getResource("xml/my-schema.xsd");
loader.getResource("conf/log4j.conf");
NOTE: The / is omitted from the beginning of the resource string because I am using ClassLoader.getResource(String) instead of Class.getResource(String).
When you use 'getResource' on a Class, a relative path is resolved based on the package the Class is in. When you use 'getResource' on a ClassLoader, a relative path is resolved based on the root folder.
If you use an absolute path, both 'getResource' methods will start at the root folder.
#GianCarlo:
You can try calling System property user.dir that will give you root of your java project and then do append this path to your relative path for example:
String root = System.getProperty("user.dir");
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt
String abspath = root+filepath;
// using above path read your file into byte []
File file = new File(abspath);
FileInputStream fis = new FileInputStream(file);
byte []filebytes = new byte[(int)file.length()];
fis.read(filebytes);
For those using eclipse + maven. Say you try to access the file images/pic.jpg in src/main/resources. Doing it this way :
ClassLoader loader = MyClass.class.getClassLoader();
File file = new File(loader.getResource("images/pic.jpg").getFile());
is perfectly correct, but may result in a null pointer exception. Seems like eclipse doesn't recognize the folders in the maven directory structure as source folders right away. By removing and the src/main/resources folder from the project's source folders list and putting it back (project>properties>java build path> source>remove/add Folder), I was able to solve this.
resourcesloader.class.getClass()
Can be broken down to:
Class<resourcesloader> clazz = resourceloader.class;
Class<Class> classClass = clazz.getClass();
Which means you're trying to load the resource using a bootstrap class.
Instead you probably want something like:
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
If only javac warned about calling static methods on non-static contexts...
Doe the following work?
resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks")
Is there a reason you can't specify the full path including the package?
Going with the two answers as mentioned above. The first one
resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString();
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString()
Should be one and same thing?
In Order to obtain real path to the file you can try this:
URL fileUrl = Resourceloader.class.getResource("resources/repository/SSL-Key/cert.jks");
String pathToClass = fileUrl.getPath;
Resourceloader is classname here.
"resources/repository/SSL-Key/cert.jks" is relative path to the file. If you had your guiclass in ./package1/java with rest of folder structure remaining, you would take "../resources/repository/SSL-Key/cert.jks" as relative path because of rules defining relative path.
This way you can read your file with BufferedReader. DO NOT USE THE STRING to identify the path to the file, because if you have spaces or some characters from not english alphabet in your path, you will get problems and the file will not be found.
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(fileUrl.openStream()));
I made a small modification on #jonathan.cone's one liner ( by adding .getFile() ) to avoid null pointer exception, and setting the path to data directory. Here's what worked for me :
String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next();
Use this:
resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**
One of the stable way to work across all OS would be toget System.getProperty("user.dir")
String filePath = System.getProperty("user.dir") + "/path/to/file.extension";
Path path = Paths.get(filePath);
if (Files.exists(path)) {
return true;
}