How to get spring boot application jar parent folder path dynamically? - java

I have a spring boot web application which I run using java -jar application.jar. I need to get the jar parent folder path dynamically from the code. How can I accomplish that?
I have already tried this, but without success.

Well, what have worked for me was an adaptation of this answer.
The code is:
if you run using java -jar myapp.jar dirtyPath will be something close
to this: jar:file:/D:/arquivos/repositorio/myapp/trunk/target/myapp-1.0.3-RELEASE.jar!/BOOT-INF/classes!/br/com/cancastilho/service.
Or if you run from Spring Tools Suit, something like this:
file:/D:/arquivos/repositorio/myapp/trunk/target/classes/br/com/cancastilho/service
public String getParentDirectoryFromJar() {
String dirtyPath = getClass().getResource("").toString();
String jarPath = dirtyPath.replaceAll("^.*file:/", ""); //removes file:/ and everything before it
jarPath = jarPath.replaceAll("jar!.*", "jar"); //removes everything after .jar, if .jar exists in dirtyPath
jarPath = jarPath.replaceAll("%20", " "); //necessary if path has spaces within
if (!jarPath.endsWith(".jar")) { // this is needed if you plan to run the app using Spring Tools Suit play button.
jarPath = jarPath.replaceAll("/classes/.*", "/classes/");
}
String directoryPath = Paths.get(jarPath).getParent().toString(); //Paths - from java 8
return directoryPath;
}
EDIT:
Actually, if your using spring boot, you could just use the ApplicationHome class like this:
ApplicationHome home = new ApplicationHome(MyMainSpringBootApplication.class);
home.getDir(); // returns the folder where the jar is. This is what I wanted.
home.getSource(); // returns the jar absolute path.

File file = new File(".");
logger.debug(file.getAbsolutePath());
This worked for me to get the path where my jar is running, I hope this is what you are expecting.

Try this code
public static String getParentRealPath(URI uri) throws URISyntaxException {
if (!"jar".equals(uri.getScheme()))
return new File(uri).getParent();
do {
uri = new URI(uri.getSchemeSpecificPart());
} while ("jar".equals(uri.getScheme()));
File file = new File(uri);
do {
while (!file.getName().endsWith(".jar!"))
file = file.getParentFile();
String path = file.toURI().toString();
uri = new URI(path.substring(0, path.length() - 1));
file = new File(uri);
} while (!file.exists());
return file.getParent();
}
URI uri = clazz.getProtectionDomain().getCodeSource().getLocation().toURI();
System.out.println(getParentRealPath(uri));

Related

