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.