Skip to content

Commit 384e973

Browse files
authored
feat(build)!: ship an explicit JPMS module and vendor the country code enum (#474)
1 parent f46781a commit 384e973

48 files changed

Lines changed: 736 additions & 68 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎404.html‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
permalink: /404.html
3+
---
4+
<!doctype html>
5+
<html lang="en">
6+
<head>
7+
<meta charset="utf-8">
8+
<meta name="viewport" content="width=device-width, initial-scale=1">
9+
<title>Page not found</title>
10+
<script>
11+
// Javadoc switched to its modular layout in 10.0.0-RC7, which inserted the module name into the
12+
// path of every class page. Deep links to the old paths are in the wild, in older releases and
13+
// in search results, so translate them here instead of serving a dead end. GitHub Pages has no
14+
// server-side redirects, and this is one file rather than a stub per page.
15+
(function () {
16+
var path = location.pathname;
17+
var moved = path
18+
.replace(/\/apidocs\/se\/michaelthelin\/spotify\//, "/apidocs/se.michaelthelin.spotify/se/michaelthelin/spotify/")
19+
.replace(/\/apidocs\/overview-summary\.html$/, "/apidocs/index.html");
20+
21+
if (moved !== path) {
22+
location.replace(moved + location.search + location.hash);
23+
}
24+
})();
25+
</script>
26+
<style>
27+
body { font-family: system-ui, sans-serif; margin: 4rem auto; max-width: 40rem; padding: 0 1rem; }
28+
</style>
29+
</head>
30+
<body>
31+
<h1>Page not found</h1>
32+
<p>
33+
If you followed a link to the API documentation, it may point at a path used before 10.0.0-RC7.
34+
Try the <a href="/spotify-web-api-java/apidocs/">current documentation</a>.
35+
</p>
36+
</body>
37+
</html>

‎MIGRATION.md‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ spotifyApi.createPlaylist("My playlist").build().execute();
3737
Spotify dropped the `{owner_id}` path segment, so `followPlaylist(String owner_id, String playlist_id, boolean public_)` and `unfollowPlaylist(String owner_id, String playlist_id)` are gone.
3838
The remaining overloads take the playlist ID alone, and they moved from `requests.data.follow.legacy` to `requests.data.users`.
3939

40+
**`CountryCode` now comes from this library.**
41+
The `com.neovisionaries:nv-i18n` dependency is gone, so every `market` and `country` parameter takes the `CountryCode` in `se.michaelthelin.spotify.enums` instead.
42+
The constant names are the same, so this is an import change and nothing else.
43+
44+
```java
45+
// v9
46+
import com.neovisionaries.i18n.CountryCode;
47+
48+
// v10
49+
import se.michaelthelin.spotify.enums.CountryCode;
50+
```
51+
4052
**Playlist item accessors were renamed.**
4153
`Playlist.getTracks()` and `PlaylistSimplified.getTracks()` are now `getItems()`, and `PlaylistTrack.getTrack()` is now `getItem()`.
4254
The return types are unchanged, so these are a straight substitution once you know the new name.
@@ -226,11 +238,23 @@ And `getAvailableMarkets` ⚠️ for `GET /markets`.
226238

227239
Model objects are deserialized reflectively by Gson.
228240
The Jackson annotations every model carried are gone, along with the Jackson dependency itself, because nothing in the library ever constructed an ObjectMapper.
241+
With nv-i18n dropped as well, the library now pulls in only Gson and HttpComponents.
229242

230243
This only affects you if you fed these model classes into your own ObjectMapper.
231244
The `@JsonDeserialize` annotations gave you builder-based deserialization for free, and you now have to configure that yourself.
232245
Nothing changes for code that goes through the library.
233246

247+
### Java modules
248+
249+
The jar is an explicit module named `se.michaelthelin.spotify`, replacing the `Automatic-Module-Name` it carried before.
250+
The name is unchanged, so an existing `requires se.michaelthelin.spotify;` keeps working.
251+
252+
What changes is that the module now declares its dependencies, so a consumer on the module path no longer has to guess.
253+
Gson and both HttpComponents modules are `requires transitive`, because types from all three appear in this library's own public signatures.
254+
That also means a `jlink` image can include the library as a real module rather than folding it into a merged one.
255+
256+
Nothing in this affects code on the classpath.
257+
234258
### Deprecations
235259

236260
49 of the 114 request builders carry `@Deprecated`, up from none in 9.4.0, where the marker only ever sat on individual builder methods.

‎ci/check-docs.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ def current_api():
9393
"""Every name a reader can still write: packages, classes, methods, plus which of them are deprecated."""
9494
packages, classes, members = set(), {}, set()
9595
for source in SOURCES.rglob("*.java"):
96+
if source.name == "module-info.java": # a module declaration, not a package of names
97+
continue
9698
text = source.read_text()
9799
package = re.search(r"^package ([\w.]+);", text, re.M).group(1)
98100
packages.add(package)

‎pom.xml‎

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,6 @@
6767
<artifactId>gson</artifactId>
6868
<version>2.14.0</version>
6969
</dependency>
70-
<dependency>
71-
<groupId>com.neovisionaries</groupId>
72-
<artifactId>nv-i18n</artifactId>
73-
<version>1.29</version>
74-
</dependency>
7570
<dependency>
7671
<groupId>org.apache.httpcomponents.client5</groupId>
7772
<artifactId>httpclient5-cache</artifactId>
@@ -206,8 +201,6 @@
206201
<!-- accessors and builder setters in model_objects carry no prose of their own,
207202
so only broken syntax and dead references should be reported -->
208203
<doclint>all,-missing</doclint>
209-
<!-- the jar carries an Automatic-Module-Name, which is enough for javadoc to switch to the modular layout; the published pages live at package paths, so keep generating them there -->
210-
<legacyMode>true</legacyMode>
211204
</configuration>
212205
</plugin>
213206
</plugins>
@@ -271,8 +264,6 @@
271264
</executions>
272265
<configuration>
273266
<doclint>all,-missing</doclint>
274-
<!-- see the javadoc-check profile: an Automatic-Module-Name alone flips javadoc to the modular layout and would move every published page -->
275-
<legacyMode>true</legacyMode>
276267
<outputDirectory>${project.basedir}/</outputDirectory>
277268
</configuration>
278269
</plugin>

‎src/main/java/module-info.java‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* The Spotify Web API client.
3+
* <p>
4+
* Everything a caller touches is exported. The model packages are additionally opened to Gson, which
5+
* populates their private fields reflectively when a response is deserialized.
6+
*/
7+
module se.michaelthelin.spotify {
8+
// types from these appear in this library's own public signatures, so callers need them too
9+
requires transitive com.google.gson;
10+
requires transitive org.apache.httpcomponents.client5.httpclient5;
11+
requires transitive org.apache.httpcomponents.core5.httpcore5;
12+
13+
requires org.apache.httpcomponents.client5.httpclient5.cache;
14+
requires java.logging;
15+
16+
exports se.michaelthelin.spotify;
17+
exports se.michaelthelin.spotify.enums;
18+
exports se.michaelthelin.spotify.exceptions;
19+
exports se.michaelthelin.spotify.exceptions.detailed;
20+
exports se.michaelthelin.spotify.model_objects;
21+
exports se.michaelthelin.spotify.model_objects.credentials;
22+
exports se.michaelthelin.spotify.model_objects.credentials.error;
23+
exports se.michaelthelin.spotify.model_objects.interfaces;
24+
exports se.michaelthelin.spotify.model_objects.miscellaneous;
25+
exports se.michaelthelin.spotify.model_objects.special;
26+
exports se.michaelthelin.spotify.model_objects.specification;
27+
exports se.michaelthelin.spotify.model_objects.utils;
28+
exports se.michaelthelin.spotify.requests;
29+
exports se.michaelthelin.spotify.requests.authorization;
30+
exports se.michaelthelin.spotify.requests.authorization.authorization_code;
31+
exports se.michaelthelin.spotify.requests.authorization.authorization_code.pkce;
32+
exports se.michaelthelin.spotify.requests.authorization.client_credentials;
33+
exports se.michaelthelin.spotify.requests.data;
34+
exports se.michaelthelin.spotify.requests.data.albums;
35+
exports se.michaelthelin.spotify.requests.data.artists;
36+
exports se.michaelthelin.spotify.requests.data.audiobooks;
37+
exports se.michaelthelin.spotify.requests.data.categories;
38+
exports se.michaelthelin.spotify.requests.data.chapters;
39+
exports se.michaelthelin.spotify.requests.data.episodes;
40+
exports se.michaelthelin.spotify.requests.data.genres;
41+
exports se.michaelthelin.spotify.requests.data.library;
42+
exports se.michaelthelin.spotify.requests.data.markets;
43+
exports se.michaelthelin.spotify.requests.data.player;
44+
exports se.michaelthelin.spotify.requests.data.playlists;
45+
exports se.michaelthelin.spotify.requests.data.search;
46+
exports se.michaelthelin.spotify.requests.data.search.interfaces;
47+
exports se.michaelthelin.spotify.requests.data.search.simplified;
48+
exports se.michaelthelin.spotify.requests.data.search.simplified.special;
49+
exports se.michaelthelin.spotify.requests.data.shows;
50+
exports se.michaelthelin.spotify.requests.data.tracks;
51+
exports se.michaelthelin.spotify.requests.data.users;
52+
exports se.michaelthelin.spotify.requests.data.users.interfaces;
53+
exports se.michaelthelin.spotify.requests.data.users.simplified;
54+
55+
opens se.michaelthelin.spotify.model_objects.credentials to com.google.gson;
56+
opens se.michaelthelin.spotify.model_objects.credentials.error to com.google.gson;
57+
opens se.michaelthelin.spotify.model_objects.miscellaneous to com.google.gson;
58+
opens se.michaelthelin.spotify.model_objects.special to com.google.gson;
59+
opens se.michaelthelin.spotify.model_objects.specification to com.google.gson;
60+
}

0 commit comments

Comments
 (0)