Java: Is there a way, how I can import a file which is in the same folder as the .jar? [duplicate]

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
My code runs inside a JAR file, say foo.jar, and I need to know, in the code, in which folder the running foo.jar is.
So, if foo.jar is in C:\FOO\, I want to get that path no matter what my current working directory is.
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getPath();
Replace "MyClass" with the name of your class.
Obviously, this will do odd things if your class was loaded from a non-file location.
Best solution for me:
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
This should solve the problem with spaces and special characters.
To obtain the File for a given Class, there are two steps:
Convert the Class to a URL
Convert the URL to a File
It is important to understand both steps, and not conflate them.
Once you have the File, you can call getParentFile to get the containing folder, if that is what you need.
Step 1: Class to URL
As discussed in other answers, there are two major ways to find a URL relevant to a Class.
URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
Both have pros and cons.
The getProtectionDomain approach yields the base location of the class (e.g., the containing JAR file). However, it is possible that the Java runtime's security policy will throw SecurityException when calling getProtectionDomain(), so if your application needs to run in a variety of environments, it is best to test in all of them.
The getResource approach yields the full URL resource path of the class, from which you will need to perform additional string manipulation. It may be a file: path, but it could also be jar:file: or even something nastier like bundleresource://346.fwk2106232034:4/foo/Bar.class when executing within an OSGi framework. Conversely, the getProtectionDomain approach correctly yields a file: URL even from within OSGi.
Note that both getResource("") and getResource(".") failed in my tests, when the class resided within a JAR file; both invocations returned null. So I recommend the #2 invocation shown above instead, as it seems safer.
Step 2: URL to File
Either way, once you have a URL, the next step is convert to a File. This is its own challenge; see Kohsuke Kawaguchi's blog post about it for full details, but in short, you can use new File(url.toURI()) as long as the URL is completely well-formed.
Lastly, I would highly discourage using URLDecoder. Some characters of the URL, : and / in particular, are not valid URL-encoded characters. From the URLDecoder Javadoc:
It is assumed that all characters in the encoded string are one of the following: "a" through "z", "A" through "Z", "0" through "9", and "-", "_", ".", and "*". The character "%" is allowed but is interpreted as the start of a special escaped sequence.
...
There are two possible ways in which this decoder could deal with illegal strings. It could either leave illegal characters alone or it could throw an IllegalArgumentException. Which approach the decoder takes is left to the implementation.
In practice, URLDecoder generally does not throw IllegalArgumentException as threatened above. And if your file path has spaces encoded as %20, this approach may appear to work. However, if your file path has other non-alphameric characters such as + you will have problems with URLDecoder mangling your file path.
Working code
To achieve these steps, you might have methods like the following:
/**
* Gets the base location of the given class.
* <p>
* If the class is directly on the file system (e.g.,
* "/path/to/my/package/MyClass.class") then it will return the base directory
* (e.g., "file:/path/to").
* </p>
* <p>
* If the class is within a JAR file (e.g.,
* "/path/to/my-jar.jar!/my/package/MyClass.class") then it will return the
* path to the JAR (e.g., "file:/path/to/my-jar.jar").
* </p>
*
* #param c The class whose location is desired.
* #see FileUtils#urlToFile(URL) to convert the result to a {#link File}.
*/
public static URL getLocation(final Class<?> c) {
if (c == null) return null; // could not load the class
// try the easy way first
try {
final URL codeSourceLocation =
c.getProtectionDomain().getCodeSource().getLocation();
if (codeSourceLocation != null) return codeSourceLocation;
}
catch (final SecurityException e) {
// NB: Cannot access protection domain.
}
catch (final NullPointerException e) {
// NB: Protection domain or code source is null.
}
// NB: The easy way failed, so we try the hard way. We ask for the class
// itself as a resource, then strip the class's path from the URL string,
// leaving the base path.
// get the class's raw resource path
final URL classResource = c.getResource(c.getSimpleName() + ".class");
if (classResource == null) return null; // cannot find class resource
final String url = classResource.toString();
final String suffix = c.getCanonicalName().replace('.', '/') + ".class";
if (!url.endsWith(suffix)) return null; // weird URL
// strip the class's path from the URL string
final String base = url.substring(0, url.length() - suffix.length());
String path = base;
// remove the "jar:" prefix and "!/" suffix, if present
if (path.startsWith("jar:")) path = path.substring(4, path.length() - 2);
try {
return new URL(path);
}
catch (final MalformedURLException e) {
e.printStackTrace();
return null;
}
}
/**
* Converts the given {#link URL} to its corresponding {#link File}.
* <p>
* This method is similar to calling {#code new File(url.toURI())} except that
* it also handles "jar:file:" URLs, returning the path to the JAR file.
* </p>
*
* #param url The URL to convert.
* #return A file path suitable for use with e.g. {#link FileInputStream}
* #throws IllegalArgumentException if the URL does not correspond to a file.
*/
public static File urlToFile(final URL url) {
return url == null ? null : urlToFile(url.toString());
}
/**
* Converts the given URL string to its corresponding {#link File}.
*
* #param url The URL to convert.
* #return A file path suitable for use with e.g. {#link FileInputStream}
* #throws IllegalArgumentException if the URL does not correspond to a file.
*/
public static File urlToFile(final String url) {
String path = url;
if (path.startsWith("jar:")) {
// remove "jar:" prefix and "!/" suffix
final int index = path.indexOf("!/");
path = path.substring(4, index);
}
try {
if (PlatformUtils.isWindows() && path.matches("file:[A-Za-z]:.*")) {
path = "file:/" + path.substring(5);
}
return new File(new URL(path).toURI());
}
catch (final MalformedURLException e) {
// NB: URL is not completely well-formed.
}
catch (final URISyntaxException e) {
// NB: URL is not completely well-formed.
}
if (path.startsWith("file:")) {
// pass through the URL as-is, minus "file:" prefix
path = path.substring(5);
return new File(path);
}
throw new IllegalArgumentException("Invalid URL: " + url);
}
You can find these methods in the SciJava Common library:
org.scijava.util.ClassUtils
org.scijava.util.FileUtils.
You can also use:
CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
Use ClassLoader.getResource() to find the URL for your current class.
For example:
package foo;
public class Test
{
public static void main(String[] args)
{
ClassLoader loader = Test.class.getClassLoader();
System.out.println(loader.getResource("foo/Test.class"));
}
}
(This example taken from a similar question.)
To find the directory, you'd then need to take apart the URL manually. See the JarClassLoader tutorial for the format of a jar URL.
I'm surprised to see that none recently proposed to use Path. Here follows a citation: "The Path class includes various methods that can be used to obtain information about the path, access elements of the path, convert the path to other forms, or extract portions of a path"
Thus, a good alternative is to get the Path objest as:
Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
The only solution that works for me on Linux, Mac and Windows:
public static String getJarContainingFolder(Class aclass) throws Exception {
CodeSource codeSource = aclass.getProtectionDomain().getCodeSource();
File jarFile;
if (codeSource.getLocation() != null) {
jarFile = new File(codeSource.getLocation().toURI());
}
else {
String path = aclass.getResource(aclass.getSimpleName() + ".class").getPath();
String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
jarFile = new File(jarFilePath);
}
return jarFile.getParentFile().getAbsolutePath();
}
If you are really looking for a simple way to get the folder in which your JAR is located you should use this implementation.
Solutions like this are hard to find and many solutions are no longer supported, many others provide the path of the file instead of the actual directory. This is easier than other solutions you are going to find and works for java version 1.12.
new File(".").getCanonicalPath()
Gathering the Input from other answers this is a simple one too:
String localPath=new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath()+"\\";
Both will return a String with this format:
"C:\Users\User\Desktop\Folder\"
In a simple and concise line.
I had the the same problem and I solved it that way:
File currentJavaJarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());
String currentJavaJarFilePath = currentJavaJarFile.getAbsolutePath();
String currentRootDirectoryPath = currentJavaJarFilePath.replace(currentJavaJarFile.getName(), "");
I hope I was of help to you.
Here's upgrade to other comments, that seem to me incomplete for the specifics of
using a relative "folder" outside .jar file (in the jar's same
location):
String path =
YourMainClassName.class.getProtectionDomain().
getCodeSource().getLocation().getPath();
path =
URLDecoder.decode(
path,
"UTF-8");
BufferedImage img =
ImageIO.read(
new File((
new File(path).getParentFile().getPath()) +
File.separator +
"folder" +
File.separator +
"yourfile.jpg"));
For getting the path of running jar file I have studied the above solutions and tried all methods which exist some difference each other. If these code are running in Eclipse IDE they all should be able to find the path of the file including the indicated class and open or create an indicated file with the found path.
But it is tricky, when run the runnable jar file directly or through the command line, it will be failed as the path of jar file gotten from the above methods will give an internal path in the jar file, that is it always gives a path as
rsrc:project-name (maybe I should say that it is the package name of the main class file - the indicated class)
I can not convert the rsrc:... path to an external path, that is when run the jar file outside the Eclipse IDE it can not get the path of jar file.
The only possible way for getting the path of running jar file outside Eclipse IDE is
System.getProperty("java.class.path")
this code line may return the living path (including the file name) of the running jar file (note that the return path is not the working directory), as the java document and some people said that it will return the paths of all class files in the same directory, but as my tests if in the same directory include many jar files, it only return the path of running jar (about the multiple paths issue indeed it happened in the Eclipse).
Other answers seem to point to the code source which is Jar file location which is not a directory.
Use
return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
the selected answer above is not working if you run your jar by click on it from Gnome desktop environment (not from any script or terminal).
Instead, I have fond that the following solution is working everywhere:
try {
return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
} catch (UnsupportedEncodingException e) {
return "";
}
I had to mess around a lot before I finally found a working (and short) solution.
It is possible that the jarLocation comes with a prefix like file:\ or jar:file\, which can be removed by using String#substring().
URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
For the jar file path:
String jarPath = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getPath();
For getting the directory path of that jar file:
String dirPath = new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getParent();
The results of the two lines above are like this:
/home/user/MyPrograms/myapp/myjar.jar (value of jarPath)
/home/user/MyPrograms/myapp (value of dirPath)
public static String dir() throws URISyntaxException
{
URI path=Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
String name= Main.class.getPackage().getName()+".jar";
String path2 = path.getRawPath();
path2=path2.substring(1);
if (path2.contains(".jar"))
{
path2=path2.replace(name, "");
}
return path2;}
Works good on Windows
I tried to get the jar running path using
String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();
c:\app>java -jar application.jar
Running the jar application named "application.jar", on Windows in the folder "c:\app", the value of the String variable "folder" was "\c:\app\application.jar" and I had problems testing for path's correctness
File test = new File(folder);
if(file.isDirectory() && file.canRead()) { //always false }
So I tried to define "test" as:
String fold= new File(folder).getParentFile().getPath()
File test = new File(fold);
to get path in a right format like "c:\app" instead of "\c:\app\application.jar" and I noticed that it work.
The simplest solution is to pass the path as an argument when running the jar.
You can automate this with a shell script (.bat in Windows, .sh anywhere else):
java -jar my-jar.jar .
I used . to pass the current working directory.
UPDATE
You may want to stick the jar file in a sub-directory so users don't accidentally click it. Your code should also check to make sure that the command line arguments have been supplied, and provide a good error message if the arguments are missing.
Actually here is a better version - the old one failed if a folder name had a space in it.
private String getJarFolder() {
// get name and path
String name = getClass().getName().replace('.', '/');
name = getClass().getResource("/" + name + ".class").toString();
// remove junk
name = name.substring(0, name.indexOf(".jar"));
name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');
// remove escape characters
String s = "";
for (int k=0; k<name.length(); k++) {
s += name.charAt(k);
if (name.charAt(k) == ' ') k += 2;
}
// replace '/' with system separator char
return s.replace('/', File.separatorChar);
}
As for failing with applets, you wouldn't usually have access to local files anyway. I don't know much about JWS but to handle local files might it not be possible to download the app.?
String path = getClass().getResource("").getPath();
The path always refers to the resource within the jar file.
Try this:
String path = new File("").getAbsolutePath();
This code worked for me to identify if the program is being executed inside a JAR file or IDE:
private static boolean isRunningOverJar() {
try {
String pathJar = Application.class.getResource(Application.class.getSimpleName() + ".class").getFile();
if (pathJar.toLowerCase().contains(".jar")) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
If I need to get the Windows full path of JAR file I am using this method:
private static String getPathJar() {
try {
final URI jarUriPath =
Application.class.getResource(Application.class.getSimpleName() + ".class").toURI();
String jarStringPath = jarUriPath.toString().replace("jar:", "");
String jarCleanPath = Paths.get(new URI(jarStringPath)).toString();
if (jarCleanPath.toLowerCase().contains(".jar")) {
return jarCleanPath.substring(0, jarCleanPath.lastIndexOf(".jar") + 4);
} else {
return null;
}
} catch (Exception e) {
log.error("Error getting JAR path.", e);
return null;
}
}
My complete code working with a Spring Boot application using CommandLineRunner implementation, to ensure that the application always be executed within of a console view (Double clicks by mistake in JAR file name), I am using the next code:
#SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) throws IOException {
Console console = System.console();
if (console == null && !GraphicsEnvironment.isHeadless() && isRunningOverJar()) {
Runtime.getRuntime().exec(new String[]{"cmd", "/c", "start", "cmd", "/k",
"java -jar \"" + getPathJar() + "\""});
} else {
SpringApplication.run(Application.class, args);
}
}
#Override
public void run(String... args) {
/*
Additional code here...
*/
}
private static boolean isRunningOverJar() {
try {
String pathJar = Application.class.getResource(Application.class.getSimpleName() + ".class").getFile();
if (pathJar.toLowerCase().contains(".jar")) {
return true;
} else {
return false;
}
} catch (Exception e) {
return false;
}
}
private static String getPathJar() {
try {
final URI jarUriPath =
Application.class.getResource(Application.class.getSimpleName() + ".class").toURI();
String jarStringPath = jarUriPath.toString().replace("jar:", "");
String jarCleanPath = Paths.get(new URI(jarStringPath)).toString();
if (jarCleanPath.toLowerCase().contains(".jar")) {
return jarCleanPath.substring(0, jarCleanPath.lastIndexOf(".jar") + 4);
} else {
return null;
}
} catch (Exception e) {
return null;
}
}
}
Something that is frustrating is that when you are developing in Eclipse MyClass.class.getProtectionDomain().getCodeSource().getLocation() returns the /bin directory which is great, but when you compile it to a jar, the path includes the /myjarname.jar part which gives you illegal file names.
To have the code work both in the ide and once it is compiled to a jar, I use the following piece of code:
URL applicationRootPathURL = getClass().getProtectionDomain().getCodeSource().getLocation();
File applicationRootPath = new File(applicationRootPathURL.getPath());
File myFile;
if(applicationRootPath.isDirectory()){
myFile = new File(applicationRootPath, "filename");
}
else{
myFile = new File(applicationRootPath.getParentFile(), "filename");
}
Not really sure about the others but in my case it didn't work with a "Runnable jar" and i got it working by fixing codes together from phchen2 answer and another from this link :How to get the path of a running JAR file?
The code:
String path=new java.io.File(Server.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.getPath())
.getAbsolutePath();
path=path.substring(0, path.lastIndexOf("."));
path=path+System.getProperty("java.class.path");
Have tried several of the solutions up there but none yielded correct results for the (probably special) case that the runnable jar has been exported with "Packaging external libraries" in Eclipse. For some reason all solutions based on the ProtectionDomain do result in null in that case.
From combining some solutions above I managed to achieve the following working code:
String surroundingJar = null;
// gets the path to the jar file if it exists; or the "bin" directory if calling from Eclipse
String jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()).getAbsolutePath();
// gets the "bin" directory if calling from eclipse or the name of the .jar file alone (without its path)
String jarFileFromSys = System.getProperty("java.class.path").split(";")[0];
// If both are equal that means it is running from an IDE like Eclipse
if (jarFileFromSys.equals(jarDir))
{
System.out.println("RUNNING FROM IDE!");
// The path to the jar is the "bin" directory in that case because there is no actual .jar file.
surroundingJar = jarDir;
}
else
{
// Combining the path and the name of the .jar file to achieve the final result
surroundingJar = jarDir + jarFileFromSys.substring(1);
}
System.out.println("JAR File: " + surroundingJar);
The above methods didn't work for me in my Spring environment, since Spring shades the actual classes into a package called BOOT-INF, thus not the actual location of the running file. I found another way to retrieve the running file through the Permissions object which have been granted to the running file:
public static Path getEnclosingDirectory() {
return Paths.get(FileUtils.class.getProtectionDomain().getPermissions()
.elements().nextElement().getName()).getParent();
}
Mention that it is checked only in Windows but i think it works perfect on other Operating Systems [Linux,MacOs,Solaris] :).
I had 2 .jar files in the same directory . I wanted from the one .jar file to start the other .jar file which is in the same directory.
The problem is that when you start it from the cmd the current directory is system32.
Warnings!
The below seems to work pretty well in all the test i have done even
with folder name ;][[;'57f2g34g87-8+9-09!2##!$%^^&() or ()%&$%^##
it works well.
I am using the ProcessBuilder with the below as following:
🍂..
//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath= new File(path + "application.jar").getAbsolutePath();
System.out.println("Directory Path is : "+applicationPath);
//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2##!$%^^&()`
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();
//...code
🍂getBasePathForClass(Class<?> classs):
/**
* Returns the absolute path of the current directory in which the given
* class
* file is.
*
* #param classs
* #return The absolute path of the current directory in which the class
* file is.
* #author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
*/
public static final String getBasePathForClass(Class<?> classs) {
// Local variables
File file;
String basePath = "";
boolean failed = false;
// Let's give a first try
try {
file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
basePath = file.getParent();
} else {
basePath = file.getPath();
}
} catch (URISyntaxException ex) {
failed = true;
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (1): ", ex);
}
// The above failed?
if (failed) {
try {
file = new File(classs.getClassLoader().getResource("").toURI().getPath());
basePath = file.getAbsolutePath();
// the below is for testing purposes...
// starts with File.separator?
// String l = local.replaceFirst("[" + File.separator +
// "/\\\\]", "")
} catch (URISyntaxException ex) {
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (2): ", ex);
}
}
// fix to run inside eclipse
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
basePath = basePath.substring(0, basePath.length() - 4);
}
// fix to run inside netbeans
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
basePath = basePath.substring(0, basePath.length() - 14);
}
// end fix
if (!basePath.endsWith(File.separator)) {
basePath = basePath + File.separator;
}
return basePath;
}
This code worked for me:
private static String getJarPath() throws IOException, URISyntaxException {
File f = new File(LicensingApp.class.getProtectionDomain().().getLocation().toURI());
String jarPath = f.getCanonicalPath().toString();
String jarDir = jarPath.substring( 0, jarPath.lastIndexOf( File.separator ));
return jarDir;
}
The getProtectionDomain approach might not work sometimes e.g. when you have to find the jar for some of the core java classes (e.g in my case StringBuilder class within IBM JDK), however following works seamlessly:
public static void main(String[] args) {
System.out.println(findSource(MyClass.class));
// OR
System.out.println(findSource(String.class));
}
public static String findSource(Class<?> clazz) {
String resourceToSearch = '/' + clazz.getName().replace(".", "/") + ".class";
java.net.URL location = clazz.getResource(resourceToSearch);
String sourcePath = location.getPath();
// Optional, Remove junk
return sourcePath.replace("file:", "").replace("!" + resourceToSearch, "");
}
I have another way to get the String location of a class.
URL path = Thread.currentThread().getContextClassLoader().getResource("");
Path p = Paths.get(path.toURI());
String location = p.toString();
The output String will have the form of
C:\Users\Administrator\new Workspace\...
The spaces and other characters are handled, and in the form without file:/. So will be easier to use.

