If like me you're using Ultrasonic to interact with your airsonic instance, you might have wondered why it stopped working when you updated to a new java version.
Airsonic is a fork of the now-defunct libresonic, itself a fork of the now-non-free subsonic, hence why it's exposing the API of the later.
Unfortunately, subsonic being a freemium
software, to use the API,
one has to have a valid license. This is why mobile applications are first
calling the /rest/getLicense.view
endpoint, before being able to use it.
On airsonic, this is a dummy endpoint, implemented in SubsonicRESTController.java:
/**
* CAUTION : this method is required by mobile applications and must not be removed.
*/
@RequestMapping(value = "/getLicense")
public void getLicense(HttpServletRequest request, HttpServletResponse response) throws Exception {
request = wrapRequest(request);
License license = new License();
license.setEmail("airsonic@github.com");
license.setValid(true);
Date neverExpireDate = new Date(Long.MAX_VALUE);
license.setLicenseExpires(jaxbWriter.convertDate(neverExpireDate));
license.setTrialExpires(jaxbWriter.convertDate(neverExpireDate));
Response res = createResponse();
res.setLicense(license);
jaxbWriter.writeResponse(request, response, res);
}
The issue is that something changed between Java8 and Java11 when it comes to
new Date(Long.MAX_VALUE)
, resulting in a 08-26 09:50:01.763 14652 14652 W
BackgroundTask: Got exception:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize
value of type
java.util.Calendarfrom String "292278994-08-17T07:12:55.807Z":
not a valid representation (error: Failed to parse Date value
'292278994-08-17T07:12:55.807Z': Cannot parse date
"292278994-08-17T07:12:55.807Z": not compatible with any of standard forms
("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy
HH:mm:ss zzz", "yyyy-MM-dd"))
exception on the application's side.
While the issue is being worked on
upstream, if you're too lazy
to recompile the -git
version, a simple
workaround is to add the following to your nginx configuration:
location /rest/getLicense.view {
alias /var/airsonic/license.json;
}
with /var/airsonic/license.json
containing something like this:
{
"subsonic-response" : {
"status" : "ok",
"version" : "1.15.0",
"license" : {
"valid" : true,
"email" : "airsonic@github.com",
"licenseExpires" : "4096-01-01T07:12:55.807Z",
"trialExpires" : "4096-01-01T07:12:55.807Z"
}
}
And voilà, Ultrasonic is working again.