Title: Making Ultrasonic work with Airsonic on Java 11
Date: 2019-09-01 11:30

If like me you're using [Ultrasonic](https://github.com/ultrasonic/ultrasonic)
to interact with your [airsonic](https://airsonic.github.io/) 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](http://www.subsonic.org/pages/api.jsp) of the later.

Unfortunately, subsonic being a [*freemium*
software](http://www.subsonic.org/pages/premium.jsp), 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](https://github.com/airsonic/airsonic/blob/master/airsonic-main/src/main/java/org/airsonic/player/controller/SubsonicRESTController.java):

```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.Calendar` from 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](https://github.com/airsonic/airsonic/issues/1214), if you're too lazy
to recompile the `-git` version, a simple
workaround is to add the following to your nginx configuration:

```nginx
    location /rest/getLicense.view {
				alias /var/airsonic/license.json;
		}
```

with `/var/airsonic/license.json` containing something like this:


```json
{
	"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.