No Such File exception in Runnable Jar file

I am trying to create a runnable jar file. My project includes models.txt file. My project works perfectly in eclipse with no error but when exported to a runnable jar file, It doesn't work. I hereby attach the error and the piece of code where the file is been called.
public static HashMap<String, RenderModel> getModelList(String file) throws IOException {
List<String> data;
HashMap<String, RenderModel> namesToModels = new HashMap<String, RenderModel>();
if (file != null) {
data = Files.readAllLines(Paths.get(file), StandardCharsets.UTF_8);
} else {
String path = "models/models.txt";
data = Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8);
}
Iterator<String> dataIterator = data.iterator();
while (dataIterator.hasNext()) {
String dataLine = dataIterator.next();
System.out.println(dataLine);
String[] line = dataLine.split("; ");
String key = line[0];
String valueObj = line[1];
String valueMtl = line[2];
float scale = Float.parseFloat((String) line[3]);
RenderModel v = new RenderModel(valueObj, valueMtl, scale);
namesToModels.put(key, v);
}
RenderModel v = new RenderModel("custom", "custom", 1.0f);
namesToModels.put("Choose Model from file", v);
return namesToModels;
}
Error Image:
If the files are in the Jar and you cannot read them, try accessing the files by doing:
getClass().getClassLoader().getResource(fileName);
Use this instead for static methods:
ClassName.class.getClassLoader().getResource(fileName);
Where fileName is the name of the file and ClassName the name of the class from which the statement is called.
In your code the path of the model.txt is 'src/models/model.txt'. When your project is packaged the src folder is not included usually. Then you must change the file location; could be better put the file outside the jar, but inside the java classpath.
It does not work because you do not have any file on the path src/models/models.txt when you run your jar else where, this path is only present in your IDE (ofcourse you can place your jar in a location from where it can reach that path, but this is not how it is supposed to be), when you package your project into a jar file it is packed in the package models and you can if you want to have it as default file read it via classpath.

