diff --git a/lib/datasource/adoptium-java/__fixtures__/page.json b/lib/datasource/adoptium-java/__fixtures__/page.json
new file mode 100644
index 0000000000000000000000000000000000000000..f5537643b3a5e11f37d592c15dd6e92e525e0780
--- /dev/null
+++ b/lib/datasource/adoptium-java/__fixtures__/page.json
@@ -0,0 +1,28 @@
+{
+  "versions": [
+    {
+      "build": 7,
+      "major": 16,
+      "minor": 0,
+      "openjdk_version": "16.0.2+7",
+      "security": 2,
+      "semver": "16.0.2+7"
+    },
+    {
+      "build": 7,
+      "major": 11,
+      "minor": 0,
+      "openjdk_version": "11.0.12+7",
+      "security": 12,
+      "semver": "11.0.12+7"
+    },
+    {
+      "build": 8,
+      "major": 8,
+      "minor": 0,
+      "openjdk_version": "1.8.0_302-b08",
+      "security": 302,
+      "semver": "8.0.302+8"
+    }
+  ]
+}
diff --git a/lib/datasource/adoptium-java/__snapshots__/index.spec.ts.snap b/lib/datasource/adoptium-java/__snapshots__/index.spec.ts.snap
new file mode 100644
index 0000000000000000000000000000000000000000..5b273483414707f2e3e4ace22be39f20945a4974
--- /dev/null
+++ b/lib/datasource/adoptium-java/__snapshots__/index.spec.ts.snap
@@ -0,0 +1,278 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`datasource/adoptium-java/index getReleases pages 1`] = `
+Object {
+  "homepage": "https://adoptium.net",
+  "registryUrl": "https://api.adoptium.net/",
+  "releases": Array [
+    Object {
+      "version": "1.1.0",
+    },
+    Object {
+      "version": "1.2.0",
+    },
+    Object {
+      "version": "1.3.0",
+    },
+    Object {
+      "version": "1.4.0",
+    },
+    Object {
+      "version": "1.5.0",
+    },
+    Object {
+      "version": "1.6.0",
+    },
+    Object {
+      "version": "1.7.0",
+    },
+    Object {
+      "version": "1.8.0",
+    },
+    Object {
+      "version": "1.9.0",
+    },
+    Object {
+      "version": "1.10.0",
+    },
+    Object {
+      "version": "1.11.0",
+    },
+    Object {
+      "version": "1.12.0",
+    },
+    Object {
+      "version": "1.13.0",
+    },
+    Object {
+      "version": "1.14.0",
+    },
+    Object {
+      "version": "1.15.0",
+    },
+    Object {
+      "version": "1.16.0",
+    },
+    Object {
+      "version": "1.17.0",
+    },
+    Object {
+      "version": "1.18.0",
+    },
+    Object {
+      "version": "1.19.0",
+    },
+    Object {
+      "version": "1.20.0",
+    },
+    Object {
+      "version": "1.21.0",
+    },
+    Object {
+      "version": "1.22.0",
+    },
+    Object {
+      "version": "1.23.0",
+    },
+    Object {
+      "version": "1.24.0",
+    },
+    Object {
+      "version": "1.25.0",
+    },
+    Object {
+      "version": "1.26.0",
+    },
+    Object {
+      "version": "1.27.0",
+    },
+    Object {
+      "version": "1.28.0",
+    },
+    Object {
+      "version": "1.29.0",
+    },
+    Object {
+      "version": "1.30.0",
+    },
+    Object {
+      "version": "1.31.0",
+    },
+    Object {
+      "version": "1.32.0",
+    },
+    Object {
+      "version": "1.33.0",
+    },
+    Object {
+      "version": "1.34.0",
+    },
+    Object {
+      "version": "1.35.0",
+    },
+    Object {
+      "version": "1.36.0",
+    },
+    Object {
+      "version": "1.37.0",
+    },
+    Object {
+      "version": "1.38.0",
+    },
+    Object {
+      "version": "1.39.0",
+    },
+    Object {
+      "version": "1.40.0",
+    },
+    Object {
+      "version": "1.41.0",
+    },
+    Object {
+      "version": "1.42.0",
+    },
+    Object {
+      "version": "1.43.0",
+    },
+    Object {
+      "version": "1.44.0",
+    },
+    Object {
+      "version": "1.45.0",
+    },
+    Object {
+      "version": "1.46.0",
+    },
+    Object {
+      "version": "1.47.0",
+    },
+    Object {
+      "version": "1.48.0",
+    },
+    Object {
+      "version": "1.49.0",
+    },
+    Object {
+      "version": "1.50.0",
+    },
+  ],
+}
+`;
+
+exports[`datasource/adoptium-java/index getReleases pages 2`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=0",
+  },
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=1",
+  },
+]
+`;
+
+exports[`datasource/adoptium-java/index getReleases processes real data 1`] = `
+Object {
+  "homepage": "https://adoptium.net",
+  "registryUrl": "https://api.adoptium.net/",
+  "releases": Array [
+    Object {
+      "version": "8.0.302+8",
+    },
+    Object {
+      "version": "11.0.12+7",
+    },
+    Object {
+      "version": "16.0.2+7",
+    },
+  ],
+}
+`;
+
+exports[`datasource/adoptium-java/index getReleases processes real data 2`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=0",
+  },
+]
+`;
+
+exports[`datasource/adoptium-java/index getReleases returns null for 404 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=0",
+  },
+]
+`;
+
+exports[`datasource/adoptium-java/index getReleases returns null for empty 200 OK 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=0",
+  },
+]
+`;
+
+exports[`datasource/adoptium-java/index getReleases throws for 5xx 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=0",
+  },
+]
+`;
+
+exports[`datasource/adoptium-java/index getReleases throws for error 1`] = `
+Array [
+  Object {
+    "headers": Object {
+      "accept": "application/json",
+      "accept-encoding": "gzip, deflate, br",
+      "host": "api.adoptium.net",
+      "user-agent": "RenovateBot/0.0.0-semantic-release (https://github.com/renovatebot/renovate)",
+    },
+    "method": "GET",
+    "url": "https://api.adoptium.net/v3/release_versions?page_size=50&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=0",
+  },
+]
+`;
diff --git a/lib/datasource/adoptium-java/common.ts b/lib/datasource/adoptium-java/common.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eabaeacd871a0c5e82cfdd8c38df191363a7adf3
--- /dev/null
+++ b/lib/datasource/adoptium-java/common.ts
@@ -0,0 +1,6 @@
+// Api page size limit 50
+export const pageSize = 50;
+
+export const defaultRegistryUrl = 'https://api.adoptium.net/';
+
+export const datasource = 'adoptium-java';
diff --git a/lib/datasource/adoptium-java/index.spec.ts b/lib/datasource/adoptium-java/index.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2960089109338d0561ef695c1cdd18365a1779f6
--- /dev/null
+++ b/lib/datasource/adoptium-java/index.spec.ts
@@ -0,0 +1,101 @@
+import { getPkgReleases } from '..';
+import * as httpMock from '../../../test/http-mock';
+import { getName, loadFixture } from '../../../test/util';
+import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages';
+import { datasource, defaultRegistryUrl, pageSize } from './common';
+
+const res1 = loadFixture('page.json');
+
+function getPath(page: number): string {
+  return `/v3/release_versions?page_size=${pageSize}&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium&page=${page}`;
+}
+function* range(start: number, end: number): Generator<number, number, number> {
+  yield start;
+  if (start === end) {
+    return;
+  }
+  yield* range(start + 1, end);
+}
+
+describe(getName(), () => {
+  describe('getReleases', () => {
+    it('throws for error', async () => {
+      httpMock
+        .scope(defaultRegistryUrl)
+        .get(getPath(0))
+        .replyWithError('error');
+      await expect(
+        getPkgReleases({
+          datasource,
+          depName: 'adoptium-java',
+        })
+      ).rejects.toThrow(EXTERNAL_HOST_ERROR);
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+
+    it('returns null for 404', async () => {
+      httpMock.scope(defaultRegistryUrl).get(getPath(0)).reply(404);
+      expect(
+        await getPkgReleases({
+          datasource,
+          depName: 'adoptium-java',
+        })
+      ).toBeNull();
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+
+    it('returns null for empty 200 OK', async () => {
+      httpMock
+        .scope(defaultRegistryUrl)
+        .get(getPath(0))
+        .reply(200, { versions: [] });
+      expect(
+        await getPkgReleases({
+          datasource,
+          depName: 'adoptium-java',
+        })
+      ).toBeNull();
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+
+    it('throws for 5xx', async () => {
+      httpMock.scope(defaultRegistryUrl).get(getPath(0)).reply(502);
+      await expect(
+        getPkgReleases({
+          datasource,
+          depName: 'adoptium-java',
+        })
+      ).rejects.toThrow(EXTERNAL_HOST_ERROR);
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+
+    it('processes real data', async () => {
+      httpMock.scope(defaultRegistryUrl).get(getPath(0)).reply(200, res1);
+      const res = await getPkgReleases({
+        datasource,
+        depName: 'adoptium-java',
+      });
+      expect(res).toMatchSnapshot();
+      expect(res.releases).toHaveLength(3);
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+
+    it('pages', async () => {
+      httpMock
+        .scope(defaultRegistryUrl)
+        .get(getPath(0))
+        .reply(200, {
+          versions: [...range(1, 50)].map((v) => ({ semver: `1.${v}.0` })),
+        })
+        .get(getPath(1))
+        .reply(404);
+      const res = await getPkgReleases({
+        datasource,
+        depName: 'adoptium-java',
+      });
+      expect(res).toMatchSnapshot();
+      expect(res.releases).toHaveLength(50);
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+  });
+});
diff --git a/lib/datasource/adoptium-java/index.ts b/lib/datasource/adoptium-java/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5213b3a218280e79cd175df6e37397a75dabc295
--- /dev/null
+++ b/lib/datasource/adoptium-java/index.ts
@@ -0,0 +1,58 @@
+import { ExternalHostError } from '../../types/errors/external-host-error';
+import { HttpError } from '../../util/http/types';
+import { Datasource } from '../datasource';
+import type { GetReleasesConfig, ReleaseResult } from '../types';
+import { datasource, pageSize } from './common';
+import type { AdoptiumJavaResponse } from './types';
+
+export class AdoptiumJavaDatasource extends Datasource {
+  static readonly id = datasource;
+
+  constructor() {
+    super(datasource);
+  }
+
+  customRegistrySupport = false;
+
+  defaultRegistryUrls = ['https://api.adoptium.net/'];
+
+  caching = true;
+
+  async getReleases({
+    registryUrl,
+  }: GetReleasesConfig): Promise<ReleaseResult | null> {
+    let page = 0;
+    const url = `${registryUrl}v3/release_versions?page_size=${pageSize}&project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium`;
+
+    const result: ReleaseResult = {
+      homepage: 'https://adoptium.net',
+      releases: [],
+    };
+    let resp: AdoptiumJavaResponse;
+    try {
+      do {
+        resp = (
+          await this.http.getJson<AdoptiumJavaResponse>(`${url}&page=${page}`)
+        ).body;
+        result.releases.push(
+          ...resp.versions.map(({ semver }) => ({ version: semver }))
+        );
+        page += 1;
+      } while (page < 50 && resp.versions.length === pageSize);
+    } catch (err) {
+      // istanbul ignore else: not testable with nock
+      if (err instanceof HttpError) {
+        if (err.response?.statusCode === 404 && page > 0) {
+          // no more pages
+          return result;
+        }
+        if (err.response?.statusCode !== 404) {
+          throw new ExternalHostError(err);
+        }
+      }
+      this.handleGenericErrors(err);
+    }
+
+    return result.releases.length ? result : null;
+  }
+}
diff --git a/lib/datasource/adoptium-java/readme.md b/lib/datasource/adoptium-java/readme.md
new file mode 100644
index 0000000000000000000000000000000000000000..841a211f0ccdbd90cebbb9ad28b76dc09daaecc4
--- /dev/null
+++ b/lib/datasource/adoptium-java/readme.md
@@ -0,0 +1,5 @@
+This datasource returns releases from [Adoptium](https://adoptium.net/) API.
+
+It uses `project=jdk&release_type=ga&sort_method=DATE&sort_order=DESC&vendor=adoptium` as filter parameters.
+
+It only uses the first 50 pages with 50 items per page.
diff --git a/lib/datasource/adoptium-java/types.ts b/lib/datasource/adoptium-java/types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..578ef99d93f2a15dd5a43843678bbdfb423740e1
--- /dev/null
+++ b/lib/datasource/adoptium-java/types.ts
@@ -0,0 +1,7 @@
+export interface AdoptiumJavaVersion {
+  semver: string;
+}
+
+export interface AdoptiumJavaResponse {
+  versions?: AdoptiumJavaVersion[];
+}
diff --git a/lib/datasource/api.ts b/lib/datasource/api.ts
index 5dde26a33af18b9ae005b6a57ffceb3396f9fcfd..9ad37f8fa7a5e9898745938bb8cd1f9250dda552 100644
--- a/lib/datasource/api.ts
+++ b/lib/datasource/api.ts
@@ -1,3 +1,4 @@
+import { AdoptiumJavaDatasource } from './adoptium-java';
 import { BitBucketTagsDatasource } from './bitbucket-tags';
 import { CdnJsDatasource } from './cdnjs';
 import { ClojureDatasource } from './clojure';
@@ -35,6 +36,7 @@ import type { DatasourceApi } from './types';
 const api = new Map<string, DatasourceApi>();
 export default api;
 
+api.set(AdoptiumJavaDatasource.id, new AdoptiumJavaDatasource());
 api.set('bitbucket-tags', new BitBucketTagsDatasource());
 api.set('cdnjs', new CdnJsDatasource());
 api.set('clojure', new ClojureDatasource());