You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opennlp.apache.org by ma...@apache.org on 2026/03/14 20:50:29 UTC
(opennlp) branch OPENNLP-1735-Upgrade-Java-to-21 created (now 6176e8f3)
This is an automated email from the ASF dual-hosted git repository.
mawiesne pushed a change to branch OPENNLP-1735-Upgrade-Java-to-21
in repository https://gitbox.apache.org/repos/asf/opennlp.git
at 6176e8f3 OPENNLP-1735: Upgrade minimum JDK level to 21 LTS - adjusts pom.xml - adjusts GH actions - replace new Locale(..) with Locale.of(..) - replaces new URL(..) with new URI(..).toURL()
This branch includes the following new commits:
new 6176e8f3 OPENNLP-1735: Upgrade minimum JDK level to 21 LTS - adjusts pom.xml - adjusts GH actions - replace new Locale(..) with Locale.of(..) - replaces new URL(..) with new URI(..).toURL()
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(opennlp) 01/01: OPENNLP-1735: Upgrade minimum JDK level to 21 LTS - adjusts pom.xml - adjusts GH actions - replace new Locale(..) with Locale.of(..) - replaces new URL(..) with new URI(..).toURL()
Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
mawiesne pushed a commit to branch OPENNLP-1735-Upgrade-Java-to-21
in repository https://gitbox.apache.org/repos/asf/opennlp.git
commit 6176e8f3975342418026a410d25eb98d45c79235
Author: Martin Wiesner <ma...@hs-heilbronn.de>
AuthorDate: Sat Mar 14 21:50:22 2026 +0100
OPENNLP-1735: Upgrade minimum JDK level to 21 LTS
- adjusts pom.xml
- adjusts GH actions
- replace new Locale(..) with Locale.of(..)
- replaces new URL(..) with new URI(..).toURL()
---
.github/workflows/license.yml | 4 +-
.github/workflows/maven.yml | 2 +-
.github/workflows/publish-snapshots.yml | 4 +-
.github/workflows/shell-tests.yml | 18 +++----
README.md | 10 ++--
.../opennlp/tools/AbstractModelLoaderTest.java | 14 ++++-
.../opennlp/tools/EnabledWhenCDNAvailable.java | 7 ++-
.../formats/NameFinderCensus90NameStream.java | 4 +-
.../opennlp/tools/formats/conllu/ConlluStream.java | 2 +-
.../tools/formats/conllu/ConlluStreamTest.java | 6 +--
.../models/simple/SimpleClassPathModelFinder.java | 3 +-
.../main/java/opennlp/tools/util/DownloadUtil.java | 63 +++++++++++++---------
.../opennlp/tools/AbstractModelLoaderTest.java | 14 ++++-
.../opennlp/tools/EnabledWhenCDNAvailable.java | 7 ++-
.../sentdetect/AbstractSentenceDetectorTest.java | 8 +--
.../tools/tokenize/TokenizerFactoryTest.java | 8 +--
.../java/opennlp/uima/normalizer/NumberUtil.java | 4 +-
.../src/test/java/opennlp/uima/AbstractIT.java | 12 ++++-
.../opennlp/tools/EnabledWhenCDNAvailable.java | 7 ++-
.../tools/namefind/AbstractNameFinderTest.java | 12 ++++-
.../opennlp/tools/util/DownloadParserTest.java | 44 +++++++++------
pom.xml | 8 +--
22 files changed, 170 insertions(+), 91 deletions(-)
diff --git a/.github/workflows/license.yml b/.github/workflows/license.yml
index 9ebde146..b3f0c245 100644
--- a/.github/workflows/license.yml
+++ b/.github/workflows/license.yml
@@ -27,10 +27,10 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
- java-version: '17'
+ java-version: '21'
distribution: 'temurin'
- name: Cache Maven packages
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index bf7aa0d4..3f0309b6 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -31,7 +31,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
- java: [ 17, 21, 25 ]
+ java: [ 21, 25 ]
experimental: [false]
# include:
# - java: 25-ea
diff --git a/.github/workflows/publish-snapshots.yml b/.github/workflows/publish-snapshots.yml
index b03082a2..c01b974b 100644
--- a/.github/workflows/publish-snapshots.yml
+++ b/.github/workflows/publish-snapshots.yml
@@ -43,8 +43,8 @@ jobs:
- name: Setup Java
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
- distribution: adopt
- java-version: 17
+ distribution: temurin
+ java-version: 21
- id: extract_version
name: Extract version
shell: bash
diff --git a/.github/workflows/shell-tests.yml b/.github/workflows/shell-tests.yml
index 5cacc0a9..888cc197 100644
--- a/.github/workflows/shell-tests.yml
+++ b/.github/workflows/shell-tests.yml
@@ -36,14 +36,14 @@ jobs:
sudo apt-get update
sudo apt-get install -y bats
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
- java-version: 17
+ java-version: 21
- name: Build with Maven
- run: mvn -V clean install --no-transfer-progress -Pci -DskipTests=true
+ run: mvn -V clean verify --no-transfer-progress -Pci -DskipTests=true
- name: Find and Extract OpenNLP Distribution
run: |
@@ -91,14 +91,14 @@ jobs:
brew update
brew install bats-core
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
- java-version: 17
+ java-version: 21
- name: Build with Maven
- run: mvn -V clean install --no-transfer-progress -Pci -DskipTests=true
+ run: mvn -V clean verify --no-transfer-progress -Pci -DskipTests=true
- name: Find and Extract OpenNLP Distribution
run: |
@@ -138,14 +138,14 @@ jobs:
Import-Module Pester
shell: pwsh
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: temurin
- java-version: 17
+ java-version: 21
- name: Build with Maven
- run: mvn -V clean install --no-transfer-progress -Pci -DskipTests=true
+ run: mvn -V clean verify --no-transfer-progress -Pci -DskipTests=true
- name: Run Pester Tests # (one step to avoid environment issues on Windows)
run: |
diff --git a/README.md b/README.md
index e263f2b6..060792a4 100644
--- a/README.md
+++ b/README.md
@@ -132,7 +132,7 @@ For users of the traditional CLI toolkit, nothing changes with the 3.x release l
The Apache OpenNLP team is planning to change the package namespace from `opennlp` to `org.apache.opennlp` in a future release (potentially 4.x).
This change will be made to align with standard Java package naming conventions and to avoid potential conflicts with other libraries.
-In addition, the Apache OpenNLP team is considering the raise of the minimal Java version to JDK 21+ in a future release (potentially 4.x)
+In addition, the Apache OpenNLP team raised the minimal Java version to JDK 21+ for the 3.0.0 release
to take advantage of the latest language features and improvements.
## Branches and Merging Strategy
@@ -141,8 +141,10 @@ To support ongoing development and stable maintenance of Apache OpenNLP, the pro
### Branch overview
-- **`main`**: Development branch for version **3.0** and beyond. All feature development and 3.x releases occur here.
-- **`opennlp-2.x`**: Maintains the stable **2.x** release line. This branch will receive selective updates and patch releases.
+- **`main`**: Development branch for version **3.0** and beyond.
+ All feature development and 3.x releases occur here. Minimum Java level: 21.
+- **`opennlp-2.x`**: Maintains the stable **2.x** release line.
+ This branch will receive selective updates and patch releases. Minimum Java level: 17.
### Workflow summary
@@ -159,7 +161,7 @@ To support ongoing development and stable maintenance of Apache OpenNLP, the pro
## Building OpenNLP
-At least JDK 17 and Maven 3.3.9 are required to build the library.
+For the main branch, at least JDK 21 and Maven 3.9.x are required to build the library.
After cloning the repository go into the destination directory and run:
diff --git a/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/AbstractModelLoaderTest.java b/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/AbstractModelLoaderTest.java
index 059a07d3..8da15743 100644
--- a/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/AbstractModelLoaderTest.java
+++ b/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/AbstractModelLoaderTest.java
@@ -20,6 +20,8 @@ package opennlp.tools;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -47,11 +49,19 @@ public abstract class AbstractModelLoaderTest {
"sv", "tr", "uk");
protected static void downloadVersion15Model(String modelName) throws IOException {
- downloadModel(new URL(BASE_URL_MODELS_V15 + modelName));
+ downloadModel(toModelURL(BASE_URL_MODELS_V15 + modelName));
}
protected static void downloadVersion183Model(String modelName) throws IOException {
- downloadModel(new URL(BASE_URL_MODELS_V183 + modelName));
+ downloadModel(toModelURL(BASE_URL_MODELS_V183 + modelName));
+ }
+
+ private static URL toModelURL(String location) throws IOException {
+ try {
+ return new URI(location).toURL();
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
}
private static void downloadModel(URL url) throws IOException {
diff --git a/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java b/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
index fccc5526..d15f2707 100644
--- a/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
+++ b/opennlp-core/opennlp-cli/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
@@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
@@ -57,7 +59,7 @@ public @interface EnabledWhenCDNAvailable {
socket.connect(new InetSocketAddress(host, 443), TIMEOUT_MS);
// Then, try to check the HTTP status by making an HTTPS request
- final URL url = new URL("https://" + host);
+ final URL url = new URI("https://" + host).toURL();
final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(TIMEOUT_MS);
connection.setReadTimeout(TIMEOUT_MS);
@@ -72,6 +74,9 @@ public @interface EnabledWhenCDNAvailable {
"Resource (CDN) reachable, but HTTP status code: " + statusCode);
}
+ } catch (URISyntaxException e) {
+ return ConditionEvaluationResult.disabled(
+ "Resource (CDN) identifier has an invalid form.");
} catch (IOException e) {
return ConditionEvaluationResult.disabled(
"Resource (CDN) unreachable.");
diff --git a/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/NameFinderCensus90NameStream.java b/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/NameFinderCensus90NameStream.java
index 43fe6f38..e8acc2c4 100644
--- a/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/NameFinderCensus90NameStream.java
+++ b/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/NameFinderCensus90NameStream.java
@@ -58,7 +58,7 @@ public class NameFinderCensus90NameStream implements ObjectStream<StringList> {
* input file to be attached to this class.
*/
public NameFinderCensus90NameStream(ObjectStream<String> lineStream) {
- this.locale = new Locale("en"); // locale is English
+ this.locale = Locale.of("en"); // locale is English
this.encoding = Charset.defaultCharset();
// todo how do we find the encoding for an already open ObjectStream() ?
this.lineStream = lineStream;
@@ -76,7 +76,7 @@ public class NameFinderCensus90NameStream implements ObjectStream<StringList> {
*/
public NameFinderCensus90NameStream(InputStreamFactory in, Charset encoding)
throws IOException {
- this.locale = new Locale("en"); // locale is English
+ this.locale = Locale.of("en"); // locale is English
this.encoding = encoding;
this.lineStream = new PlainTextByLineStream(in, this.encoding);
}
diff --git a/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/conllu/ConlluStream.java b/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/conllu/ConlluStream.java
index e4a9d8fa..17c991e6 100644
--- a/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/conllu/ConlluStream.java
+++ b/opennlp-core/opennlp-formats/src/main/java/opennlp/tools/formats/conllu/ConlluStream.java
@@ -240,7 +240,7 @@ public class ConlluStream implements ObjectStream<ConlluSentence> {
throw new InvalidFormatException(e);
}
if (!lang.isEmpty()) {
- textLang.put(new Locale(lang), secondPart);
+ textLang.put(Locale.of(lang), secondPart);
}
else {
throw new InvalidFormatException(String.format("Locale language code is invalid: %s", lang));
diff --git a/opennlp-core/opennlp-formats/src/test/java/opennlp/tools/formats/conllu/ConlluStreamTest.java b/opennlp-core/opennlp-formats/src/test/java/opennlp/tools/formats/conllu/ConlluStreamTest.java
index 5545f321..5716a84a 100644
--- a/opennlp-core/opennlp-formats/src/test/java/opennlp/tools/formats/conllu/ConlluStreamTest.java
+++ b/opennlp-core/opennlp-formats/src/test/java/opennlp/tools/formats/conllu/ConlluStreamTest.java
@@ -83,8 +83,8 @@ public class ConlluStreamTest extends AbstractConlluSampleStreamTest<SentenceSam
Assertions.assertEquals(3, sent3.getWordLines().size());
Assertions.assertTrue(sent3.isNewParagraph());
Map<Object, Object> textLang3 = new HashMap<>();
- textLang3.put(new Locale("fr"), "VoilĂ ce qui nous est parvenu par la tradition orale.");
- textLang3.put(new Locale("en"), "This is what is heard.");
+ textLang3.put(Locale.of("fr"), "VoilĂ ce qui nous est parvenu par la tradition orale.");
+ textLang3.put(Locale.of("en"), "This is what is heard.");
Assertions.assertEquals(Optional.of(textLang3)
, sent3.getTextLang());
@@ -99,7 +99,7 @@ public class ConlluStreamTest extends AbstractConlluSampleStreamTest<SentenceSam
Assertions.assertTrue(sent4.isNewParagraph());
Assertions.assertEquals(Optional.of("mf920901-001"), sent4.getDocumentId());
Assertions.assertEquals(Optional.of("mf920901-001-p1"), sent4.getParagraphId());
- Assertions.assertEquals(Optional.of(Collections.singletonMap(new Locale("en"),
+ Assertions.assertEquals(Optional.of(Collections.singletonMap(Locale.of("en"),
"Slovak constitution: pros and cons"))
, sent4.getTextLang());
diff --git a/opennlp-core/opennlp-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java b/opennlp-core/opennlp-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java
index ebc7da9f..f776e3d3 100644
--- a/opennlp-core/opennlp-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java
+++ b/opennlp-core/opennlp-models/src/main/java/opennlp/tools/models/simple/SimpleClassPathModelFinder.java
@@ -159,9 +159,8 @@ public class SimpleClassPathModelFinder extends AbstractClassPathModelFinder imp
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
if (!entry.isDirectory()) {
- final URL entryUrl = new URL(jarUrl + entry.getName());
try {
- uris.add(entryUrl.toURI());
+ uris.add(new URI(jarUrl + entry.getName()));
} catch (URISyntaxException ignored) {
//if we cannot convert to URI here, we ignore that entry.
}
diff --git a/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/DownloadUtil.java b/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/DownloadUtil.java
index 03f6f064..7554c064 100644
--- a/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/DownloadUtil.java
+++ b/opennlp-core/opennlp-runtime/src/main/java/opennlp/tools/util/DownloadUtil.java
@@ -22,6 +22,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -61,7 +63,7 @@ public class DownloadUtil {
System.getProperty("OPENNLP_DOWNLOAD_MODEL_PATH", "models/ud-models-1.3/");
private static final String OPENNLP_DOWNLOAD_HOME = "OPENNLP_DOWNLOAD_HOME";
- private static Map<String, Map<ModelType, String>> availableModels;
+ private static Map<String, Map<ModelType, URL>> availableModels;
/**
* Checks if a model of the specified {@code modelType} has been downloaded already
@@ -71,22 +73,23 @@ public class DownloadUtil {
* @param modelType The {@link ModelType type} of model.
* @return {@code true} if a model exists locally, {@code false} otherwise.
* @throws IOException Thrown if IO errors occurred or the computed hash sum
- * of an associated, local model file was incorrect.
+ * of an associated, local model file was incorrect.
*/
static boolean existsModel(String language, ModelType modelType) throws IOException {
- Map<ModelType, String> modelsByLanguage = getAvailableModels().get(language);
+ Map<ModelType, URL> modelsByLanguage = getAvailableModels().get(language);
if (modelsByLanguage == null) {
return false;
} else {
- final String url = modelsByLanguage.get(modelType);
+ final URL url = modelsByLanguage.get(modelType);
if (url != null) {
final Path homeDirectory = getDownloadHome();
- final String filename = url.substring(url.lastIndexOf("/") + 1);
+ final String extUrl = url.toExternalForm();
+ final String filename = extUrl.substring(extUrl.lastIndexOf("/") + 1);
final Path localFile = homeDirectory.resolve(filename);
boolean exists;
if (Files.exists(localFile)) {
// if this does not throw the requested model is valid!
- validateModel(new URL(url + ".sha512"), localFile);
+ validateModel(url + ".sha512", localFile);
exists = true;
} else {
exists = false;
@@ -112,9 +115,9 @@ public class DownloadUtil {
Class<T> type) throws IOException {
if (getAvailableModels().containsKey(language)) {
- final String url = getAvailableModels().get(language).get(modelType);
+ final URL url = getAvailableModels().get(language).get(modelType);
if (url != null) {
- return downloadModel(new URL(url), type);
+ return downloadModel(url, type);
}
}
@@ -156,7 +159,7 @@ public class DownloadUtil {
try (final InputStream in = url.openStream()) {
Files.copy(in, localFile, StandardCopyOption.REPLACE_EXISTING);
}
- validateModel(new URL(url + ".sha512"), localFile);
+ validateModel(url + ".sha512", localFile);
logger.debug("Download complete.");
} else {
logger.debug("Model file '{}' already exists. Skipping download.", filename);
@@ -169,11 +172,12 @@ public class DownloadUtil {
}
}
- public static Map<String, Map<ModelType, String>> getAvailableModels() {
+ public static Map<String, Map<ModelType, URL>> getAvailableModels() {
if (availableModels == null) {
try {
- availableModels = new DownloadParser(new URL(BASE_URL + MODEL_URI_PATH)).getAvailableModels();
- } catch (MalformedURLException e) {
+ DownloadParser p = new DownloadParser(new URI(BASE_URL + MODEL_URI_PATH).toURL());
+ availableModels = p.getAvailableModels();
+ } catch (MalformedURLException | URISyntaxException e) {
throw new RuntimeException(e);
}
}
@@ -187,15 +191,21 @@ public class DownloadUtil {
* @param downloadedModel the model file to check
* @throws IOException thrown if the checksum could not be computed
*/
- private static void validateModel(URL sha512, Path downloadedModel) throws IOException {
- // Download SHA512 checksum file
+ private static void validateModel(String sha512, Path downloadedModel) throws IOException {
String expectedChecksum;
- try (BufferedReader reader = new BufferedReader(new InputStreamReader(sha512.openStream()))) {
- expectedChecksum = reader.readLine();
+ try {
+ // Download SHA512 checksum file
+ final URL hashSum = new URI(sha512).toURL();
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(hashSum.openStream()))) {
+ expectedChecksum = reader.readLine();
- if (expectedChecksum != null) {
- expectedChecksum = expectedChecksum.split("\\s")[0].trim();
+ if (expectedChecksum != null) {
+ expectedChecksum = expectedChecksum.split("\\s")[0].trim();
+ }
}
+ } catch (URISyntaxException use) {
+ throw new IOException("Expected SHA512 checksum could not be retrieved for " +
+ downloadedModel.getFileName(), use);
}
// Validate SHA512 checksum
@@ -248,7 +258,8 @@ public class DownloadUtil {
this.indexUrl = indexUrl;
}
- Map<String, Map<ModelType, String>> getAvailableModels() {
+ Map<String, Map<ModelType, URL>> getAvailableModels()
+ throws MalformedURLException, URISyntaxException {
final Matcher matcher = LINK_PATTERN.matcher(fetchPageIndex());
final List<String> links = new ArrayList<>();
@@ -259,8 +270,9 @@ public class DownloadUtil {
return toMap(links);
}
- private Map<String, Map<ModelType, String>> toMap(List<String> links) {
- final Map<String, Map<ModelType, String>> result = new HashMap<>();
+ private Map<String, Map<ModelType, URL>> toMap(List<String> links)
+ throws MalformedURLException, URISyntaxException {
+ final Map<String, Map<ModelType, URL>> result = new HashMap<>();
for (String link : links) {
if (link.endsWith(".bin")) {
if (link.contains("de-ud")) { // German
@@ -341,10 +353,11 @@ public class DownloadUtil {
return result;
}
- private void addModel(String locale, String link, Map<String, Map<ModelType, String>> result) {
- final Map<ModelType, String> models = result.getOrDefault(locale, new HashMap<>());
- final String url = (indexUrl.toString().endsWith("/") ? indexUrl : indexUrl + "/") + link;
-
+ private void addModel(String locale, String link, Map<String, Map<ModelType, URL>> result)
+ throws URISyntaxException, MalformedURLException {
+ final Map<ModelType, URL> models = result.getOrDefault(locale, new HashMap<>());
+ final String combined = (indexUrl.toString().endsWith("/") ? indexUrl : indexUrl + "/") + link;
+ final URL url = new URI(combined).toURL();
if (link.contains("sentence")) {
models.put(ModelType.SENTENCE_DETECTOR, url);
} else if (link.contains("tokens")) {
diff --git a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/AbstractModelLoaderTest.java b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/AbstractModelLoaderTest.java
index 059a07d3..8da15743 100644
--- a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/AbstractModelLoaderTest.java
+++ b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/AbstractModelLoaderTest.java
@@ -20,6 +20,8 @@ package opennlp.tools;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -47,11 +49,19 @@ public abstract class AbstractModelLoaderTest {
"sv", "tr", "uk");
protected static void downloadVersion15Model(String modelName) throws IOException {
- downloadModel(new URL(BASE_URL_MODELS_V15 + modelName));
+ downloadModel(toModelURL(BASE_URL_MODELS_V15 + modelName));
}
protected static void downloadVersion183Model(String modelName) throws IOException {
- downloadModel(new URL(BASE_URL_MODELS_V183 + modelName));
+ downloadModel(toModelURL(BASE_URL_MODELS_V183 + modelName));
+ }
+
+ private static URL toModelURL(String location) throws IOException {
+ try {
+ return new URI(location).toURL();
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
}
private static void downloadModel(URL url) throws IOException {
diff --git a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
index fccc5526..d15f2707 100644
--- a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
+++ b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
@@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
@@ -57,7 +59,7 @@ public @interface EnabledWhenCDNAvailable {
socket.connect(new InetSocketAddress(host, 443), TIMEOUT_MS);
// Then, try to check the HTTP status by making an HTTPS request
- final URL url = new URL("https://" + host);
+ final URL url = new URI("https://" + host).toURL();
final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(TIMEOUT_MS);
connection.setReadTimeout(TIMEOUT_MS);
@@ -72,6 +74,9 @@ public @interface EnabledWhenCDNAvailable {
"Resource (CDN) reachable, but HTTP status code: " + statusCode);
}
+ } catch (URISyntaxException e) {
+ return ConditionEvaluationResult.disabled(
+ "Resource (CDN) identifier has an invalid form.");
} catch (IOException e) {
return ConditionEvaluationResult.disabled(
"Resource (CDN) unreachable.");
diff --git a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/sentdetect/AbstractSentenceDetectorTest.java b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/sentdetect/AbstractSentenceDetectorTest.java
index 64f2a000..d258ea4e 100644
--- a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/sentdetect/AbstractSentenceDetectorTest.java
+++ b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/sentdetect/AbstractSentenceDetectorTest.java
@@ -30,10 +30,10 @@ import opennlp.tools.util.TrainingParameters;
public abstract class AbstractSentenceDetectorTest {
- protected static final Locale LOCALE_DUTCH = new Locale("nl");
- protected static final Locale LOCALE_POLISH = new Locale("pl");
- protected static final Locale LOCALE_PORTUGUESE = new Locale("pt");
- protected static final Locale LOCALE_SPANISH = new Locale("es");
+ protected static final Locale LOCALE_DUTCH = Locale.of("nl");
+ protected static final Locale LOCALE_POLISH = Locale.of("pl");
+ protected static final Locale LOCALE_PORTUGUESE = Locale.of("pt");
+ protected static final Locale LOCALE_SPANISH = Locale.of("es");
static ObjectStream<SentenceSample> createSampleStream(Locale loc) throws IOException {
final String trainingResource;
diff --git a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/tokenize/TokenizerFactoryTest.java b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/tokenize/TokenizerFactoryTest.java
index 23d2ba7a..41ff5d44 100644
--- a/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/tokenize/TokenizerFactoryTest.java
+++ b/opennlp-core/opennlp-runtime/src/test/java/opennlp/tools/tokenize/TokenizerFactoryTest.java
@@ -42,10 +42,10 @@ import opennlp.tools.util.TrainingParameters;
*/
public class TokenizerFactoryTest {
- private static final Locale LOCALE_DUTCH = new Locale("nl");
- private static final Locale LOCALE_POLISH = new Locale("pl");
- private static final Locale LOCALE_PORTUGUESE = new Locale("pt");
- private static final Locale LOCALE_SPANISH = new Locale("es");
+ private static final Locale LOCALE_DUTCH = Locale.of("nl");
+ private static final Locale LOCALE_POLISH = Locale.of("pl");
+ private static final Locale LOCALE_PORTUGUESE = Locale.of("pt");
+ private static final Locale LOCALE_SPANISH = Locale.of("es");
private static ObjectStream<TokenSample> createSampleStream() throws IOException {
InputStreamFactory in = new ResourceAsStreamFactory(
diff --git a/opennlp-extensions/opennlp-uima/src/main/java/opennlp/uima/normalizer/NumberUtil.java b/opennlp-extensions/opennlp-uima/src/main/java/opennlp/uima/normalizer/NumberUtil.java
index 6adf9030..f14df8ec 100644
--- a/opennlp-extensions/opennlp-uima/src/main/java/opennlp/uima/normalizer/NumberUtil.java
+++ b/opennlp-extensions/opennlp-uima/src/main/java/opennlp/uima/normalizer/NumberUtil.java
@@ -36,7 +36,7 @@ public final class NumberUtil {
* @return true if the language is supported
*/
public static boolean isLanguageSupported(String languageCode) {
- Locale locale = new Locale(languageCode);
+ Locale locale = Locale.of(languageCode);
Locale[] possibleLocales = NumberFormat.getAvailableLocales();
@@ -70,7 +70,7 @@ public final class NumberUtil {
throw new IllegalArgumentException("Language " + languageCode + " is not supported!");
}
- Locale locale = new Locale(languageCode);
+ Locale locale = Locale.of(languageCode);
NumberFormat numberFormat = NumberFormat.getInstance(locale);
number = WHITESPACE_PATTERN.matcher(number).replaceAll("");
return numberFormat.parse(number);
diff --git a/opennlp-extensions/opennlp-uima/src/test/java/opennlp/uima/AbstractIT.java b/opennlp-extensions/opennlp-uima/src/test/java/opennlp/uima/AbstractIT.java
index 4e0c45ef..9d5633dd 100644
--- a/opennlp-extensions/opennlp-uima/src/test/java/opennlp/uima/AbstractIT.java
+++ b/opennlp-extensions/opennlp-uima/src/test/java/opennlp/uima/AbstractIT.java
@@ -21,6 +21,8 @@ import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -71,7 +73,15 @@ abstract class AbstractIT extends AbstractUimaTest {
}
private static void downloadVersion15Model(String modelName) throws IOException {
- downloadModel(new URL(BASE_URL_MODELS_V15 + modelName));
+ downloadModel(toModelURL(BASE_URL_MODELS_V15 + modelName));
+ }
+
+ private static URL toModelURL(String location) throws IOException {
+ try {
+ return new URI(location).toURL();
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
}
private static void downloadModel(URL url) throws IOException {
diff --git a/opennlp-tools/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java b/opennlp-tools/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
index fccc5526..d15f2707 100644
--- a/opennlp-tools/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
+++ b/opennlp-tools/src/test/java/opennlp/tools/EnabledWhenCDNAvailable.java
@@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.InetSocketAddress;
import java.net.Socket;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
@@ -57,7 +59,7 @@ public @interface EnabledWhenCDNAvailable {
socket.connect(new InetSocketAddress(host, 443), TIMEOUT_MS);
// Then, try to check the HTTP status by making an HTTPS request
- final URL url = new URL("https://" + host);
+ final URL url = new URI("https://" + host).toURL();
final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setConnectTimeout(TIMEOUT_MS);
connection.setReadTimeout(TIMEOUT_MS);
@@ -72,6 +74,9 @@ public @interface EnabledWhenCDNAvailable {
"Resource (CDN) reachable, but HTTP status code: " + statusCode);
}
+ } catch (URISyntaxException e) {
+ return ConditionEvaluationResult.disabled(
+ "Resource (CDN) identifier has an invalid form.");
} catch (IOException e) {
return ConditionEvaluationResult.disabled(
"Resource (CDN) unreachable.");
diff --git a/opennlp-tools/src/test/java/opennlp/tools/namefind/AbstractNameFinderTest.java b/opennlp-tools/src/test/java/opennlp/tools/namefind/AbstractNameFinderTest.java
index 47fa4d72..3a0cca4a 100644
--- a/opennlp-tools/src/test/java/opennlp/tools/namefind/AbstractNameFinderTest.java
+++ b/opennlp-tools/src/test/java/opennlp/tools/namefind/AbstractNameFinderTest.java
@@ -21,6 +21,8 @@ import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -112,7 +114,15 @@ abstract class AbstractNameFinderTest {
}
protected static void downloadVersion15Model(String modelName) throws IOException {
- downloadModel(new URL(BASE_URL_MODELS_V15 + modelName));
+ downloadModel(toModelURL(BASE_URL_MODELS_V15 + modelName));
+ }
+
+ private static URL toModelURL(String location) throws IOException {
+ try {
+ return new URI(location).toURL();
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
}
private static void downloadModel(URL url) throws IOException {
diff --git a/opennlp-tools/src/test/java/opennlp/tools/util/DownloadParserTest.java b/opennlp-tools/src/test/java/opennlp/tools/util/DownloadParserTest.java
index b2d360bd..ac04d7d4 100644
--- a/opennlp-tools/src/test/java/opennlp/tools/util/DownloadParserTest.java
+++ b/opennlp-tools/src/test/java/opennlp/tools/util/DownloadParserTest.java
@@ -18,6 +18,8 @@
package opennlp.tools.util;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;
import java.util.stream.Stream;
@@ -32,6 +34,7 @@ import opennlp.tools.models.ModelType;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
public class DownloadParserTest {
@@ -44,20 +47,23 @@ public class DownloadParserTest {
final DownloadUtil.DownloadParser downloadParser = new DownloadUtil.DownloadParser(baseUrl);
- Map<String, Map<ModelType, String>> result = downloadParser.getAvailableModels();
+ try {
+ Map<String, Map<ModelType, URL>> result = downloadParser.getAvailableModels();
+ assertNotNull(result);
+ assertEquals(36, result.size());
- assertNotNull(result);
- assertEquals(36, result.size());
+ final Map<ModelType, URL> availableModels = result.get(language);
+ assertNotNull(availableModels);
- final Map<ModelType, String> availableModels = result.get(language);
- assertNotNull(availableModels);
+ for (Map.Entry<ModelType, String> e : expectedModels.entrySet()) {
+ final URL url = availableModels.get(e.getKey());
+ final String expectedUrl = baseUrl + "/" + e.getValue();
- for (Map.Entry<ModelType, String> e : expectedModels.entrySet()) {
- final String url = availableModels.get(e.getKey());
- final String expectedUrl = baseUrl + "/" + e.getValue();
-
- assertNotNull(url, "A model for the given model type is expected");
- assertEquals(expectedUrl, url);
+ assertNotNull(url, "A model for the given model type is expected");
+ assertEquals(expectedUrl, url.toExternalForm());
+ }
+ } catch (URISyntaxException | MalformedURLException e) {
+ fail(e);
}
}
@@ -68,12 +74,16 @@ public class DownloadParserTest {
}
@Test
- void testInvalidUrl() throws MalformedURLException {
- final DownloadUtil.DownloadParser downloadParser =
- new DownloadUtil.DownloadParser(new URL("file:/this/does/not/exist"));
- Map<String, Map<ModelType, String>> result = downloadParser.getAvailableModels();
- assertNotNull(result);
- assertEquals(0, result.size());
+ void testInvalidUrl() {
+ try {
+ final DownloadUtil.DownloadParser downloadParser =
+ new DownloadUtil.DownloadParser(new URI("file:/this/does/not/exist").toURL());
+ Map<String, Map<ModelType, URL>> result = downloadParser.getAvailableModels();
+ assertNotNull(result);
+ assertEquals(0, result.size());
+ } catch (URISyntaxException | MalformedURLException e) {
+ fail(e);
+ }
}
private URL fromClasspath(String file) {
diff --git a/pom.xml b/pom.xml
index b85d3a32..98a3df1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -221,8 +221,8 @@
<properties>
<!-- Build properties -->
- <java.version>17</java.version>
- <maven.version>3.3.9</maven.version>
+ <java.version>21</java.version>
+ <maven.version>3.9.0</maven.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
<maven.compiler.target>${java.version}</maven.compiler.target>
@@ -485,11 +485,11 @@
<configuration>
<rules>
<requireJavaVersion>
- <message>Java 17 or higher is required to compile this module</message>
+ <message>Java 21 or higher is required to compile this module</message>
<version>[${java.version},)</version>
</requireJavaVersion>
<requireMavenVersion>
- <message>Maven 3.3.9 or higher is required to compile this module</message>
+ <message>Maven 3.9.0 or higher is required to compile this module</message>
<version>[${maven.version},)</version>
</requireMavenVersion>
</rules>