How do I print the working directory on the server? [duplicate]

I want to access my current working directory using Java.
My code:
String currentPath = new java.io.File(".").getCanonicalPath();
System.out.println("Current dir:" + currentPath);
String currentDir = System.getProperty("user.dir");
System.out.println("Current dir using System:" + currentDir);
Output:
Current dir: C:\WINDOWS\system32
Current dir using System: C:\WINDOWS\system32
My output is not correct because the C drive is not my current directory.
How to get the current directory?
Code :
public class JavaApplication {
public static void main(String[] args) {
System.out.println("Working Directory = " + System.getProperty("user.dir"));
}
}
This will print the absolute path of the current directory from where your application was initialized.
Explanation:
From the documentation:
java.io package resolve relative pathnames using current user directory. The current directory is represented as system property, that is, user.dir and is the directory from where the JVM was invoked.
See: Path Operations (The Java™ Tutorials > Essential Classes > Basic I/O).
Using java.nio.file.Path and java.nio.file.Paths, you can do the following to show what Java thinks is your current path. This for 7 and on, and uses NIO.
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current absolute path is: " + s);
This outputs:
Current absolute path is: /Users/george/NetBeansProjects/Tutorials
that in my case is where I ran the class from.
Constructing paths in a relative way, by not using a leading separator to indicate you are constructing an absolute path, will use this relative path as the starting point.
The following works on Java 7 and up (see here for documentation).
import java.nio.file.Paths;
Paths.get(".").toAbsolutePath().normalize().toString();
This will give you the path of your current working directory:
Path path = FileSystems.getDefault().getPath(".");
And this will give you the path to a file called "Foo.txt" in the working directory:
Path path = FileSystems.getDefault().getPath("Foo.txt");
Edit :
To obtain an absolute path of current directory:
Path path = FileSystems.getDefault().getPath(".").toAbsolutePath();
* Update *
To get current working directory:
Path path = FileSystems.getDefault().getPath("").toAbsolutePath();
Java 11 and newer
This solution is better than others and more portable:
Path cwd = Path.of("").toAbsolutePath();
Or even
String cwd = Path.of("").toAbsolutePath().toString();
This is the solution for me
File currentDir = new File("");
What makes you think that c:\windows\system32 is not your current directory? The user.dir property is explicitly to be "User's current working directory".
To put it another way, unless you start Java from the command line, c:\windows\system32 probably is your CWD. That is, if you are double-clicking to start your program, the CWD is unlikely to be the directory that you are double clicking from.
Edit: It appears that this is only true for old windows and/or Java versions.
Use CodeSource#getLocation().
This works fine in JAR files as well. You can obtain CodeSource by ProtectionDomain#getCodeSource() and the ProtectionDomain in turn can be obtained by Class#getProtectionDomain().
public class Test {
public static void main(String... args) throws Exception {
URL location = Test.class.getProtectionDomain().getCodeSource().getLocation();
System.out.println(location.getFile());
}
}
this.getClass().getClassLoader().getResource("").getPath()
generally, as a File object:
File getCwd() {
return new File("").getAbsoluteFile();
}
you may want to have full qualified string like "D:/a/b/c" doing:
getCwd().getAbsolutePath()
I'm on Linux and get same result for both of these approaches:
#Test
public void aaa()
{
System.err.println(Paths.get("").toAbsolutePath().toString());
System.err.println(System.getProperty("user.dir"));
}
Paths.get("") docs
System.getProperty("user.dir") docs
I hope you want to access the current directory including the package i.e. If your Java program is in c:\myApp\com\foo\src\service\MyTest.java and you want to print until c:\myApp\com\foo\src\service then you can try the following code:
String myCurrentDir = System.getProperty("user.dir")
+ File.separator
+ System.getProperty("sun.java.command")
.substring(0, System.getProperty("sun.java.command").lastIndexOf("."))
.replace(".", File.separator);
System.out.println(myCurrentDir);
Note: This code is only tested in Windows with Oracle JRE.
On Linux when you run a jar file from terminal, these both will return the same String: "/home/CurrentUser", no matter, where youre jar file is. It depends just on what current directory are you using with your terminal, when you start the jar file.
Paths.get("").toAbsolutePath().toString();
System.getProperty("user.dir");
If your Class with main would be called MainClass, then try:
MainClass.class.getProtectionDomain().getCodeSource().getLocation().getFile();
This will return a String with absolute path of the jar file.
Using Windows user.dir returns the directory as expected, but NOT when you start your application with elevated rights (run as admin), in that case you get C:\WINDOWS\system32
Mention that it is checked only in Windows but i think it works perfect on other Operating Systems [Linux,MacOs,Solaris] :).
I had 2 .jar files in the same directory . I wanted from the one .jar file to start the other .jar file which is in the same directory.
The problem is that when you start it from the cmd the current directory is system32.
Warnings!
The below seems to work pretty well in all the test i have done even
with folder name ;][[;'57f2g34g87-8+9-09!2##!$%^^&() or ()%&$%^##
it works well.
I am using the ProcessBuilder with the below as following:
🍂..
//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath= new File(path + "application.jar").getAbsolutePath();
System.out.println("Directory Path is : "+applicationPath);
//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2##!$%^^&()`
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();
//...code
🍂getBasePathForClass(Class<?> classs):
/**
* Returns the absolute path of the current directory in which the given
* class
* file is.
*
* #param classs
* #return The absolute path of the current directory in which the class
* file is.
* #author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
*/
public static final String getBasePathForClass(Class<?> classs) {
// Local variables
File file;
String basePath = "";
boolean failed = false;
// Let's give a first try
try {
file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
basePath = file.getParent();
} else {
basePath = file.getPath();
}
} catch (URISyntaxException ex) {
failed = true;
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (1): ", ex);
}
// The above failed?
if (failed) {
try {
file = new File(classs.getClassLoader().getResource("").toURI().getPath());
basePath = file.getAbsolutePath();
// the below is for testing purposes...
// starts with File.separator?
// String l = local.replaceFirst("[" + File.separator +
// "/\\\\]", "")
} catch (URISyntaxException ex) {
Logger.getLogger(classs.getName()).log(Level.WARNING,
"Cannot firgue out base path for class with way (2): ", ex);
}
}
// fix to run inside eclipse
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
basePath = basePath.substring(0, basePath.length() - 4);
}
// fix to run inside netbeans
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
basePath = basePath.substring(0, basePath.length() - 14);
}
// end fix
if (!basePath.endsWith(File.separator)) {
basePath = basePath + File.separator;
}
return basePath;
}
assume that you're trying to run your project inside eclipse, or netbean or stand alone from command line. I have write a method to fix it
public static final String getBasePathForClass(Class<?> clazz) {
File file;
try {
String basePath = null;
file = new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
basePath = file.getParent();
} else {
basePath = file.getPath();
}
// fix to run inside eclipse
if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
|| basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
basePath = basePath.substring(0, basePath.length() - 4);
}
// fix to run inside netbean
if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
basePath = basePath.substring(0, basePath.length() - 14);
}
// end fix
if (!basePath.endsWith(File.separator)) {
basePath = basePath + File.separator;
}
return basePath;
} catch (URISyntaxException e) {
throw new RuntimeException("Cannot firgue out base path for class: " + clazz.getName());
}
}
To use, everywhere you want to get base path to read file, you can pass your anchor class to above method, result may be the thing you need :D
Best,
For Java 11 you could also use:
var path = Path.of(".").toRealPath();
This is a very confuse topic, and we need to understand some concepts before providing a real solution.
The File, and NIO File Api approaches with relative paths "" or "." uses internally the system parameter "user.dir" value to determine the return location.
The "user.dir" value is based on the USER working directory, and the behavior of that value depends on the operative system, and the way the jar is executed.
For example, executing a JAR from Linux using a File Explorer (opening it by double click) will set user.dir with the user home directory, regardless of the location of the jar. If the same jar is executed from command line, it will return the jar location, because each cd command to the jar location modified the working directory.
Having said that, the solutions using Java NIO, Files or "user.dir" property will work for all the scenarios in the way the "user.dir" has the correct value.
String userDirectory = System.getProperty("user.dir");
String userDirectory2 = new File("").getAbsolutePath();
String userDirectory3 = Paths.get("").toAbsolutePath().toString();
We could use the following code:
new File(MyApp.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.toURI().getPath())
.getParent();
to get the current location of the executed JAR, and personally I used the following approach to get the expected location and overriding the "user.dir" system property at the very beginning of the application. So, later when the other approaches are used, I will get the expected values always.
More details here -> https://blog.adamgamboa.dev/getting-current-directory-path-in-java/
public class MyApp {
static {
//This static block runs at the very begin of the APP, even before the main method.
try{
File file = new File(MyApp.class.getProtectionDomain().getCodeSource()
.getLocation().toURI().getPath());
String basePath = file.getParent();
//Overrides the existing value of "user.dir"
System.getProperties().put("user.dir", basePath);
}catch(URISyntaxException ex){
//log the error
}
}
public static void main(String args []){
//Your app logic
//All these approaches should return the expected value
//regardless of the way the jar is executed.
String userDirectory = System.getProperty("user.dir");
String userDirectory2 = new File("").getAbsolutePath();
String userDirectory3 = Paths.get("").toAbsolutePath().toString();
}
}
I hope this explanation and details are helpful to others...
Current working directory is defined differently in different Java implementations. For certain version prior to Java 7 there was no consistent way to get the working directory. You could work around this by launching Java file with -D and defining a variable to hold the info
Something like
java -D com.mycompany.workingDir="%0"
That's not quite right, but you get the idea. Then System.getProperty("com.mycompany.workingDir")...
This is my silver bullet when ever the moment of confusion bubbles in.(Call it as first thing in main). Maybe for example JVM is slipped to be different version by IDE. This static function searches current process PID and opens VisualVM on that pid. Confusion stops right there because you want it all and you get it...
public static void callJVisualVM() {
System.out.println("USER:DIR!:" + System.getProperty("user.dir"));
//next search current jdk/jre
String jre_root = null;
String start = "vir";
try {
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
String jvmName = runtime.getName();
System.out.println("JVM Name = " + jvmName);
long pid = Long.valueOf(jvmName.split("#")[0]);
System.out.println("JVM PID = " + pid);
Runtime thisRun = Runtime.getRuntime();
jre_root = System.getProperty("java.home");
System.out.println("jre_root:" + jre_root);
start = jre_root.concat("\\..\\bin\\jvisualvm.exe " + "--openpid " + pid);
thisRun.exec(start);
} catch (Exception e) {
System.getProperties().list(System.out);
e.printStackTrace();
}
}
This isn't exactly what's asked, but here's an important note: When running Java on a Windows machine, the Oracle installer puts a "java.exe" into C:\Windows\system32, and this is what acts as the launcher for the Java application (UNLESS there's a java.exe earlier in the PATH, and the Java app is run from the command-line). This is why File(".") keeps returning C:\Windows\system32, and why running examples from macOS or *nix implementations keep coming back with different results from Windows.
Unfortunately, there's really no universally correct answer to this one, as far as I have found in twenty years of Java coding unless you want to create your own native launcher executable using JNI Invocation, and get the current working directory from the native launcher code when it's launched. Everything else is going to have at least some nuance that could break under certain situations.
Try something like this I know I am late for the answer but this obvious thing happened in java8 a new version from where this question is asked but..
The code
import java.io.File;
public class Find_this_dir {
public static void main(String[] args) {
//some sort of a bug in java path is correct but file dose not exist
File this_dir = new File("");
//but these both commands work too to get current dir
// File this_dir_2 = new File(this_dir.getAbsolutePath());
File this_dir_2 = new File(new File("").getAbsolutePath());
System.out.println("new File(" + "\"\"" + ")");
System.out.println(this_dir.getAbsolutePath());
System.out.println(this_dir.exists());
System.out.println("");
System.out.println("new File(" + "new File(" + "\"\"" + ").getAbsolutePath()" + ")");
System.out.println(this_dir_2.getAbsolutePath());
System.out.println(this_dir_2.exists());
}
}
This will work and show you the current path but I don't now why java fails to find current dir in new File(""); besides I am using Java8 compiler...
This works just fine I even tested it new File(new File("").getAbsolutePath());
Now you have current directory in a File object so (Example file object is f then),
f.getAbsolutePath() will give you the path in a String varaible type...
Tested in another directory that is not drive C works fine
My favorite method is to get it from the system environment variables attached to the current running process. In this case, your application is being managed by the JVM.
String currentDir = System.getenv("PWD");
/*
/home/$User/Documents/java
*/
To view other environment variables that you might find useful like, home dir, os version ........
//Home directory
String HomeDir = System.getEnv("HOME");
//Outputs for unix
/home/$USER
//Device user
String user = System.getEnv("USERNAME");
//Outputs for unix
$USER
The beautiful thing with this approach is that all paths will be resolved for all types of OS platform
You might use new File("./"). This way isDirectory() returns true (at least on Windows platform). On the other hand new File("") isDirectory() returns false.
None of the answers posted here worked for me. Here is what did work:
java.nio.file.Paths.get(
getClass().getProtectionDomain().getCodeSource().getLocation().toURI()
);
Edit: The final version in my code:
URL myURL = getClass().getProtectionDomain().getCodeSource().getLocation();
java.net.URI myURI = null;
try {
myURI = myURL.toURI();
} catch (URISyntaxException e1)
{}
return java.nio.file.Paths.get(myURI).toFile().toString()
System.getProperty("java.class.path")

