System.getProperty("java.version") Returns 空
System.getProperty("java.version") Returns Null
我正在尝试编译一个使用 Processing 3.4 源代码的 class。我在尝试编译扩展 PApplet
的 class 时得到一个 StringIndexOutOfBoundsException
。
PApplet
class 有以下代码,我认为这是问题所在
public class PApplet implements PConstants {
/** Full name of the Java version (i.e. 1.5.0_11). */
static public final String javaVersionName =
System.getProperty("java.version");
static public final int javaPlatform;
static {
String version = javaVersionName;
if (javaVersionName.startsWith("1.")) {
version = version.substring(2);
javaPlatform = parseInt(version.substring(0, version.indexOf('.')));
} else {
// Remove -xxx and .yyy from java.version (@see JEP-223)
javaPlatform = parseInt(version.replaceAll("-.*","").replaceAll("\..*",""));
}
}
我认为字符串 javaVersionName
被设置为 null 或其他导致 version.indexOf('.')
到 return -1
.
的奇怪值
堆栈跟踪:
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:567)
at org.codehaus.mojo.exec.ExecJavaMojo.run (ExecJavaMojo.java:293)
at java.lang.Thread.run (Thread.java:830)
Caused by: java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 2
at java.lang.String.checkBoundsBeginEnd (String.java:3720)
at java.lang.String.substring (String.java:1909)
at processing.core.PApplet.<clinit> (PApplet.java:123)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:567)
at org.codehaus.mojo.exec.ExecJavaMojo.run (ExecJavaMojo.java:293)
at java.lang.Thread.run (Thread.java:830)
其中某处显示 at processing.core.PApplet.<clinit> (PApplet.java:123)
。 PApplet.java
中的第 123 行是我在上面发布的第一行 (public class PApplet ...
)。
我怀疑这可能与我的路径和 JAVA_HOME 系统变量有关。我正在使用 JDK 13 作为 C:\Program Files\Java\jdk-13\bin
添加到我的路径并且 JAVA_HOME 变量设置为 C:\Program Files\Java\jdk-13\
编辑:我的 class 中的主要函数如下所示
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
if (passedArgs != null) {
PApplet.main(concat(appletArgs, passedArgs));
} else {
PApplet.main(appletArgs);
}
}
编辑:我还应该提到,我上面发布的 PApplet
片段并不是我使用的实际来源,只是我在网上找到的。我拥有的实际来源位于 core.jar
文件夹中。我很难轻易更改源。
这有两个方面:
- 在上下文中抛出
StringIndexOutOfBoundsException
这一事实意味着 javaVersionName
字符串 不是 null
,否则,您当调用 startsWith
时会得到 NullPointerException
- 这里的问题是假设
1.
之后的字符串部分会有另一个点
有多种 Java 主要版本和供应商,并且版本会随之变化。
您应该简单地调试您的代码并推断那里返回的值到底是什么。
作为一个可能不相关的说明,如果(正如 class 名称所暗示的那样),您的应用程序是一个小程序,您还需要谨慎:
Security consideration: Access to system properties can be restricted
by the Security Manager. This is most often an issue in applets, which
are prevented from reading some system properties, and from writing
any system properties. For more on accessing system properties in
applets, refer to System Properties in the Doing More With Java Rich
Internet Applications lesson.
来源here。
问题出在这里:
//supposing Java version 18.9
version = version.substring(2);
//now version is equal to "9"
javaPlatform = parseInt(version.substring(0, version.indexOf('.')));//error! because indexOf('.') return -1 since '.' is not found in variable version
因此,indexOf('.')
return -1 和 subString(0,-1)
引发 StringIndexOutOfBoundsException
看来你有点作弊 ;)
您显示的代码已经在修复 Java 版本 9
后的正确处理之后 - 这是您的主要版本和修补版本略有不同的地方。
看起来你的 core.jar
是预提交的:
java.version
属性 的处理已修复。
因此,您的示例代码应为
public class PApplet {
static public final String javaVersionName =
System.getProperty("java.version");
static public final int javaPlatform =
PApplet.parseInt(PApplet.split(javaVersionName, '.')[1]);
static public String[] split(String value, char delim) {
// do this so that the exception occurs inside the user's
// program, rather than appearing to be a bug inside split()
if (value == null) return null;
//return split(what, String.valueOf(delim)); // huh
char chars[] = value.toCharArray();
int splitCount = 0; //1;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == delim) splitCount++;
}
// make sure that there is something in the input string
//if (chars.length > 0) {
// if the last char is a delimeter, get rid of it..
//if (chars[chars.length-1] == delim) splitCount--;
// on second thought, i don't agree with this, will disable
//}
if (splitCount == 0) {
String splits[] = new String[1];
splits[0] = value;
return splits;
}
//int pieceCount = splitCount + 1;
String splits[] = new String[splitCount + 1];
int splitIndex = 0;
int startIndex = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == delim) {
splits[splitIndex++] =
new String(chars, startIndex, i-startIndex);
startIndex = i + 1;
}
}
//if (startIndex != chars.length) {
splits[splitIndex] =
new String(chars, startIndex, chars.length-startIndex);
//}
return splits;
}
static final public int parseInt(String what) {
return parseInt(what, 0);
}
static final public int parseInt(String what, int otherwise) {
try {
int offset = what.indexOf('.');
if (offset == -1) {
return Integer.parseInt(what);
} else {
return Integer.parseInt(what.substring(0, offset));
}
} catch (NumberFormatException e) { }
return otherwise;
}
public static void main(String [] args) {
System.out.println("Java version: " + javaPlatform);
}
}
和主要
public class Main {
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
PApplet.main(appletArgs);
}
}
你会在哪里得到你的异常
> javac PApplet.java
> javac Main.java
> java -cp . Main
Exception in thread "main" java.lang.ExceptionInInitializerError
at Main.main(Main.java:7)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at PApplet.<clinit>(PApplet.java:6)
... 1 more
如果您使用评论中建议的勾号,您可以获得它"fixed"
public class Main {
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
System.setProperty("java.version", "1.1.1");
PApplet.main(appletArgs);
}
}
你会得到你的代码 运行ning
> javac PApplet.java
> javac Main.java
> java -cp . Main
Java version: 1
那么,最后,为什么不从最新的来源构建它呢? :)
替代方法 - 有点老套
假设您不能更改 Main.java
和 core.jar
。你可以在这里做的是欺骗Java
去哪里寻找PApplet.class
。您可以创建一个目录 - 我们称它为 fix
。在 fix
中你只能编译一个 class: PApplet.java
。然后,你可以运行这样的代码:
> java -cp fix:. Main
其中 fix 包含您特制的版本
public class PApplet {
static public final String javaVersionName =
System.getProperty("java.version");
static public final int javaPlatform = 1;
public static void main(String [] args) {
System.out.println("Java version: " + javaPlatform);
}
}
我正在尝试编译一个使用 Processing 3.4 源代码的 class。我在尝试编译扩展 PApplet
的 class 时得到一个 StringIndexOutOfBoundsException
。
PApplet
class 有以下代码,我认为这是问题所在
public class PApplet implements PConstants {
/** Full name of the Java version (i.e. 1.5.0_11). */
static public final String javaVersionName =
System.getProperty("java.version");
static public final int javaPlatform;
static {
String version = javaVersionName;
if (javaVersionName.startsWith("1.")) {
version = version.substring(2);
javaPlatform = parseInt(version.substring(0, version.indexOf('.')));
} else {
// Remove -xxx and .yyy from java.version (@see JEP-223)
javaPlatform = parseInt(version.replaceAll("-.*","").replaceAll("\..*",""));
}
}
我认为字符串 javaVersionName
被设置为 null 或其他导致 version.indexOf('.')
到 return -1
.
堆栈跟踪:
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:567)
at org.codehaus.mojo.exec.ExecJavaMojo.run (ExecJavaMojo.java:293)
at java.lang.Thread.run (Thread.java:830)
Caused by: java.lang.StringIndexOutOfBoundsException: begin 0, end -1, length 2
at java.lang.String.checkBoundsBeginEnd (String.java:3720)
at java.lang.String.substring (String.java:1909)
at processing.core.PApplet.<clinit> (PApplet.java:123)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:567)
at org.codehaus.mojo.exec.ExecJavaMojo.run (ExecJavaMojo.java:293)
at java.lang.Thread.run (Thread.java:830)
其中某处显示 at processing.core.PApplet.<clinit> (PApplet.java:123)
。 PApplet.java
中的第 123 行是我在上面发布的第一行 (public class PApplet ...
)。
我怀疑这可能与我的路径和 JAVA_HOME 系统变量有关。我正在使用 JDK 13 作为 C:\Program Files\Java\jdk-13\bin
添加到我的路径并且 JAVA_HOME 变量设置为 C:\Program Files\Java\jdk-13\
编辑:我的 class 中的主要函数如下所示
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
if (passedArgs != null) {
PApplet.main(concat(appletArgs, passedArgs));
} else {
PApplet.main(appletArgs);
}
}
编辑:我还应该提到,我上面发布的 PApplet
片段并不是我使用的实际来源,只是我在网上找到的。我拥有的实际来源位于 core.jar
文件夹中。我很难轻易更改源。
这有两个方面:
- 在上下文中抛出
StringIndexOutOfBoundsException
这一事实意味着javaVersionName
字符串 不是null
,否则,您当调用startsWith
时会得到NullPointerException
- 这里的问题是假设
1.
之后的字符串部分会有另一个点
有多种 Java 主要版本和供应商,并且版本会随之变化。
您应该简单地调试您的代码并推断那里返回的值到底是什么。
作为一个可能不相关的说明,如果(正如 class 名称所暗示的那样),您的应用程序是一个小程序,您还需要谨慎:
Security consideration: Access to system properties can be restricted by the Security Manager. This is most often an issue in applets, which are prevented from reading some system properties, and from writing any system properties. For more on accessing system properties in applets, refer to System Properties in the Doing More With Java Rich Internet Applications lesson.
来源here。
问题出在这里:
//supposing Java version 18.9
version = version.substring(2);
//now version is equal to "9"
javaPlatform = parseInt(version.substring(0, version.indexOf('.')));//error! because indexOf('.') return -1 since '.' is not found in variable version
因此,indexOf('.')
return -1 和 subString(0,-1)
引发 StringIndexOutOfBoundsException
看来你有点作弊 ;)
您显示的代码已经在修复 Java 版本 9
后的正确处理之后 - 这是您的主要版本和修补版本略有不同的地方。
看起来你的 core.jar
是预提交的:
java.version
属性 的处理已修复。
因此,您的示例代码应为
public class PApplet {
static public final String javaVersionName =
System.getProperty("java.version");
static public final int javaPlatform =
PApplet.parseInt(PApplet.split(javaVersionName, '.')[1]);
static public String[] split(String value, char delim) {
// do this so that the exception occurs inside the user's
// program, rather than appearing to be a bug inside split()
if (value == null) return null;
//return split(what, String.valueOf(delim)); // huh
char chars[] = value.toCharArray();
int splitCount = 0; //1;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == delim) splitCount++;
}
// make sure that there is something in the input string
//if (chars.length > 0) {
// if the last char is a delimeter, get rid of it..
//if (chars[chars.length-1] == delim) splitCount--;
// on second thought, i don't agree with this, will disable
//}
if (splitCount == 0) {
String splits[] = new String[1];
splits[0] = value;
return splits;
}
//int pieceCount = splitCount + 1;
String splits[] = new String[splitCount + 1];
int splitIndex = 0;
int startIndex = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == delim) {
splits[splitIndex++] =
new String(chars, startIndex, i-startIndex);
startIndex = i + 1;
}
}
//if (startIndex != chars.length) {
splits[splitIndex] =
new String(chars, startIndex, chars.length-startIndex);
//}
return splits;
}
static final public int parseInt(String what) {
return parseInt(what, 0);
}
static final public int parseInt(String what, int otherwise) {
try {
int offset = what.indexOf('.');
if (offset == -1) {
return Integer.parseInt(what);
} else {
return Integer.parseInt(what.substring(0, offset));
}
} catch (NumberFormatException e) { }
return otherwise;
}
public static void main(String [] args) {
System.out.println("Java version: " + javaPlatform);
}
}
和主要
public class Main {
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
PApplet.main(appletArgs);
}
}
你会在哪里得到你的异常
> javac PApplet.java
> javac Main.java
> java -cp . Main
Exception in thread "main" java.lang.ExceptionInInitializerError
at Main.main(Main.java:7)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
at PApplet.<clinit>(PApplet.java:6)
... 1 more
如果您使用评论中建议的勾号,您可以获得它"fixed"
public class Main {
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
System.setProperty("java.version", "1.1.1");
PApplet.main(appletArgs);
}
}
你会得到你的代码 运行ning
> javac PApplet.java
> javac Main.java
> java -cp . Main
Java version: 1
那么,最后,为什么不从最新的来源构建它呢? :)
替代方法 - 有点老套
假设您不能更改 Main.java
和 core.jar
。你可以在这里做的是欺骗Java
去哪里寻找PApplet.class
。您可以创建一个目录 - 我们称它为 fix
。在 fix
中你只能编译一个 class: PApplet.java
。然后,你可以运行这样的代码:
> java -cp fix:. Main
其中 fix 包含您特制的版本
public class PApplet {
static public final String javaVersionName =
System.getProperty("java.version");
static public final int javaPlatform = 1;
public static void main(String [] args) {
System.out.println("Java version: " + javaPlatform);
}
}