I’m seeing the same issue on Archlinux as well, and was able to track it down. tl;dr and workaround at the bottom of everything, but check the next post for a better workaround.
I’ve tried to document everything (also as a note to myself). I took a closer look at the traceback I got:
java.lang.RuntimeException: java.lang.NullPointerException
at cc.arduino.contributions.packages.ui.ContributionManagerUI.lambda$onInstallPressed$2(ContributionManagerUI.java:179)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at java.io.File.<init>(File.java:362)
at cc.arduino.contributions.packages.ContributionInstaller.install(ContributionInstaller.java:160)
at cc.arduino.contributions.packages.ui.ContributionManagerUI.lambda$onInstallPressed$2(ContributionManagerUI.java:172)
... 1 more
This shows that it happens in Arduino’s ContributionInstaller.java on line 160:
File destFolder = new File(platformFolder, contributedPlatform.getParsedVersion());
This then calls into File.java on line 362:
public File(File parent, String child) {
if (child == null) {
throw new NullPointerException();
}
// ...
}
Thus, the crash happens because contributedPlatform.getParsedVersion() returned null. The source for that, in turn, says:
public String getParsedVersion() {
Optional<Version> version = VersionHelper.valueOf(getVersion());
if (version.isPresent()) {
return version.get().toString();
}
return null;
}
thus, version.isPresent() was false. It’s coming from VersionHelper.valueOf, and taking a look at that reveals that either the version passed to it was empty or invalid:
public static Optional<Version> valueOf(String ver) {
if (ver == null) {
return Optional.empty();
}
try {
// [version parsing logic]
return Optional.of(Version.valueOf(version + extra));
} catch (Exception e) {
return Optional.empty();
}
}
So something has either an invalid or missing version number. I really wish both Arduino and Java had some better error handling…
So let’s take a look at the master index JSON and compare it to the regular release JSON. Here’s the difference as generated by diff -Naur package_keyboardio_index.json package_kaleidoscope_master_index.json:
--- package_keyboardio_index.json 2021-09-02 20:18:48.769433980 +0200
+++ package_kaleidoscope_master_index.json 2021-09-02 20:18:54.128748865 +0200
@@ -1,451 +1,16 @@
{
"packages" : [
{
- "email" : "",
+ "email" : "jesse@keyboard.io",
"help" : {
- "online" : "http://keyboard.io"
+ "online" : "https://kaleidoscope.readthedocs.io"
},
"maintainer" : "Keyboardio",
- "name" : "keyboardio",
+ "name" : "kaleidoscope_nightly",
"platforms" : [
{
"architecture" : "avr",
- [lots and lots of releases removed, but we only are interested in the differences to the newest release]
- "archiveFileName" : "Kaleidoscope-1.99.3.tar.bz2",
+ "archiveFileName" : "Kaleidoscope-2021.08.05182428.tar.bz2",
"boards" : [
{
"name" : "Keyboardio Model 01"
@@ -455,12 +20,12 @@
}
],
"category" : "Contributed",
- "checksum" : "SHA-256:eb75a6203962f77e9d18add88bdb3d6ddada45135d825a6c40e8bc492db21df7",
+ "checksum" : "SHA-256:fc17b1d9e9c208558d6c0b5507943c6d05ad5742b67161ed3fdbbe45d5bcaf4f",
"help" : {
"online" : "https://community.keyboard.io"
},
"name" : "Kaleidoscope keyboards",
- "size" : 679181,
+ "size" : 767144,
"toolsDependencies" : [
{
"name" : "avr-gcc",
@@ -473,8 +38,8 @@
"version" : "6.3.0-arduino17"
}
],
- "url" : "https://raw.githubusercontent.com/keyboardio/boardsmanager/master/builds//Kaleidoscope-1.99.3.tar.bz2",
- "version" : "1.99.3"
+ "url" : "https://raw.githubusercontent.com/keyboardio/arduino-kaleidoscope-master/master/builds//Kaleidoscope-2021.08.05182428.tar.bz2",
+ "version" : "2021.08.05182428"
}
],
"tools" : [],
I can see a few possible culprits:
- The version number changed from
1.99.3 to 2021.08.05182428. That does look like a valid version number to me, though, and the version parsing logic seems like it can deal with it just fine.
- The download URL changed (as expected) from Kaleidoscope-1.99.3.tar.bz2 to Kaleidoscope-2021.08.05182428.tar.bz2. Perhaps something in those archives content is wrong? I took a cursory look with kdiff3, and all changes are in the code inside
libraries/ - notably, boards.txt and platform.txt are equal, and those are probably the only things the Arduino IDE cares about at that stage.
- There’s a double slash in the URL: […]/builds//Kaleidoscope-2021.08.05182428.tar.bz2 - maybe that trips something up?
At this point I uploaded the JSON file to my own website so I can experiment with changes. Note that I’d recommend backing up and removing ~/Arduino and ~/.arduino15 for those tests, as there are other issues related to the removal of packages resulting in a very similar NullPointerException.
Fixing the double slash did nothing, unfortunately. Then again, it’s part of the working JSON as well, so that was unlikely to be the culprit.
Next, I tried setting the version to 1.99.9999 and suddenly was able to install the package correctly. I haven’t tried to build it yet since it’s getting late here, but I assume it will work just fine. Here are the changes compared to the original:
--- package_kaleidoscope_master_index.json.1 2021-09-02 21:12:57.881159310 +0200
+++ package_kaleidoscope_master_index.json 2021-09-02 21:09:03.366922818 +0200
@@ -38,8 +38,8 @@
"version" : "6.3.0-arduino17"
}
],
- "url" : "https://raw.githubusercontent.com/keyboardio/arduino-kaleidoscope-master/master/builds//Kaleidoscope-2021.08.05182428.tar.bz2",
- "version" : "2021.08.05182428"
+ "url" : "https://raw.githubusercontent.com/keyboardio/arduino-kaleidoscope-master/master/builds/Kaleidoscope-2021.08.05182428.tar.bz2",
+ "version" : "1.99.9999"
}
],
"tools" : [],
So, let’s look at the version parsing logic again:
try {
// Allow x.y-something, assuming x.y.0-something
// Allow x-something, assuming x.0.0-something
String version = ver;
String extra = "";
String split[] = ver.split("[+-]", 2);
if (split.length == 2) {
version = split[0];
extra = ver.substring(version.length()); // includes separator + or -
}
String[] parts = version.split("\\.");
if (parts.length >= 3) {
return Optional.of(Version.valueOf(ver));
}
if (parts.length == 2) {
version += ".0";
}
if (parts.length == 1) {
version += ".0.0";
}
return Optional.of(Version.valueOf(version + extra));
} catch (Exception e) {
return Optional.empty();
}
At least there, I really don’t see anything which would be happy with 1.99.9999 but failing with 2021.08.05182428… Maybe there’s something I’ve missed which doesn’t like the leading zeroes in the date or something, but that’d be weird too. I have no idea, this is as far as I got.
tl;dr: It’s something about the Arduino IDE not liking the version number. Feel free to use my modified version which installs fine for me, but please note that it’s totally unofficial and - while that would be a very sad thing - I’m not responsible for any kittens being harmed or other problems with it. Check the next post for a better workaround.