Unable to access/run executable jar placed within the project

I am trying to run an executable jar places in the resources folder of my project. If I place the jar in any directory of my File System and provide the absolute path, it works fine.
Please see the code below:
String jarPath = "C:\\JarFolder\\myJar.jar";
String command = "java -jar";
String space = " ";
String params = "-a abc";
try {
proc = Runtime
.getRuntime()
.exec(command + space + jarPath + space + params);
} catch (IOException e) {
e.printStackTrace();
}
But when I place the jar inside the resources folder, and set the relative jar path as:
String jarPath = "..\\..\\..\\resources\\myJar.jar";
I get an error: Error: Unable to access jarfile ..\\..\\..\\resources\\myJar.jar
I have verified the path, it is valid.
Am I doing something wrong here? Is this the correct way to do this?
Use the ClassLoader to get the path of your resource.
String jarPath = this.getClass().getClassLoader().getResource("myJar.jar").getPath();
String command = "java -jar";
String space = " ";
String params = "-a abc";
try {
proc = Runtime
.getRuntime()
.exec(command + space + jarPath + space + params);
} catch (IOException e) {
e.printStackTrace();
}
If this is being ran from a main static method, then just replace this.getClass() with YourClass.class.
Relative path should work straight forward. Need more details of the error description you see and project folder structure (where the executing jar is placed and where is the import folder placed.)
Other alternate solution is to find the absolute file location of the currently executing jar file. You can fetch it with below code snippet.
MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
Other jar file to be executed must be placed somewhere in the same folder or in some child folders.
Now remove the current jar file name from the absolute path and append the relative path of the other jar file and execute it. It should work.
If you are on window, you can use as follow. I have tested this code and it works.
public class test {
public static void main(String[]args) throws IOException{
String jarPath = test.class.getClass().getResource("/resources/b.jar").getPath();
System.out.println("jarPath "+ jarPath);
//the result path have extra "/" so we have to remove it as follow.
jarPath = jarPath.substring(1);
//and again the result is encoded so we need to decode it back
jarPath = URLDecoder.decode(jarPath);
Runtime
.getRuntime()
.exec("java -jar \""+jarPath+"\"");
}
}
Note: I put my runnable jar in my resources folder with name "b.jar".
And the above codes need some modification to meet your needs.
Good Luck

