我正在尝试编译一个使用Processing 3.4源代码的类。尝试编译扩展StringIndexOutOfBoundsException
的类时遇到PApplet
问题。
PApplet
类包含以下我认为是问题的代码
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('.')
返回-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$1.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$1.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\
编辑:我班上的主要功能是这样的
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
文件夹中。我无法毫不费力地更改来源。
答案 0 :(得分:1)
这有两个方面:
StringIndexOutOfBoundsException
的事实意味着javaVersionName
字符串不是不是 null
,否则,您会得到一个{ {1}}在调用NullPointerException
时startsWith
之后的字符串部分将有另一个点有各种Java主要版本和供应商,并且版本会随之变化。
您应该只调试代码并推断那里返回的值是什么。
作为一个可能不相关的注释,如果您的应用程序是一个applet,则您也要保持谨慎:
安全考虑:可以限制对系统属性的访问 由安全经理。在applet中,这通常是一个问题, 被阻止读取某些系统属性和写入 任何系统属性。有关在中访问系统属性的更多信息 小程序,请参阅《使用Java进行更多操作》中的“系统属性”。 互联网应用课程。
来源here。
答案 1 :(得分:0)
您似乎在作弊;)
自9
发行版以来,您所显示的代码已经在正确处理Java版本的修补程序之后-在这里,您的主要发行版和修补版本的版本略有不同。
您的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
如果使用注释中建议的勾号,则可以将其“修复”
public class Main {
static public void main(String[] passedArgs) {
String[] appletArgs = new String[] { "Demo" };
System.setProperty("java.version", "1.1.1");
PApplet.main(appletArgs);
}
}
您将使代码运行
> javac PApplet.java
> javac Main.java
> java -cp . Main
Java version: 1
因此,最后,为什么不从最新资源构建它? :)
替代方法-有点hacky
比方说,您既不能更改Main.java
也不能更改core.jar
。您在这里可以做的是欺骗Java
,在哪里寻找PApplet.class
。您可以创建一个目录-称其为fix
。在fix
内部,您只能编译一个类:PApplet.java
。然后,您可以运行如下代码:
> java -cp fix:. Main
其中的修复程序包含您特制的版本
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);
}
}
答案 2 :(得分:-1)
问题在这里:
//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('.')
返回-1,而subString(0,-1)
引发StringIndexOutOfBoundsException