As you may have already been apprised, the start of your dilemma is within the changePath() method on this one line of code: int index1=path.indexOf(jdk);
.
This is the beginning of the end for the changePath() method and it is because the method's parameter variable named jdk
is passed an argument of "jdk-13"
which simply does not exist within the path string which is also supplied to this method as an argument for the path
parameter. Because "jdk-13"
does not exist within the supplied path of "/usr/java/jdk1.8/bin/"
, the String#indexOf() method returns an index of -1
which is a no can do for any argument passed to a String#substring() method or any other method that requires an index value. A value of -1
is an invalid index value and will always be returned from the String#indexOf() method if the supplied string to get an index for can not be located. This actually real handy for a lot of different situations.
On a side:
Now, I don't know why you want to access different JDK /bin/
directories and quite honestly, I don't care however you do need to know that the java
directory which holds your JDK's should not necessarily be hard-coded into your code (String path = "/usr/java/jdk1.8/bin/";
). I'm sure you did this just as an example but I thought I would throw this out there anyways. It's actually a bad idea for the simple reason that upon a JDK installation, this directory can potentially be named anything and placed anywhere from one system to another, for example in my System, I have the Java JRE on one drive and the JDK on another drive.
When I run an application from my IDE the System.getProperties("java.home")
property points to the JDK on my local drive D:
in a specific path format (the JDK also contains a jre
). If I were to now compile the same application into a JAR file and now run it from a Command Window, the System.getProperties("java.home")
property points to the JRE on my local drive C:
in a completely different path format. It would be better to let code determine this path, for example:
When application is run from the IDE:
String javaHome = System.getProperty("java.home");
String lastFolder = javaHome.substring(javaHome.lastIndexOf("\\") + 1);
String path = javaHome.replace(java.io.File.separator, "/").replace("/jre", "/bin/");
String jdk13 = "jdk-13";
// Using the changeJdkPath() method:
String newPath = changeJdkPath(path, jdk13);
System.out.println(newPath);
When application is compiled and run as a JAR file from a Command Window:
String javaHome = System.getProperty("java.home");
String lastFolder = javaHome.substring(javaHome.lastIndexOf("\\") + 1);
String path = path = javaHome.replace(java.io.File.separator, "/") + "/bin/";
String jre13 = "jre-13";
// Using the changeJrePath() method:
String newPath = changeJrePath(path, jre13);
System.out.println(newPath);
Putting it all together:
Below is an example runnable application which you can run from the IDE or compile it and run as a JAR file from a Command Window. Run the application both ways to see the results. Here is the runnable code:
public class Change_JDK_Path_Demo {
public static void main(String[] args) {
/* Depending on instalation, the JDK Java home directory can be
named anything and placed litteraly anywhere including on any
local drive. This is only good if you run your code within the
IDE. These paths change within the System Properties when the
application is compiled and run as a JAR file from within a
Command Window and it would be the JRE you need to change to
in order to access its' /bin/ directory. */
String javaHome = System.getProperty("java.home");
String lastFolder = javaHome.substring(javaHome.lastIndexOf("\\") + 1);
String path;
String jdk_jre;
// If running from IDE - change JDK folder
if (lastFolder.length() == 3) {
path = javaHome.replace(java.io.File.separator, "/").replace("/jre", "/bin/");
jdk_jre = "jdk-13";
}
// Running as JAR - change JRE folder
else {
path = javaHome.replace(java.io.File.separator, "/") + "/bin/";
jdk_jre = "jre-13";
}
System.out.println("Original Path is: -> " + path);
String newPath = changeJdkOrJrePath(path, jdk_jre);
System.out.println("New Path is: -> " + newPath);
}
public static String changeJdkOrJrePath(String jdkORjrePath, String newJDKorJRE) {
// Handle passed arguments that are either Null or Empty.
if (jdkORjrePath == null || jdkORjrePath.trim().isEmpty()) {
return null;
}
if (newJDKorJRE == null || newJDKorJRE.trim().isEmpty()) {
return jdkORjrePath;
}
// Get parent directory name for JDK's or JRE's from jdkORjrePath:
String parent = "java"; // An Assumed Default.
String[] pathParts = jdkORjrePath.split("/");
for (int i = 0; i < pathParts.length; i++) {
String part = pathParts[i].toLowerCase();
if (part.startsWith(newJDKorJRE.toLowerCase().startsWith("jdk") ? "jdk" : "jre")) {
parent = pathParts[i-1] + "/";
break;
}
}
/* Retrieve the current JDK or JRE directory indicated after the
JDK's or JRE's parent directory. This could potentialy be any
JDK or any JRE. */
String oldJDK = jdkORjrePath.substring(jdkORjrePath.indexOf(parent) + parent.length(),
jdkORjrePath.indexOf("/", (jdkORjrePath.indexOf(parent) + parent.length())));
/* Now replace that determined JDK or JRE with the JDK or
JRE passed to this method and return the new path: */
return jdkORjrePath.replace(oldJDK, newJDKorJRE);
}
}
When I run this code from my IDE I get a result of:
Original Path is: -> D:/JAVA/jdk1.8.0_111/bin/
New Path is: -> D:/JAVA/jdk-13/bin/
When I run this code from a Command Window as a compiled JAR file I get a result of:
Original Path is: -> C:/Program Files/Java/jre1.8.0_311/bin/
New Path is: -> C:/Program Files/Java/jre-13/bin/