Location of javaagent jar in bootclasspath

I have a javaagent jar that I put on the bootclasspath using
Boot-Class-Path: myagent.jar
inside the MANIFEST.MF file.
I need to find out the directory on the filesystem in which the jar is located.
However the method described for this here doesnt seem to work for me:
new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().g­etPath());
In this case the ProtectionDomain.getCodeSource() returns null. I guess this is happening because the jar has been put on the boot classpath. Because of this I also cannot do MyClass.getClassLoader() to get the resource location.
I am using Java 6.
Can anyone tell how to get the location of the jar?
You can use the System class loader to find classes on the boot class path. For example, this
System.out.println(
ClassLoader.getSystemClassLoader().getResource("java/lang/String.class")
);
Will print out something like,
jar:file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/rt.jar!/java/lang/String.class
To find the location of MyClass.class on disk, do
String urlString = ClassLoader
.getSystemClassLoader()
.getResource("com/my/package/MyClass.class")
.toString();
urlString = urlString.substring(urlString.indexOf("file:"), urlString.indexOf('!'));
URL url = new URL(urlString);
File file = new File(url.toURI());
System.out.println(file);
System.out.println(file.exists());
Update 2020-06-29 by kriegaex: Rather than writing a new answer to this old question, I want to enhance or update this very good answer, also taking account paths with spaces and Java 9+ modules.
Here is a method returning the class file path as a File instance. If a class file is part of a JAR or Java runtime module (URL starts with protocol jrt:), it just returns the paths to the JAR or to the JMOD file, which is something you might not want, but it is just a showcase you can edit to your heart's content. Of course this is still hacky, e.g. not considering classes loaded from a web URL instead of from file, but you get the idea.
public static File getFileForClass(String className) {
className = className.replace('.', '/') + ".class";
URL classURL = ClassLoader.getSystemClassLoader().getResource(className);
if (classURL == null)
return null;
System.out.println("Class file URL: " + classURL);
// Adapt this if you also have '.war' or other archive types
if (classURL.toString().contains(".jar!")) {
String jarFileName = classURL.getPath().replaceFirst("!.*", "");
System.out.println("Containing JAR file: " + jarFileName);
try {
return new File(new URL(jarFileName).toURI());
}
catch (URISyntaxException | MalformedURLException e) {
throw new RuntimeException(e);
}
}
if (classURL.getProtocol().equals("jrt")) {
String jrtModule = classURL.getFile().replaceFirst("/([^/]+).*", "$1");
System.out.println("Target class is part of Java runtime module " + jrtModule);
String jmodName = System.getProperty("java.home") + "/jmods/" + jrtModule + ".jmod";
System.out.println("Containing Java module file: " + jmodName);
return new File(jmodName);
}
try {
return new File(classURL.toURI());
}
catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
When I call this from one of my IntelliJ IDEA projects with JDK 14 installed under a path containing spaces and deliberately adding a JAR also containing a path with spaces for testing, this code...
public static void main(String[] args) throws IOException {
Instrumentation instrumentation = ByteBuddyAgent.install();
instrumentation.appendToSystemClassLoaderSearch(
new JarFile("C:/Program Files/JetBrains/IntelliJ IDEA 2018.3/lib/idea_rt.jar")
);
Stream
.of(
Weaver.class.getName(),
String.class.getName(),
ByteBuddy.class.getName(),
"com.intellij.execution.TestDiscoveryListener"
)
.forEach(className -> System.out.printf("Found file: %s%n%n", getFileForClass(className)));
}
... yields this console output:
Class file URL: file:/C:/Users/alexa/Documents/java-src/Sarek/sarek-aspect/target/classes/dev/sarek/agent/aspect/Weaver.class
Found file: C:\Users\alexa\Documents\java-src\Sarek\sarek-aspect\target\classes\dev\sarek\agent\aspect\Weaver.class
Class file URL: jrt:/java.base/java/lang/String.class
Target class is part of Java runtime module java.base
Containing Java module file: C:\Program Files\Java\jdk-14.0.1/jmods/java.base.jmod
Found file: C:\Program Files\Java\jdk-14.0.1\jmods\java.base.jmod
Class file URL: jar:file:/C:/Users/alexa/.m2/repository/net/bytebuddy/byte-buddy/1.10.13/byte-buddy-1.10.13.jar!/net/bytebuddy/ByteBuddy.class
Containing JAR file: file:/C:/Users/alexa/.m2/repository/net/bytebuddy/byte-buddy/1.10.13/byte-buddy-1.10.13.jar
Found file: C:\Users\alexa\.m2\repository\net\bytebuddy\byte-buddy\1.10.13\byte-buddy-1.10.13.jar
Class file URL: jar:file:/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202018.3/lib/idea_rt.jar!/com/intellij/execution/TestDiscoveryListener.class
Containing JAR file: file:/C:/Program%20Files/JetBrains/IntelliJ%20IDEA%202018.3/lib/idea_rt.jar
Found file: C:\Program Files\JetBrains\IntelliJ IDEA 2018.3\lib\idea_rt.jar
You could do something like this:
final String bootClassPath;
final String[] entries;
// different VM may use a different string here...
bootClassPath = System.getProperty("sun.boot.class.path");
entries = bootClassPath.split(File.pathSeparator);
for(final String entry : entries)
{
System.out.println(entry);
}
Which goes through each entry in the boot classpath. For each entry you could then get the JAR file and look at the manifest file and see if it is yours. You could add another entry in the manifest to look for if there isn't already something unique to find.

Categories