got java.lang.ExceptionInInitializerError when calling SQLiteConfig.Pragma.values()
ianhash opened this issue · 8 comments
Describe the bug
i got java.lang.ExceptionInInitializerError when calling SQLiteConfig.Pragma.values(), it seems there was an issue during the static initialization phase of the Pragma enum in the SQLiteConfig class
To Reproduce
public static void main(String[] args) {
SQLiteConfig.Pragma[] values = SQLiteConfig.Pragma.values();
for (SQLiteConfig.Pragma value : values) {
System.out.println(value);
}
}
sqlite-jdbc version >=3.25.2,here is 3.46.0.0
Expected behavior
just like sqlite-jdbc version <=3.23.1, it should print all SQLiteConfig.Pragma enum contants.
Logs
sqlite-jdbc version = 3.46.0.0
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.sqlite.SQLiteConfig$Pragma.<clinit>(SQLiteConfig.java:380)
at mess.javamess.sqlite.SqliteConfigInit.main(SqliteConfigInit.java:15)
Caused by: java.lang.NullPointerException
at org.sqlite.SQLiteConfig$Pragma.values(SQLiteConfig.java:376)
at org.sqlite.SQLiteConfig.<clinit>(SQLiteConfig.java:357)
... 2 more
Environment (please complete the following information):
- OS: MacOs m1
- CPU architecture: arm64
- sqlite-jdbc version >=3.25.2
- java version:
adoptopenjdk-8.jdk
openjdk@11/11.0.23
openjdk 21.0.3
oracel jdk-22
Additional context
Interesting. I have no idea why this happens, any insights are welcome.
Interesting. I have no idea why this happens, any insights are welcome.
I think there is a circular dependencies in static initialization ,
SQLiteConfig.class -> SQLiteConfig static block -> SQLiteConfig.Pragma -> SQLiteConfig.OnOff -> SQLiteConfig.class
I think the private static field OnOff
needs to be extracted to another class,just like this:
static class OnOff {
private static final String[] OnOff = new String[] { "true", "false" };
}
i tried inlining the OnOff
field and remove the field altogether, but the problem remains.
i tried inlining the
OnOff
field and remove the field altogether, but the problem remains.
inlining MUST BE OK,
public class Foo {
public static final Set<String> FOO_TYPES = new HashSet<>();
private static final String[] OnOff = new String[] { "true", "false" };
static {
for (Foo.FooType v : Foo.FooType.values()) {
FOO_TYPES.add(v.name());
}
}
public static enum FooType {
A(null),
B(OnOff), // BAD
// B(new String[] { "true", "false" }) , // GOOD
;
public final String[] choices;
FooType(String[] onOff) {
this.choices = onOff;
}
}
}
BTW: My suggestion is to extract OnOff
into another class。
inlining MUST BE OK,
i tested this with a unit test and it still fails. I don't see how extracting the class would be any different, if inlining the array does not work.
inlining MUST BE OK,
i tested this with a unit test and it still fails. I don't see how extracting the class would be any different, if inlining the array does not work.
The method toStringArray
has same problem. this method is only called in class Pragma
, so I moved it to Pragma
.
please look into my pr #1124 for the details.
🎉 This issue has been resolved in 3.46.0.1
(Release Notes)